diff --git a/AUTHORS b/AUTHORS
index 9cc81a4..454fdbd 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1427,6 +1427,7 @@
 Zachary Capalbo <zach.geek@gmail.com>
 Zeno Albisser <zeno.albisser@digia.com>
 Zeqin Chen <talonchen@tencent.com>
+Zhanbang He <hezhanbang@gmail.com>
 Zhang Hao <zhanghao.m@bytedance.com>
 Zhang Hao <15686357310a@gmail.com>
 Zhaoming Jiang <zhaoming.jiang@intel.com>
diff --git a/DEPS b/DEPS
index f3a052b..c2086e7 100644
--- a/DEPS
+++ b/DEPS
@@ -300,15 +300,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '593ece8f74c7b9ebadab78baaf7a709eba296ce6',
+  'skia_revision': 'fbba25f66405a036324d1d2a0b0c81db256fd38f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '0c4044b7336787781646e48b2f98f0c7d1b400a5',
+  'v8_revision': '5fe133f1abc5b04c1a30cc17a3899da36b147cd9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '7e2336b1e85ab97012b4f3b8c98ead5a8356ef14',
+  'angle_revision': 'c18972fdef08c8d959584b8f1f089d1426162599',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -316,7 +316,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '28eb03ee8c0582d046ecd012c44ef0121c1b4e72',
+  'pdfium_revision': '88ad8bf36b79ce341898817b44f3620ca188a695',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -371,7 +371,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'b05d23a92828099d59a61e6969b938d8d3fcdc54',
+  'catapult_revision': '2ed88c5bbb2377b0f294b35f49a4f7a10a5ddda1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -387,7 +387,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '4a3abb9f18851d07a4ea7f0ed74aefe8f288de8b',
+  'devtools_frontend_revision': 'a923c0870a632c4396c2fa11be0b4cd8503a7fc6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -427,7 +427,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'f5a62539f4ea16999fbdac588793aa3a47f0d8b0',
+  'dawn_revision': '4b35f52f9b33eb358a01170ad2fd334f2b5b4347',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -777,7 +777,7 @@
   },
 
   'src/chrome/test/data/autofill/captured_sites/artifacts': {
-    'url': Var('chrome_git') + '/chrome/test/captured_sites/autofill.git' + '@' + '47f4547ce696dcafa837541132149341ebba15b9',
+    'url': Var('chrome_git') + '/chrome/test/captured_sites/autofill.git' + '@' + 'bff7987166462e8276297b301222f312241b0b56',
     'condition': 'checkout_chromium_autofill_test_dependencies',
   },
 
@@ -808,7 +808,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    'ec29fe34fb6d05059f25ea5d27451e3788864df2',
+    'da759bdea3376f3c79b4196f82123e4fff17a425',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -837,7 +837,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '4ca20170cd25d0c963cc73ded2e63927defcb2e8',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '8e490b68d2674b5389e2d33091680de4ab4ae51a',
       'condition': 'checkout_ios',
   },
 
@@ -907,7 +907,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': 'DgO5iraLNCzb4PVDYsfAz0VB4EmOfAl5Ktch6jabdisC',
+          'version': 'tXWMTKtqhqICaLq3jy6atPAp_DkSaD-PWYP8po_BRb4C',
         },
       ],
       'dep_type': 'cipd',
@@ -918,7 +918,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'D9HGEkmYRI7dvDO31rgru_CPZ-5YItG_QFlIMsDKr1oC',
+          'version': 'VC28gwk12n0qJ3MbmP3wjtfzuA9s5wLYXXoUwB5RRz8C',
         },
       ],
       'dep_type': 'cipd',
@@ -929,7 +929,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': 'N3tEBmfSDhrfbY5LHR4_q30LQHWNzClkcL2FUJXfGW8C',
+          'version': '6C9S-weeku25MBieyRTu6rX8bWCJDa5c_2ySqHQLCi0C',
         },
       ],
       'dep_type': 'cipd',
@@ -997,7 +997,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'Q3AZB5fRWzo_uiJt47UQ11_LRBtSFcurOt1Aofa9Wy4C',
+          'version': 'Ll2UQauMCmQu65qrrb_Z3qzG-sZhesVx9RnsetEDXPUC',
       },
     ],
     'condition': 'checkout_android',
@@ -1200,7 +1200,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c4f366a31e8b496d783ee6906ac3533738bb099c',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'e4ef5001f25e46d7f29bcc5d55cdad58818b1dac',
       'condition': 'checkout_chromeos',
   },
 
@@ -1232,13 +1232,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '85c13de0becd351c4ad2faeff8bbf88fdc74d038',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '456d085e75803f045be4583d0af25f01bffea62f',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'b91c273b1f05dc40507efa2aaf39d213ec98cce5',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '60bf9a3ec30692895216e0662c64c6fc33464e57',
     'condition': 'checkout_src_internal',
   },
 
@@ -1694,7 +1694,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '09a4f3ec842a8932341b195c5b01e141c8a16eb7',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + 'bb3844ee29d0c91a45124cf9787b64590cf88fd6',
+    Var('chromium_git') + '/openscreen' + '@' + '1bbcb5cb1251e0ac6084b09cbe43a57ec04849e0',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '58a00cf85c39ad5ec4dc43a769624e420c06179a',
@@ -1705,7 +1705,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '603af5820895ff5b344fd8b2b7e90a5336f2de30',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'face7c192d81d632120a587dd45884fe89158203',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1745,7 +1745,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/r8',
-              'version': 'h3mD8cigmlOPxMqeMRW8Z2Wb364bRLWUMdjhwWy_UPsC',
+              'version': 'dJL8gwEiDUoK5pirX6la4l7ofdBufwcc1HUaCv4CZ8cC',
           },
       ],
       'condition': 'checkout_android',
@@ -1850,7 +1850,7 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@25c584aa4cec2d79706854dafbd52392389d8004',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@354eac3ca8c83244089f93f99294dd0dfc265459',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907',
@@ -1887,10 +1887,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd1b65aa5a88f6efd900604dfcda840154e9f16e2',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '9a4977319ea9ca1639ca9d09238247d60c712358',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0be3bde33c5abf01aef574403c888b8ec372453d',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '4e231eedbd5a1b7e50a9e6fc86157d82cb9b4876',
+    Var('webrtc_git') + '/src.git' + '@' + '621cb2943df6e99206563de4469161aa0b59e676',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -1937,7 +1937,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/linux-amd64',
-          'version': 'Axj26GvFKuSjh3j36_dDWFE_8GPzCBI8xMHB55-9KkwC',
+          'version': 'UMqOqE8nlXwo9xj56g4W9ySvvqo2Tsw3B6tWZLo19L8C',
         },
       ],
       'dep_type': 'cipd',
@@ -1947,7 +1947,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/windows-amd64',
-          'version': 'RrfT7u4je5UzYBYkRTDnhzRj0rYXgnyrmtB7YrD5I2oC',
+          'version': 'wveYksSfL51dPfdRZ5474IFmCMkL8gg6ygZxxPdBezAC',
         },
       ],
       'dep_type': 'cipd',
@@ -1958,7 +1958,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/mac-amd64',
-          'version': 'hPekni-3ILDb_vKt8AQPlSQuAt0AP4oGRbEK5ZKGTZ0C',
+          'version': 'vjY1ew6KN-bIFZEk7IbwPCAb6xZxib9uqLXMwbi8JLQC',
         },
       ],
       'dep_type': 'cipd',
@@ -1969,7 +1969,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/mac-arm64',
-          'version': 'Uj9i2aXWBfK915rIKB9UfFkjeqqE8FP9jdTvXxamubUC',
+          'version': 'twOZsJTmRSqlOwstPpWMhT_fXhiOaijMu24-UJLGK20C',
         },
       ],
       'dep_type': 'cipd',
@@ -1980,7 +1980,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': Var('chrome_git') + '/chrome/src-internal.git@26b4899e30ef57c32a4c708e252a4ed038aff8e9',
+    'url': Var('chrome_git') + '/chrome/src-internal.git@f735077d6d5b15041b1b52ecdd8ddc4c71f9b7ba',
     'condition': 'checkout_src_internal',
   },
 
@@ -2010,7 +2010,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': '3rrVAFgdA4taMSvM2Jcn3k9nZEbxTs5t-Iesu46PBHsC',
+        'version': 'wbKoB4M1y2AARLe8VCszM7k882LhuvxBMDh3sLGUSDoC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2021,7 +2021,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'mNd-TXITVIMNgGUojaN0yxKq8YkyCG6ftMV1IzKJcjoC',
+        'version': 'VRYJrAJ9fzb-6ABkUSwxlqF0yiuM_-UWl858Srcx8DoC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4179,7 +4179,7 @@
 
   'src/ios_internal':  {
       'url': '{chrome_git}/chrome/ios_internal.git' + '@' +
-        '11374517c66b33d85bc08c69a3511ad115f8d6d5',
+        'ffcb0936673603987c5dabba5a672bc5a5c934a0',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index f445847..f600eed2 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1504,6 +1504,7 @@
       True,
       (
           r'^base/win/scoped_winrt_initializer\.cc$',
+          r'^third_party/abseil-cpp/absl/.*',
       ),
     ),
     BanRule(
diff --git a/WATCHLISTS b/WATCHLISTS
index 04de445..1907bf7 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -2395,7 +2395,7 @@
     'blink_animation': ['alexis.menard@intel.com',
                         'gerchiko@microsoft.com',
                         'blink-reviews-animation@chromium.org'],
-    'blink_audio': ['hongchan@chromium.org', 'mjwilson@chromium.org', 'alvinji@chromium.org'],
+    'blink_audio': ['hongchan@chromium.org', 'mjwilson@chromium.org', 'alvinji@chromium.org', 'sinafirooz@chromium.org'],
     'blink_battery_status': ['raphael.kubo.da.costa@intel.com'],
     'blink_bindings': ['blink-reviews-bindings@chromium.org', 'haraken@chromium.org'],
     'blink_bindings_serialization': ['jbroman+watch@chromium.org'],
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index 1270d83..ad1d144 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -104,6 +104,7 @@
 
   "+third_party/blink/public/common/client_hints/enabled_client_hints.h",
   "+third_party/blink/public/common/features.h",
+  "+third_party/blink/public/common/origin_trials/origin_trial_feature.h",
   "+third_party/blink/public/common/origin_trials/origin_trials_settings_provider.h",
   "+third_party/blink/public/common/origin_trials/trial_token_validator.h",
   "+third_party/blink/public/common/page_state/page_state.h",
diff --git a/android_webview/browser/aw_client_hints_controller_delegate.cc b/android_webview/browser/aw_client_hints_controller_delegate.cc
index c9d5684e..d3d1847 100644
--- a/android_webview/browser/aw_client_hints_controller_delegate.cc
+++ b/android_webview/browser/aw_client_hints_controller_delegate.cc
@@ -4,6 +4,7 @@
 
 #include "android_webview/browser/aw_client_hints_controller_delegate.h"
 
+#include "android_webview/browser/aw_browser_process.h"
 #include "android_webview/browser/aw_contents.h"
 #include "android_webview/browser/aw_cookie_access_policy.h"
 #include "base/notreached.h"
@@ -32,15 +33,17 @@
 }  // namespace prefs
 
 AwClientHintsControllerDelegate::AwClientHintsControllerDelegate(
-    PrefService* pref_service)
-    : pref_service_(pref_service) {}
+    PrefService* context_pref_service)
+    : context_pref_service_(context_pref_service) {}
 
 AwClientHintsControllerDelegate::~AwClientHintsControllerDelegate() = default;
 
 blink::UserAgentMetadata
-AwClientHintsControllerDelegate::GetUserAgentMetadataOverrideBrand(
-    const PrefService* pref_service) {
-  auto metadata = embedder_support::GetUserAgentMetadata(pref_service);
+AwClientHintsControllerDelegate::GetUserAgentMetadataOverrideBrand() {
+  // embedder_support::GetUserAgentMetadata() can accept a browser local_state
+  // PrefService argument, but doesn't need one. Either way, it shouldn't be the
+  // context_pref_service_ that this class holds.
+  auto metadata = embedder_support::GetUserAgentMetadata();
   std::string major_version = version_info::GetMajorVersionNumber();
 
   // Use the major version number as a greasing seed
@@ -79,9 +82,10 @@
   }
 
   // Add stored hints to the enabled list.
-  if (pref_service_->HasPrefPath(prefs::kClientHintsCachedPerOriginMap)) {
+  if (context_pref_service_->HasPrefPath(
+          prefs::kClientHintsCachedPerOriginMap)) {
     auto* const client_hints_list =
-        pref_service_->GetDict(prefs::kClientHintsCachedPerOriginMap)
+        context_pref_service_->GetDict(prefs::kClientHintsCachedPerOriginMap)
             .FindList(origin.Serialize());
     if (client_hints_list) {
       for (const auto& client_hint : *client_hints_list) {
@@ -134,7 +138,7 @@
 
 blink::UserAgentMetadata
 AwClientHintsControllerDelegate::GetUserAgentMetadata() {
-  return GetUserAgentMetadataOverrideBrand(pref_service_);
+  return GetUserAgentMetadataOverrideBrand();
 }
 
 void AwClientHintsControllerDelegate::PersistClientHints(
@@ -164,13 +168,15 @@
     client_hints_list.Append(static_cast<int>(entry));
   }
   base::Value::Dict ch_per_origin;
-  if (pref_service_->HasPrefPath(prefs::kClientHintsCachedPerOriginMap)) {
+  if (context_pref_service_->HasPrefPath(
+          prefs::kClientHintsCachedPerOriginMap)) {
     ch_per_origin =
-        pref_service_->GetDict(prefs::kClientHintsCachedPerOriginMap).Clone();
+        context_pref_service_->GetDict(prefs::kClientHintsCachedPerOriginMap)
+            .Clone();
   }
   ch_per_origin.Set(primary_origin.Serialize(), std::move(client_hints_list));
-  pref_service_->SetDict(prefs::kClientHintsCachedPerOriginMap,
-                         std::move(ch_per_origin));
+  context_pref_service_->SetDict(prefs::kClientHintsCachedPerOriginMap,
+                                 std::move(ch_per_origin));
   network::LogClientHintsPersistenceMetrics(persistence_started,
                                             client_hints.size());
 }
diff --git a/android_webview/browser/aw_client_hints_controller_delegate.h b/android_webview/browser/aw_client_hints_controller_delegate.h
index 415c4238b..03bf75d8 100644
--- a/android_webview/browser/aw_client_hints_controller_delegate.h
+++ b/android_webview/browser/aw_client_hints_controller_delegate.h
@@ -40,13 +40,17 @@
 class AwClientHintsControllerDelegate
     : public content::ClientHintsControllerDelegate {
  public:
-  explicit AwClientHintsControllerDelegate(PrefService* pref_service);
+  // The supplied PrefService should be the PrefService tied to the
+  // AwBrowserContext (profile), not the browser-wide local_state. Note that
+  // this is not comparible to the PrefService used by
+  // client_hints::ClientHints::ClientHints() - these PrefServices are used for
+  // different purposes.
+  explicit AwClientHintsControllerDelegate(PrefService* context_pref_service);
   ~AwClientHintsControllerDelegate() override;
 
   // Add an unique brand to the brand list to allow users distinguish Android
   // and Android WebView using user-agent client hints.
-  static blink::UserAgentMetadata GetUserAgentMetadataOverrideBrand(
-      const PrefService* pref_service);
+  static blink::UserAgentMetadata GetUserAgentMetadataOverrideBrand();
 
   network::NetworkQualityTracker* GetNetworkQualityTracker() override;
 
@@ -79,7 +83,7 @@
 
  private:
   std::vector<network::mojom::WebClientHintsType> additional_hints_;
-  raw_ptr<PrefService> pref_service_;
+  raw_ptr<PrefService> context_pref_service_;
   gfx::Size viewport_size_;
 };
 
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 716c12b2..717b1eb 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -11,6 +11,7 @@
 
 #include "android_webview/browser/aw_browser_context.h"
 #include "android_webview/browser/aw_browser_main_parts.h"
+#include "android_webview/browser/aw_browser_process.h"
 #include "android_webview/browser/aw_client_hints_controller_delegate.h"
 #include "android_webview/browser/aw_contents.h"
 #include "android_webview/browser/aw_contents_client_bridge.h"
@@ -1028,8 +1029,7 @@
 }
 
 blink::UserAgentMetadata AwContentBrowserClient::GetUserAgentMetadata() {
-  return AwClientHintsControllerDelegate::GetUserAgentMetadataOverrideBrand(
-      browser_context_->GetPrefService());
+  return AwClientHintsControllerDelegate::GetUserAgentMetadataOverrideBrand();
 }
 
 content::ContentBrowserClient::WideColorGamutHeuristic
diff --git a/android_webview/browser/aw_settings.cc b/android_webview/browser/aw_settings.cc
index 2a5c039..013b34dd 100644
--- a/android_webview/browser/aw_settings.cc
+++ b/android_webview/browser/aw_settings.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/browser/aw_browser_process.h"
 #include "android_webview/browser/aw_client_hints_controller_delegate.h"
 #include "android_webview/browser/aw_content_browser_client.h"
 #include "android_webview/browser/aw_contents.h"
@@ -223,8 +224,7 @@
         !ua_string_override.empty() &&
         ua_string_override.find(ua_default) != std::string::npos) {
       override_ua_with_metadata.ua_metadata_override =
-          AwClientHintsControllerDelegate::GetUserAgentMetadataOverrideBrand(
-              AwBrowserContext::GetDefault()->GetPrefService());
+          AwClientHintsControllerDelegate::GetUserAgentMetadataOverrideBrand();
     }
 
     // Set overridden user-agent and default client hints metadata if applied.
diff --git a/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc b/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
index a83a49e..58ae9fdf 100644
--- a/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
+++ b/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
@@ -47,6 +47,7 @@
 #include "services/network/public/mojom/early_hints.mojom.h"
 #include "services/network/public/mojom/fetch_api.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
 #include "url/gurl.h"
 #include "url/origin.h"
@@ -352,9 +353,10 @@
     }
   }
 
-  result_args->xrw_origin_trial_enabled = delegate->IsTrialPersistedForOrigin(
+  result_args->xrw_origin_trial_enabled = delegate->IsFeaturePersistedForOrigin(
       url::Origin::Create(request_url), partition_origin,
-      "WebViewXRequestedWithDeprecation", base::Time::Now());
+      blink::OriginTrialFeature::kWebViewXRequestedWithDeprecation,
+      base::Time::Now());
   base::UmaHistogramBoolean(
       "Android.WebView.RequestedWithHeader.OriginTrialEnabled",
       result_args->xrw_origin_trial_enabled);
diff --git a/ash/accelerators/accelerator_commands.cc b/ash/accelerators/accelerator_commands.cc
index 409375a..48715d9 100644
--- a/ash/accelerators/accelerator_commands.cc
+++ b/ash/accelerators/accelerator_commands.cc
@@ -586,6 +586,10 @@
   return GetPaletteTray()->ShouldShowPalette();
 }
 
+bool CanStopScreenRecording() {
+  return CaptureModeController::Get()->is_recording_in_progress();
+}
+
 bool CanSwapPrimaryDisplay() {
   return display::Screen::GetScreen()->GetNumDisplays() > 1;
 }
@@ -1141,6 +1145,12 @@
   NewWindowDelegate::GetInstance()->ShowTaskManager();
 }
 
+void StopScreenRecording() {
+  CaptureModeController* controller = CaptureModeController::Get();
+  CHECK(controller->is_recording_in_progress());
+  controller->EndVideoRecording(EndRecordingReason::kKeyboardShortcut);
+}
+
 void Suspend() {
   chromeos::PowerManagerClient::Get()->RequestSuspend();
 }
diff --git a/ash/accelerators/accelerator_commands.h b/ash/accelerators/accelerator_commands.h
index 3aaf884a..519fdc8 100644
--- a/ash/accelerators/accelerator_commands.h
+++ b/ash/accelerators/accelerator_commands.h
@@ -85,6 +85,8 @@
 
 ASH_EXPORT bool CanShowStylusTools();
 
+ASH_EXPORT bool CanStopScreenRecording();
+
 ASH_EXPORT bool CanSwapPrimaryDisplay();
 
 ASH_EXPORT bool CanToggleCalendar();
@@ -284,6 +286,9 @@
 // Brings up task manager.
 ASH_EXPORT void ShowTaskManager();
 
+// Stops the capture mode recording.
+ASH_EXPORT void StopScreenRecording();
+
 // Puts device in sleep mode(suspend).
 ASH_EXPORT void Suspend();
 
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc
index 54a7636..06525cdd 100644
--- a/ash/accelerators/accelerator_controller_impl.cc
+++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -736,6 +736,8 @@
       return accelerators::CanShowStylusTools();
     case AcceleratorAction::kStartAssistant:
       return true;
+    case AcceleratorAction::kStopScreenRecording:
+      return accelerators::CanStopScreenRecording();
     case AcceleratorAction::kSwapPrimaryDisplay:
       return accelerators::CanSwapPrimaryDisplay();
     case AcceleratorAction::kSwitchIme:
@@ -1255,6 +1257,9 @@
       base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
       accelerators::ShiftPrimaryDisplay();
       break;
+    case AcceleratorAction::kStopScreenRecording:
+      accelerators::StopScreenRecording();
+      break;
     case AcceleratorAction::kSwitchIme:
       HandleSwitchIme(accelerator);
       break;
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc
index b8fde615..ae4803a 100644
--- a/ash/accessibility/accessibility_controller_impl.cc
+++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -130,7 +130,8 @@
      &kSystemMenuAccessibilityChromevoxIcon},
     {FeatureType::kSelectToSpeak, prefs::kAccessibilitySelectToSpeakEnabled,
      &kSystemMenuAccessibilitySelectToSpeakIcon},
-    {FeatureType::kStickyKeys, prefs::kAccessibilityStickyKeysEnabled, nullptr},
+    {FeatureType::kStickyKeys, prefs::kAccessibilityStickyKeysEnabled, nullptr,
+     /*conflicting_feature=*/FeatureType::kSpokenFeedback},
     {FeatureType::kSwitchAccess, prefs::kAccessibilitySwitchAccessEnabled,
      &kSwitchAccessIcon},
     {FeatureType::kVirtualKeyboard, prefs::kAccessibilityVirtualKeyboardEnabled,
@@ -827,6 +828,26 @@
   conflicting_feature_ = feature;
 }
 
+void AccessibilityControllerImpl::Feature::ObserveConflictingFeature() {
+  std::string conflicting_pref_name = "";
+  switch (conflicting_feature_) {
+    case A11yFeatureType::kSpokenFeedback:
+      conflicting_pref_name = prefs::kAccessibilitySpokenFeedbackEnabled;
+      break;
+    default:
+      // No other features are used as conflicting features at the moment,
+      // but this could be populated if needed in the future.
+      NOTREACHED() << "No pref name for conflicting feature "
+                   << static_cast<int>(conflicting_feature_);
+  }
+  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
+  pref_change_registrar_->Init(owner_->active_user_prefs_);
+  pref_change_registrar_->Add(
+      conflicting_pref_name,
+      base::BindRepeating(&AccessibilityControllerImpl::Feature::UpdateFromPref,
+                          base::Unretained(this)));
+}
+
 AccessibilityControllerImpl::FeatureWithDialog::FeatureWithDialog(
     FeatureType type,
     const std::string& pref_name,
@@ -924,6 +945,11 @@
           feature_data.type, feature_data.pref, feature_data.icon, it->second,
           this);
     }
+    if (feature_data.conflicting_feature !=
+        FeatureType::kNoConflictingFeature) {
+      features_[feature_index]->SetConflictingFeature(
+          feature_data.conflicting_feature);
+    }
   }
 }
 
@@ -1911,6 +1937,9 @@
         base::BindRepeating(
             &AccessibilityControllerImpl::Feature::UpdateFromPref,
             base::Unretained(feature.get())));
+    if (feature->conflicting_feature() != FeatureType::kNoConflictingFeature) {
+      feature->ObserveConflictingFeature();
+    }
     feature->UpdateFromPref();
   }
 
diff --git a/ash/accessibility/accessibility_controller_impl.h b/ash/accessibility/accessibility_controller_impl.h
index 26a63d16..e1bf3ca 100644
--- a/ash/accessibility/accessibility_controller_impl.h
+++ b/ash/accessibility/accessibility_controller_impl.h
@@ -113,9 +113,13 @@
     bool IsEnterpriseIconVisible() const;
     const std::string& pref_name() const { return pref_name_; }
     const gfx::VectorIcon& icon() const;
+    A11yFeatureType conflicting_feature() const { return conflicting_feature_; }
 
     void UpdateFromPref();
     void SetConflictingFeature(A11yFeatureType feature);
+    // Start observing changes to the conflicting feature's pref, in order to
+    // update own enabled state.
+    void ObserveConflictingFeature();
 
    protected:
     const A11yFeatureType type_;
@@ -123,6 +127,9 @@
     // feature is enabled, we cannot enable current feature.
     A11yFeatureType conflicting_feature_ =
         A11yFeatureType::kNoConflictingFeature;
+    // Used to watch for changes in conflicting feature to ensure this updates
+    // enabled state appropriately.
+    std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
     bool enabled_ = false;
     const std::string pref_name_;
     raw_ptr<const gfx::VectorIcon, ExperimentalAsh> icon_;
diff --git a/ash/accessibility/accessibility_controller_unittest.cc b/ash/accessibility/accessibility_controller_unittest.cc
index 4240116..8e77027 100644
--- a/ash/accessibility/accessibility_controller_unittest.cc
+++ b/ash/accessibility/accessibility_controller_unittest.cc
@@ -1025,6 +1025,45 @@
   controller->RemoveObserver(&observer);
 }
 
+TEST_F(AccessibilityControllerTest, FeaturesConflictingWithChromeVox) {
+  AccessibilityControllerImpl* controller =
+      Shell::Get()->accessibility_controller();
+  EXPECT_FALSE(controller->spoken_feedback().enabled());
+  EXPECT_FALSE(controller->sticky_keys().enabled());
+  EXPECT_FALSE(controller->focus_highlight().enabled());
+  EXPECT_TRUE(controller->IsSpokenFeedbackSettingVisibleInTray());
+  EXPECT_TRUE(controller->IsFocusHighlightSettingVisibleInTray());
+  EXPECT_TRUE(controller->IsStickyKeysSettingVisibleInTray());
+
+  controller->sticky_keys().SetEnabled(true);
+  controller->focus_highlight().SetEnabled(true);
+  EXPECT_FALSE(controller->spoken_feedback().enabled());
+  EXPECT_TRUE(controller->sticky_keys().enabled());
+  EXPECT_TRUE(controller->focus_highlight().enabled());
+  EXPECT_TRUE(controller->IsSpokenFeedbackSettingVisibleInTray());
+  EXPECT_TRUE(controller->IsFocusHighlightSettingVisibleInTray());
+  EXPECT_TRUE(controller->IsStickyKeysSettingVisibleInTray());
+
+  // Turning on Spoken Feedback will make sticky keys, focus highlight
+  // act disabled and disappear from the tray.
+  controller->spoken_feedback().SetEnabled(true);
+  EXPECT_TRUE(controller->spoken_feedback().enabled());
+  EXPECT_FALSE(controller->sticky_keys().enabled());
+  EXPECT_FALSE(controller->focus_highlight().enabled());
+  EXPECT_TRUE(controller->IsSpokenFeedbackSettingVisibleInTray());
+  EXPECT_FALSE(controller->IsFocusHighlightSettingVisibleInTray());
+  EXPECT_FALSE(controller->IsStickyKeysSettingVisibleInTray());
+
+  // Disabling ChromeVox will reset to previous state.
+  controller->spoken_feedback().SetEnabled(false);
+  EXPECT_FALSE(controller->spoken_feedback().enabled());
+  EXPECT_TRUE(controller->sticky_keys().enabled());
+  EXPECT_TRUE(controller->focus_highlight().enabled());
+  EXPECT_TRUE(controller->IsSpokenFeedbackSettingVisibleInTray());
+  EXPECT_TRUE(controller->IsFocusHighlightSettingVisibleInTray());
+  EXPECT_TRUE(controller->IsStickyKeysSettingVisibleInTray());
+}
+
 TEST_F(AccessibilityControllerTest, SetStickyKeysEnabled) {
   AccessibilityControllerImpl* controller =
       Shell::Get()->accessibility_controller();
diff --git a/ash/ambient/metrics/ambient_metrics.cc b/ash/ambient/metrics/ambient_metrics.cc
index 0b246432..ea78179 100644
--- a/ash/ambient/metrics/ambient_metrics.cc
+++ b/ash/ambient/metrics/ambient_metrics.cc
@@ -5,6 +5,7 @@
 #include "ash/ambient/metrics/ambient_metrics.h"
 
 #include <string>
+#include <utility>
 
 #include "ash/ambient/ambient_ui_settings.h"
 #include "ash/public/cpp/ambient/ambient_ui_model.h"
@@ -12,6 +13,7 @@
 #include "ash/public/cpp/ash_web_view.h"
 #include "base/check.h"
 #include "base/containers/contains.h"
+#include "base/functional/bind.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
@@ -22,6 +24,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "net/base/url_util.h"
+#include "services/data_decoder/public/cpp/data_decoder.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
@@ -41,7 +44,12 @@
 constexpr int kAmbientModeElapsedTimeHistogramBuckets = 144;
 
 // Fields of the JSON dictionary that the ambient video HTML sends to C++ to
-// communicate playback metrics. They reflect the VideoPlaybackQuality JS API:
+// communicate playback metrics.
+//
+// Whether or not playback started successfully.
+constexpr base::StringPiece kVideoFieldPlaybackStarted = "playback_started";
+//
+// These reflect the VideoPlaybackQuality JS API:
 // https://developer.mozilla.org/en-US/docs/Web/API/VideoPlaybackQuality
 //
 // Total number of video frames dropped since playback started.
@@ -75,6 +83,121 @@
       /*buckets=*/kAmbientModeElapsedTimeHistogramBuckets);
 }
 
+// After the JSON in the URL fragment has been decoded in `result`:
+void OnAmbientVideoPlaybackMetricsParsed(
+    base::OnceCallback<void(base::Value::Dict)> completion_cb,
+    data_decoder::DataDecoder::ValueOrError result) {
+  CHECK(completion_cb);
+  // These errors really shouldn't ever happen, but they're not significant
+  // enough to crash the whole process over.
+  if (!result.has_value()) {
+    LOG(ERROR) << "JSON parsing failed with error: " << result.error();
+    std::move(completion_cb).Run(base::Value::Dict());
+    return;
+  }
+  if (!result->is_dict()) {
+    LOG(ERROR) << "Expected JSON dictionary for metrics";
+    std::move(completion_cb).Run(base::Value::Dict());
+    return;
+  }
+  std::move(completion_cb).Run(std::move(*result).TakeDict());
+}
+
+// Retrieves the the JSON dictionary in the `web_view`'s URL fragment.
+void GetAmbientVideoPlaybackMetrics(
+    AshWebView* web_view,
+    base::OnceCallback<void(base::Value::Dict)> completion_cb) {
+  CHECK(web_view);
+  CHECK(completion_cb);
+  // The URL fragment identifier is used as a way of communicating the playback
+  // metrics data without using any elaborate frameworks or permissions
+  // (ex: a WebUI).
+  std::string serialized_playback_metrics =
+      net::UnescapePercentEncodedUrl(web_view->GetVisibleURL().ref());
+  if (serialized_playback_metrics.empty()) {
+    // This can legitimately happen if the ambient video is still being loaded
+    // and it's still unclear whether playback has started successfully or
+    // failed.
+    DVLOG(2) << "Ambient video still loading";
+    std::move(completion_cb).Run(base::Value::Dict());
+    return;
+  }
+  data_decoder::DataDecoder::ParseJsonIsolated(
+      serialized_playback_metrics,
+      base::BindOnce(&OnAmbientVideoPlaybackMetricsParsed,
+                     std::move(completion_cb)));
+}
+
+AmbientVideoSessionStatus ParseAmbientVideoSessionStatus(
+    const base::Value::Dict& playback_metrics) {
+  absl::optional<bool> playback_started =
+      playback_metrics.FindBool(kVideoFieldPlaybackStarted);
+  if (playback_started.has_value()) {
+    return *playback_started ? AmbientVideoSessionStatus::kSuccess
+                             : AmbientVideoSessionStatus::kFailed;
+  } else {
+    // `playback_started` is not set in the URL fragment identifier until it's
+    // clear that playback has definitely started successfully or failed.
+    return AmbientVideoSessionStatus::kLoading;
+  }
+}
+
+// `GetAmbientModeVideoSessionStatus()` continued:
+// After the `playback_metrics` have been parsed from the URL fragment:
+void CompleteGetAmbientVideoSessionStatus(
+    base::OnceCallback<void(AmbientVideoSessionStatus)> completion_cb,
+    base::Value::Dict playback_metrics) {
+  CHECK(completion_cb);
+  std::move(completion_cb)
+      .Run(ParseAmbientVideoSessionStatus(playback_metrics));
+}
+
+// `RecordAmbientModeVideoSessionStatus()` continued:
+// After the `AmbientVideoSessionStatus` has been parsed from the URL fragment:
+void RecordAmbientModeVideoSessionStatusInternal(
+    const AmbientUiSettings& ui_settings,
+    AmbientVideoSessionStatus status) {
+  base::UmaHistogramEnumeration(
+      /*name=*/base::StrCat(
+          {"Ash.AmbientMode.VideoPlaybackStatus.", ui_settings.ToString()}),
+      status);
+}
+
+// `RecordAmbientModeVideoSmoothness()` continued:
+// After the `playback_metrics` have been parsed from the URL fragment:
+void RecordAmbientModeVideoSmoothnessInternal(
+    const AmbientUiSettings& ui_settings,
+    base::Value::Dict playback_metrics) {
+  CHECK_EQ(ui_settings.theme(), AmbientTheme::kVideo);
+  if (ParseAmbientVideoSessionStatus(playback_metrics) !=
+      AmbientVideoSessionStatus::kSuccess) {
+    // Just to prevent error log spam below. If playback failed completely,
+    // `RecordAmbientModeVideoSessionStatus()` should cover that.
+    return;
+  }
+  absl::optional<int> dropped_frames =
+      playback_metrics.FindInt(kVideoFieldDroppedFrames);
+  // Assuming 24 fps, the ambient session would have to last ~2.83 years before
+  // the int overflows. For all intensive purposes, this should not happen.
+  absl::optional<int> expected_frames =
+      playback_metrics.FindInt(kVideoFieldTotalFrames);
+  if (!dropped_frames || !expected_frames) {
+    LOG(ERROR) << "Received invalid metrics dictionary: " << playback_metrics;
+    return;
+  }
+  if (*dropped_frames < 0 || *expected_frames <= 0 ||
+      *dropped_frames > *expected_frames) {
+    LOG(ERROR) << "Frame statistics are invalid: " << playback_metrics;
+    return;
+  }
+  int created_frames = *expected_frames - *dropped_frames;
+  int smoothness = base::ClampRound(
+      100.f * (static_cast<float>(created_frames) / *expected_frames));
+  base::UmaHistogramPercentage(base::StrCat({"Ash.AmbientMode.VideoSmoothness.",
+                                             ui_settings.ToString()}),
+                               smoothness);
+}
+
 }  // namespace
 
 AmbientModePhotoSource AmbientSettingsToPhotoSource(
@@ -160,48 +283,32 @@
       /*buckets=*/50);
 }
 
+void GetAmbientModeVideoSessionStatus(
+    AshWebView* web_view,
+    base::OnceCallback<void(AmbientVideoSessionStatus)> completion_cb) {
+  CHECK(completion_cb);
+  if (web_view->IsErrorDocument()) {
+    // There was an issue loading the actual html.
+    std::move(completion_cb).Run(AmbientVideoSessionStatus::kFailed);
+    return;
+  }
+  GetAmbientVideoPlaybackMetrics(
+      web_view, base::BindOnce(&CompleteGetAmbientVideoSessionStatus,
+                               std::move(completion_cb)));
+}
+
+void RecordAmbientModeVideoSessionStatus(AshWebView* web_view,
+                                         const AmbientUiSettings& ui_settings) {
+  GetAmbientModeVideoSessionStatus(
+      web_view, base::BindOnce(&RecordAmbientModeVideoSessionStatusInternal,
+                               ui_settings));
+}
+
 void RecordAmbientModeVideoSmoothness(AshWebView* web_view,
                                       const AmbientUiSettings& ui_settings) {
-  CHECK(web_view);
-  CHECK_EQ(ui_settings.theme(), AmbientTheme::kVideo);
-  // The URL fragment identifier is used as a way of communicating the playback
-  // metrics data without using any elaborate frameworks or permissions
-  // (ex: a WebUI).
-  std::string serialized_playback_metrics =
-      net::UnescapePercentEncodedUrl(web_view->GetVisibleURL().ref());
-  if (serialized_playback_metrics.empty()) {
-    // This can legitimately happen if the ambient session was too short (just a
-    // couple seconds) and not statistically significant enough to record.
-    DVLOG(2) << "Ambient video session not long enough to record smoothness";
-    return;
-  }
-  absl::optional<base::Value::Dict> playback_metrics =
-      base::JSONReader::ReadDict(serialized_playback_metrics);
-  if (!playback_metrics) {
-    LOG(ERROR) << "Received non-json metrics: " << serialized_playback_metrics;
-    return;
-  }
-  absl::optional<int> dropped_frames =
-      playback_metrics->FindInt(kVideoFieldDroppedFrames);
-  // Assuming 24 fps, the ambient session would have to last ~2.83 years before
-  // the int overflows. For all intensive purposes, this should not happen.
-  absl::optional<int> expected_frames =
-      playback_metrics->FindInt(kVideoFieldTotalFrames);
-  if (!dropped_frames || !expected_frames) {
-    LOG(ERROR) << "Received invalid metrics dictionary: " << *playback_metrics;
-    return;
-  }
-  if (*dropped_frames < 0 || *expected_frames <= 0 ||
-      *dropped_frames > *expected_frames) {
-    LOG(ERROR) << "Frame statistics are invalid: " << *playback_metrics;
-    return;
-  }
-  int created_frames = *expected_frames - *dropped_frames;
-  int smoothness = base::ClampRound(
-      100.f * (static_cast<float>(created_frames) / *expected_frames));
-  base::UmaHistogramPercentage(base::StrCat({"Ash.AmbientMode.VideoSmoothness.",
-                                             ui_settings.ToString()}),
-                               smoothness);
+  GetAmbientVideoPlaybackMetrics(
+      web_view,
+      base::BindOnce(&RecordAmbientModeVideoSmoothnessInternal, ui_settings));
 }
 
 AmbientOrientationMetricsRecorder::AmbientOrientationMetricsRecorder(
diff --git a/ash/ambient/metrics/ambient_metrics.h b/ash/ambient/metrics/ambient_metrics.h
index 2ba077d..32522769 100644
--- a/ash/ambient/metrics/ambient_metrics.h
+++ b/ash/ambient/metrics/ambient_metrics.h
@@ -9,6 +9,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/public/cpp/ambient/ambient_mode_photo_source.h"
+#include "base/functional/callback.h"
 #include "base/scoped_observation.h"
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
@@ -26,6 +27,20 @@
 
 namespace ambient {
 
+// These values are persisted to UMA logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class AmbientVideoSessionStatus {
+  // Confirmed playback started successfully.
+  kSuccess = 0,
+  // Confirmed playback failed with a hard error.
+  kFailed = 1,
+  // User terminated ambient session while video was still loading. Unknown
+  // whether playback would have ultimately succeeded or not. This should be
+  // rare.
+  kLoading = 2,
+  kMaxValue = kLoading,
+};
+
 // Duration after which ambient mode is considered to have failed to start.
 // See summary in histograms.xml for why 15 seconds is used.
 constexpr base::TimeDelta kMetricsStartupTimeMax = base::Seconds(15);
@@ -57,6 +72,14 @@
     base::TimeDelta startup_time,
     const AmbientUiSettings& ui_settings);
 
+ASH_EXPORT void GetAmbientModeVideoSessionStatus(
+    AshWebView* web_view,
+    base::OnceCallback<void(AmbientVideoSessionStatus)> completion_cb);
+
+ASH_EXPORT void RecordAmbientModeVideoSessionStatus(
+    AshWebView* web_view,
+    const AmbientUiSettings& ui_settings);
+
 ASH_EXPORT void RecordAmbientModeVideoSmoothness(
     AshWebView* web_view,
     const AmbientUiSettings& ui_settings);
diff --git a/ash/ambient/metrics/ambient_metrics_unittest.cc b/ash/ambient/metrics/ambient_metrics_unittest.cc
index 80bbceb1..a039b43 100644
--- a/ash/ambient/metrics/ambient_metrics_unittest.cc
+++ b/ash/ambient/metrics/ambient_metrics_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/test/task_environment.h"
 #include "base/timer/elapsed_timer.h"
 #include "net/base/url_util.h"
+#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/views/view.h"
@@ -97,68 +98,121 @@
       base::ScopedMockElapsedTimersForTest::kMockElapsedTime, 1);
 }
 
-TEST(AmbientMetricsTest, RecordAmbientModeVideoSmoothness) {
-  base::test::TaskEnvironment task_environment;
-  base::HistogramTester histogram_tester;
-  AshWebView::InitParams init_params;
-  TestAshWebView view(init_params);
-  view.Navigate(net::AppendOrReplaceRef(
-      GURL("http://test.com"), R"({"dropped_frames":1,"total_frames":5})"));
+class AmbientMetricsVideoTest : public ::testing::Test {
+ protected:
+  AmbientMetricsVideoTest() : view_(init_params_) {}
+
+  void RecordAmbientModeVideoSmoothness(const AmbientUiSettings& ui_settings) {
+    ::ash::ambient::RecordAmbientModeVideoSmoothness(&view_, ui_settings);
+    task_environment_.RunUntilIdle();
+  }
+
+  void RecordAmbientModeVideoSessionStatus(
+      const AmbientUiSettings& ui_settings) {
+    ::ash::ambient::RecordAmbientModeVideoSessionStatus(&view_, ui_settings);
+    task_environment_.RunUntilIdle();
+  }
+
+  base::test::TaskEnvironment task_environment_;
+  data_decoder::test::InProcessDataDecoder data_decoder_;
+  base::HistogramTester histogram_tester_;
+  const AshWebView::InitParams init_params_;
+  TestAshWebView view_;
+};
+
+TEST_F(AmbientMetricsVideoTest, RecordAmbientModeVideoSmoothness) {
+  view_.Navigate(net::AppendOrReplaceRef(
+      GURL("http://test.com"),
+      R"({"playback_started":true,"dropped_frames":1,"total_frames":5})"));
   RecordAmbientModeVideoSmoothness(
-      &view, AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
-  histogram_tester.ExpectBucketCount(
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+  histogram_tester_.ExpectBucketCount(
       "Ash.AmbientMode.VideoSmoothness.Video.Clouds", 80, 1);
 
-  view.Navigate(net::AppendOrReplaceRef(
-      GURL("http://test.com"), R"({"dropped_frames":5,"total_frames":5})"));
+  view_.Navigate(net::AppendOrReplaceRef(
+      GURL("http://test.com"),
+      R"({"playback_started":true,"dropped_frames":5,"total_frames":5})"));
   RecordAmbientModeVideoSmoothness(
-      &view, AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
-  histogram_tester.ExpectBucketCount(
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+  histogram_tester_.ExpectBucketCount(
       "Ash.AmbientMode.VideoSmoothness.Video.Clouds", 0, 1);
 
-  view.Navigate(net::AppendOrReplaceRef(
-      GURL("http://test.com"), R"({"dropped_frames":0,"total_frames":5})"));
+  view_.Navigate(net::AppendOrReplaceRef(
+      GURL("http://test.com"),
+      R"({"playback_started":true,"dropped_frames":0,"total_frames":5})"));
   RecordAmbientModeVideoSmoothness(
-      &view, AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
-  histogram_tester.ExpectBucketCount(
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+  histogram_tester_.ExpectBucketCount(
       "Ash.AmbientMode.VideoSmoothness.Video.Clouds", 100, 1);
 }
 
-TEST(AmbientMetricsTest, RecordAmbientModeVideoSmoothnessInvalidInput) {
-  base::test::TaskEnvironment task_environment;
-  base::HistogramTester histogram_tester;
-  AshWebView::InitParams init_params;
-  TestAshWebView view(init_params);
-
-  view.Navigate(
+TEST_F(AmbientMetricsVideoTest, RecordAmbientModeVideoSmoothnessInvalidInput) {
+  view_.Navigate(
       net::AppendOrReplaceRef(GURL("http://test.com"), "invalid-json"));
   RecordAmbientModeVideoSmoothness(
-      &view, AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
 
-  view.Navigate(net::AppendOrReplaceRef(GURL("http://test.com"),
-                                        R"({"total_frames":5})"));
+  view_.Navigate(
+      net::AppendOrReplaceRef(GURL("http://test.com"),
+                              R"({"playback_started":true,"total_frames":5})"));
   RecordAmbientModeVideoSmoothness(
-      &view, AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
 
-  view.Navigate(net::AppendOrReplaceRef(GURL("http://test.com"),
-                                        R"({"dropped_frames":5})"));
+  view_.Navigate(net::AppendOrReplaceRef(
+      GURL("http://test.com"),
+      R"({"playback_started":true,"dropped_frames":5})"));
   RecordAmbientModeVideoSmoothness(
-      &view, AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
 
-  view.Navigate(net::AppendOrReplaceRef(
-      GURL("http://test.com"), R"({"dropped_frames":0,"total_frames":0})"));
+  view_.Navigate(net::AppendOrReplaceRef(
+      GURL("http://test.com"),
+      R"({"playback_started":true,"dropped_frames":0,"total_frames":0})"));
   RecordAmbientModeVideoSmoothness(
-      &view, AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
 
-  view.Navigate(net::AppendOrReplaceRef(
-      GURL("http://test.com"), R"({"dropped_frames":20,"total_frames":10})"));
+  view_.Navigate(net::AppendOrReplaceRef(
+      GURL("http://test.com"),
+      R"({"playback_started":true,"dropped_frames":20,"total_frames":10})"));
   RecordAmbientModeVideoSmoothness(
-      &view, AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
 
-  histogram_tester.ExpectTotalCount(
+  histogram_tester_.ExpectTotalCount(
       "Ash.AmbientMode.VideoSmoothness.Video.Clouds", 0);
 }
 
+TEST_F(AmbientMetricsVideoTest, RecordAmbientModeVideoSessionStatus) {
+  view_.Navigate(net::AppendOrReplaceRef(GURL("http://test.com"),
+                                         R"({"playback_started":true})"));
+  RecordAmbientModeVideoSessionStatus(
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+  histogram_tester_.ExpectBucketCount(
+      "Ash.AmbientMode.VideoPlaybackStatus.Video.Clouds",
+      AmbientVideoSessionStatus::kSuccess, 1);
+
+  view_.Navigate(net::AppendOrReplaceRef(GURL("http://test.com"),
+                                         R"({"playback_started":false})"));
+  RecordAmbientModeVideoSessionStatus(
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+  histogram_tester_.ExpectBucketCount(
+      "Ash.AmbientMode.VideoPlaybackStatus.Video.Clouds",
+      AmbientVideoSessionStatus::kFailed, 1);
+
+  view_.Navigate(GURL("http://test.com"));
+  RecordAmbientModeVideoSessionStatus(
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+  histogram_tester_.ExpectBucketCount(
+      "Ash.AmbientMode.VideoPlaybackStatus.Video.Clouds",
+      AmbientVideoSessionStatus::kLoading, 1);
+
+  view_.set_is_error_document(true);
+  view_.Navigate(GURL("http://test.com"));
+  RecordAmbientModeVideoSessionStatus(
+      AmbientUiSettings(AmbientTheme::kVideo, AmbientVideo::kClouds));
+  histogram_tester_.ExpectBucketCount(
+      "Ash.AmbientMode.VideoPlaybackStatus.Video.Clouds",
+      AmbientVideoSessionStatus::kFailed, 2);
+}
+
 }  // namespace metrics
 }  // namespace ambient
 }  // namespace ash
diff --git a/ash/ambient/ui/ambient_video_view.cc b/ash/ambient/ui/ambient_video_view.cc
index e098ca3..df275384 100644
--- a/ash/ambient/ui/ambient_video_view.cc
+++ b/ash/ambient/ui/ambient_video_view.cc
@@ -71,8 +71,10 @@
 }
 
 AmbientVideoView::~AmbientVideoView() {
-  ambient::RecordAmbientModeVideoSmoothness(
-      ash_web_view_.get(), AmbientUiSettings(AmbientTheme::kVideo, video_));
+  AmbientUiSettings ui_settings(AmbientTheme::kVideo, video_);
+  ambient::RecordAmbientModeVideoSessionStatus(ash_web_view_.get(),
+                                               ui_settings);
+  ambient::RecordAmbientModeVideoSmoothness(ash_web_view_.get(), ui_settings);
 }
 
 }  // namespace ash
diff --git a/ash/app_list/app_list_metrics.cc b/ash/app_list/app_list_metrics.cc
index f3a704db..4f266ff 100644
--- a/ash/app_list/app_list_metrics.cc
+++ b/ash/app_list/app_list_metrics.cc
@@ -182,6 +182,7 @@
     case AppListShowSource::kTabletMode:
     case AppListShowSource::kAssistantEntryPoint:
     case AppListShowSource::kBrowser:
+    case AppListShowSource::kWelcomeTour:
       return "Others";
   }
   NOTREACHED();
diff --git a/ash/app_list/views/app_list_search_view.cc b/ash/app_list/views/app_list_search_view.cc
index 7b984b4e..730bee7 100644
--- a/ash/app_list/views/app_list_search_view.cc
+++ b/ash/app_list/views/app_list_search_view.cc
@@ -108,8 +108,7 @@
   auto* answer_card_container =
       scroll_contents->AddChildView(std::make_unique<SearchResultListView>(
           view_delegate, dialog_controller_,
-          SearchResultView::SearchResultViewType::kAnswerCard,
-          /*animates_result_updates=*/true, absl::nullopt));
+          SearchResultView::SearchResultViewType::kAnswerCard, absl::nullopt));
   answer_card_container->SetListType(
       SearchResultListView::SearchResultListType::kAnswerCard);
   add_result_container(answer_card_container);
@@ -118,8 +117,7 @@
   auto* best_match_container =
       scroll_contents->AddChildView(std::make_unique<SearchResultListView>(
           view_delegate, dialog_controller_,
-          SearchResultView::SearchResultViewType::kDefault,
-          /*animated_result_updates=*/true, absl::nullopt));
+          SearchResultView::SearchResultViewType::kDefault, absl::nullopt));
   best_match_container->SetListType(
       SearchResultListView::SearchResultListType::kBestMatch);
   add_result_container(best_match_container);
@@ -143,8 +141,7 @@
     auto* result_container =
         scroll_contents->AddChildView(std::make_unique<SearchResultListView>(
             view_delegate, dialog_controller_,
-            SearchResultView::SearchResultViewType::kDefault,
-            /*animates_result_updates=*/true, i));
+            SearchResultView::SearchResultViewType::kDefault, i));
     add_result_container(result_container);
   }
 
diff --git a/ash/app_list/views/result_selection_controller_unittest.cc b/ash/app_list/views/result_selection_controller_unittest.cc
index 61361a4..b780e54 100644
--- a/ash/app_list/views/result_selection_controller_unittest.cc
+++ b/ash/app_list/views/result_selection_controller_unittest.cc
@@ -139,6 +139,11 @@
 
  private:
   int DoUpdate() override { return search_result_views_.size(); }
+  void UpdateResultsVisibility(bool force_hide) override {}
+  views::View* GetTitleLabel() override { return nullptr; }
+  std::vector<views::View*> GetViewsToAnimate() override {
+    return std::vector<views::View*>();
+  }
 
   std::map<std::string, std::unique_ptr<TestSearchResult>> results_;
   std::vector<std::unique_ptr<TestResultView>> search_result_views_;
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc
index 75dbd1e..b256d74 100644
--- a/ash/app_list/views/search_box_view.cc
+++ b/ash/app_list/views/search_box_view.cc
@@ -32,6 +32,8 @@
 #include "ash/style/ash_color_id.h"
 #include "ash/style/ash_color_provider.h"
 #include "ash/style/typography.h"
+#include "ash/user_education/user_education_class_properties.h"
+#include "ash/user_education/user_education_constants.h"
 #include "base/i18n/rtl.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -247,6 +249,13 @@
       model_provider->search_model()->search_box();
   search_box_model_observer_.Observe(search_box_model);
 
+  if (features::IsUserEducationEnabled()) {
+    // NOTE: Set `kHelpBubbleContextKey` before `views::kElementIdentifierKey`
+    // in case registration causes a help bubble to be created synchronously.
+    SetProperty(kHelpBubbleContextKey, HelpBubbleContext::kAsh);
+    SetProperty(views::kElementIdentifierKey, kSearchBoxViewElementId);
+  }
+
   if (is_jelly_enabled_) {
     auto font_list = TypographyProvider::Get()->ResolveTypographyToken(
         TypographyToken::kCrosBody1);
diff --git a/ash/app_list/views/search_result_container_view.cc b/ash/app_list/views/search_result_container_view.cc
index c33f066..f7a44d52 100644
--- a/ash/app_list/views/search_result_container_view.cc
+++ b/ash/app_list/views/search_result_container_view.cc
@@ -4,9 +4,27 @@
 
 #include "ash/app_list/views/search_result_container_view.h"
 
+#include "ash/public/cpp/app_list/app_list_features.h"
 #include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/task/single_thread_task_runner.h"
+#include "ui/compositor/layer.h"
+#include "ui/views/animation/animation_builder.h"
+#include "ui/views/controls/label.h"
+
+namespace {
+
+constexpr base::TimeDelta kFadeInDuration = base::Milliseconds(100);
+constexpr base::TimeDelta kIdentityTranslationDuration =
+    base::Milliseconds(200);
+constexpr base::TimeDelta kFastFadeInDuration = base::Milliseconds(0);
+
+// Show animations for search result views and titles have a translation
+// distance of 'kAnimatedOffsetMultiplier' * i where i is the position of the
+// view in the 'AppListSearchView'.
+constexpr int kAnimatedOffsetMultiplier = 4;
+
+}  // namespace
 
 namespace ash {
 
@@ -64,8 +82,64 @@
 absl::optional<SearchResultContainerView::ResultsAnimationInfo>
 SearchResultContainerView::ScheduleResultAnimations(
     const ResultsAnimationInfo& aggregate_animation_info) {
-  NOTREACHED();
-  return absl::nullopt;
+  // Collect current container animation info.
+  ResultsAnimationInfo current_animation_info;
+
+  if (num_results() < 1 || !enabled_) {
+    UpdateResultsVisibility(/*force_hide=*/true);
+    return current_animation_info;
+  }
+
+  // All views should be animated if
+  // *   the container is being shown, or
+  // *   any of the result views that precede the container in the search UI are
+  //     animating, or
+  // *   if the first animating result view is in a preceding container.
+  bool force_animation =
+      !GetVisible() || aggregate_animation_info.animating_views > 0 ||
+      aggregate_animation_info.first_animated_result_view_index <=
+          aggregate_animation_info.total_result_views;
+
+  UpdateResultsVisibility(/*force_hide=*/false);
+  current_animation_info.use_short_animations =
+      aggregate_animation_info.use_short_animations;
+
+  auto schedule_animation =
+      [&current_animation_info,
+       &aggregate_animation_info](views::View* animated_view) {
+        ShowViewWithAnimation(animated_view,
+                              current_animation_info.total_views +
+                                  aggregate_animation_info.total_views,
+                              current_animation_info.use_short_animations);
+        ++current_animation_info.animating_views;
+      };
+
+  views::View* title_label = GetTitleLabel();
+  if (title_label && title_label->GetVisible()) {
+    if (force_animation) {
+      schedule_animation(title_label);
+    }
+    ++current_animation_info.total_views;
+  }
+
+  for (auto* result_view : GetViewsToAnimate()) {
+    // Checks whether the index of the current result view is greater than
+    // or equal to the index of the first result view that should be animated.
+    // Force animations if true.
+    if (aggregate_animation_info.total_result_views +
+            current_animation_info.total_result_views >=
+        aggregate_animation_info.first_animated_result_view_index) {
+      force_animation = true;
+    }
+    if (force_animation) {
+      schedule_animation(result_view);
+    }
+
+    ++current_animation_info.total_views;
+    ++current_animation_info.total_result_views;
+  }
+
+  return current_animation_info;
 }
 
 void SearchResultContainerView::AppendShownResultMetadata(
@@ -74,7 +148,22 @@
 }
 
 bool SearchResultContainerView::HasAnimatingChildView() {
-  NOTREACHED();
+  auto is_animating = [](views::View* view) {
+    return (view->GetVisible() && view->layer() &&
+            view->layer()->GetAnimator() &&
+            view->layer()->GetAnimator()->is_animating());
+  };
+
+  if (is_animating(GetTitleLabel())) {
+    return true;
+  }
+
+  for (auto* result_view : GetViewsToAnimate()) {
+    if (is_animating(result_view)) {
+      return true;
+    }
+  }
+
   return false;
 }
 
@@ -139,6 +228,48 @@
   return true;
 }
 
+// static
+void SearchResultContainerView::ShowViewWithAnimation(
+    views::View* result_view,
+    int position,
+    bool use_short_animations) {
+  DCHECK(result_view->layer()->GetAnimator());
+
+  // Abort any in-progress layer animation.
+  result_view->layer()->GetAnimator()->AbortAllAnimations();
+
+  // Animation spec:
+  //
+  // Y Position: Down (offset) → End position
+  // offset: position * kAnimatedOffsetMultiplier px
+  // Duration: 200ms
+  // Ease: (0.00, 0.00, 0.20, 1.00)
+
+  // Opacity: 0% -> 100%
+  // Duration: 100 ms
+  // Ease: Linear
+
+  gfx::Transform translate_down;
+  translate_down.Translate(0, position * kAnimatedOffsetMultiplier);
+
+  views::AnimationBuilder()
+      .SetPreemptionStrategy(
+          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
+      .Once()
+      .SetOpacity(result_view, 0.0f)
+      .SetTransform(result_view, translate_down)
+      .Then()
+      .SetOpacity(result_view, 1.0f, gfx::Tween::LINEAR)
+      .SetDuration(use_short_animations ? kFastFadeInDuration : kFadeInDuration)
+      .At(base::TimeDelta())
+      .SetDuration(
+          use_short_animations
+              ? app_list_features::DynamicSearchUpdateAnimationDuration()
+              : kIdentityTranslationDuration)
+      .SetTransform(result_view, gfx::Transform(),
+                    gfx::Tween::LINEAR_OUT_SLOW_IN);
+}
+
 void SearchResultContainerView::ScheduleUpdate() {
   if (!active_)
     return;
diff --git a/ash/app_list/views/search_result_container_view.h b/ash/app_list/views/search_result_container_view.h
index dee58c9..0ba578e 100644
--- a/ash/app_list/views/search_result_container_view.h
+++ b/ash/app_list/views/search_result_container_view.h
@@ -157,6 +157,29 @@
   // actually run (i.e. whether an update was scheduled).
   bool RunScheduledUpdateForTest();
 
+ protected:
+  // Fades the view in and animates a vertical transform based on the view's
+  // position in the overall search container view.
+  static void ShowViewWithAnimation(views::View* result_view,
+                                    int position,
+                                    bool use_short_animations);
+
+  // Updates the visibility of this container view and its children result
+  // views. Force hiding all views if `force_hide` is set to true.
+  virtual void UpdateResultsVisibility(bool force_hide) = 0;
+
+  // Returns the title label if there is one, otherwise returns nullptr.
+  virtual views::View* GetTitleLabel() = 0;
+
+  // Returns the views in the container that will be animated to become visible.
+  virtual std::vector<views::View*> GetViewsToAnimate() = 0;
+
+  // A search result list view may be disabled if there are fewer search result
+  // categories than there are search result list views in the
+  // 'productivity_launcher_search_view_'. A disabled view does not query the
+  // search model.
+  bool enabled_ = true;
+
  private:
   // Schedules an Update call using |update_factory_|. Do nothing if there is a
   // pending call.
diff --git a/ash/app_list/views/search_result_image_list_view.cc b/ash/app_list/views/search_result_image_list_view.cc
index a4615e6e..d1e3df7 100644
--- a/ash/app_list/views/search_result_image_list_view.cc
+++ b/ash/app_list/views/search_result_image_list_view.cc
@@ -60,6 +60,8 @@
 
   image_view_container_ =
       AddChildView(std::make_unique<views::BoxLayoutView>());
+  image_view_container_->SetPaintToLayer();
+  image_view_container_->layer()->SetFillsBoundsOpaquely(false);
 
   // TODO(crbug.com/1352636) replace mock results with real results.
   int dummy_search_result_id = 0;
@@ -131,26 +133,12 @@
   return image_views_[index];
 }
 
-bool SearchResultImageListView::HasAnimatingChildView() {
-  // TODO(crbug.com/1352636) Update once animations are defined by UX.
-  return false;
-}
-
 void SearchResultImageListView::AppendShownResultMetadata(
     std::vector<SearchResultAimationMetadata>* result_metadata_) {
   // TODO(crbug.com/1352636) Update once animations are defined by UX.
   return;
 }
 
-absl::optional<SearchResultContainerView::ResultsAnimationInfo>
-SearchResultImageListView::ScheduleResultAnimations(
-    const ResultsAnimationInfo& aggregate_animation_info) {
-  SetVisible(true);
-  // TODO(crbug.com/1352636) Update once animations are defined by UX. There is
-  // no animation information to be returned for this container.
-  return absl::nullopt;
-}
-
 std::vector<SearchResultImageView*>
 SearchResultImageListView::GetSearchResultImageViews() {
   return image_views_;
@@ -180,19 +168,33 @@
   for (size_t i = 0; i < image_views_.size(); ++i) {
     SearchResultImageView* result_view = GetResultViewAt(i);
     if (i < num_results) {
-      result_view->SetVisible(true);
       result_view->SetResult(display_results[i]);
       result_view->SizeToPreferredSize();
     } else {
-      result_view->SetVisible(false);
       result_view->SetResult(nullptr);
     }
   }
-  image_info_container_->SetVisible(num_results == 1);
-  SetVisible(num_results > 0);
+
   return num_results;
 }
 
+void SearchResultImageListView::UpdateResultsVisibility(bool force_hide) {
+  SetVisible(num_results() > 0 && !force_hide);
+  for (size_t i = 0; i < image_views_.size(); ++i) {
+    SearchResultImageView* result_view = GetResultViewAt(i);
+    result_view->SetVisible(i < num_results() && !force_hide);
+  }
+  image_info_container_->SetVisible(num_results() == 1 && !force_hide);
+}
+
+views::View* SearchResultImageListView::GetTitleLabel() {
+  return title_label_.get();
+}
+
+std::vector<views::View*> SearchResultImageListView::GetViewsToAnimate() {
+  return {image_view_container_};
+}
+
 BEGIN_METADATA(SearchResultImageListView, SearchResultContainerView)
 END_METADATA
 
diff --git a/ash/app_list/views/search_result_image_list_view.h b/ash/app_list/views/search_result_image_list_view.h
index 3e42ca2..bec73d5 100644
--- a/ash/app_list/views/search_result_image_list_view.h
+++ b/ash/app_list/views/search_result_image_list_view.h
@@ -39,11 +39,8 @@
 
   // Overridden from SearchResultContainerView:
   SearchResultImageView* GetResultViewAt(size_t index) override;
-  bool HasAnimatingChildView() override;
   void AppendShownResultMetadata(
       std::vector<SearchResultAimationMetadata>* result_metadata_) override;
-  absl::optional<ResultsAnimationInfo> ScheduleResultAnimations(
-      const ResultsAnimationInfo& aggregate_animation_info) override;
 
   // Returns all search result image views children of this view.
   std::vector<SearchResultImageView*> GetSearchResultImageViews();
@@ -59,6 +56,9 @@
   // Overridden from SearchResultContainerView:
   void OnSelectedResultChanged() override;
   int DoUpdate() override;
+  void UpdateResultsVisibility(bool force_hide) override;
+  views::View* GetTitleLabel() override;
+  std::vector<views::View*> GetViewsToAnimate() override;
 
   // The singleton delegate for search result image views that implements
   // support for context menu and drag-and-drop operations. This delegate needs
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc
index 5e0d529..d0ee3c6 100644
--- a/ash/app_list/views/search_result_list_view.cc
+++ b/ash/app_list/views/search_result_list_view.cc
@@ -17,7 +17,6 @@
 #include "ash/app_list/model/search/search_result.h"
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_config.h"
-#include "ash/public/cpp/app_list/app_list_features.h"
 #include "ash/public/cpp/app_list/app_list_metrics.h"
 #include "ash/public/cpp/app_list/app_list_notifier.h"
 #include "ash/public/cpp/ash_typography.h"
@@ -25,16 +24,13 @@
 #include "ash/style/ash_color_id.h"
 #include "ash/style/typography.h"
 #include "base/dcheck_is_on.h"
-#include "base/time/time.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/compositor/layer.h"
-#include "ui/compositor/layer_animator.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/views/accessibility/view_accessibility.h"
-#include "ui/views/animation/animation_builder.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/flex_layout.h"
@@ -48,17 +44,6 @@
 constexpr int kPreferredTitleTopMargins = 12;
 constexpr int kPreferredTitleBottomMargins = 4;
 
-constexpr static base::TimeDelta kFadeInDuration = base::Milliseconds(100);
-constexpr static base::TimeDelta kIdentityTranslationDuration =
-    base::Milliseconds(200);
-
-constexpr static base::TimeDelta kFastFadeInDuration = base::Milliseconds(0);
-
-// Show animations for search result views and titles have a translation
-// distance of 'kAnimatedOffsetMultiplier' * i where i is the position of the
-// view in the 'AppListSearchView'.
-constexpr int kAnimatedOffsetMultiplier = 4;
-
 // Maps 'AppListSearchResultCategory' to 'SearchResultListType'.
 SearchResultListView::SearchResultListType CategoryToListType(
     ash::AppListSearchResultCategory category) {
@@ -93,10 +78,8 @@
     AppListViewDelegate* view_delegate,
     SearchResultPageDialogController* dialog_controller,
     SearchResultView::SearchResultViewType search_result_view_type,
-    bool animates_result_updates,
     absl::optional<size_t> productivity_launcher_index)
     : SearchResultContainerView(view_delegate),
-      animates_result_updates_(animates_result_updates),
       results_container_(new views::View),
       productivity_launcher_index_(productivity_launcher_index),
       search_result_view_type_(search_result_view_type) {
@@ -265,74 +248,6 @@
   return categorical_search_types;
 }
 
-absl::optional<SearchResultContainerView::ResultsAnimationInfo>
-SearchResultListView::ScheduleResultAnimations(
-    const ResultsAnimationInfo& aggregate_animation_info) {
-  DCHECK(animates_result_updates_);
-
-  // Collect current container animation info.
-  ResultsAnimationInfo current_animation_info;
-
-  if (num_results() < 1 || !enabled_) {
-    SetVisible(false);
-    for (auto* result_view : search_result_views_)
-      result_view->SetVisible(false);
-    return current_animation_info;
-  }
-
-  // All views should be animated if
-  // *   the container is being shown, or
-  // *   any of the result views that precede the container in the search UI are
-  //     animating, or
-  // *   if.the first animating result view is in a preceding container.
-  bool force_animation =
-      !GetVisible() || aggregate_animation_info.animating_views > 0 ||
-      aggregate_animation_info.first_animated_result_view_index <=
-          aggregate_animation_info.total_result_views;
-
-  SetVisible(true);
-  current_animation_info.use_short_animations =
-      aggregate_animation_info.use_short_animations;
-
-  auto schedule_animation = [this, &current_animation_info,
-                             &aggregate_animation_info](views::View* view) {
-    ShowViewWithAnimation(view,
-                          current_animation_info.total_views +
-                              aggregate_animation_info.total_views,
-                          current_animation_info.use_short_animations);
-    ++current_animation_info.animating_views;
-  };
-
-  if (title_label_->GetVisible()) {
-    if (force_animation)
-      schedule_animation(title_label_);
-    ++current_animation_info.total_views;
-  }
-
-  for (size_t i = 0; i < search_result_views_.size(); ++i) {
-    SearchResultView* result_view = GetResultViewAt(i);
-    result_view->SetVisible(i < num_results());
-
-    if (i < num_results()) {
-      // Checks whether the index of the current result view is greater than
-      // or equal to the index of the first result view that should be animated.
-      // Force animations if true.
-      if (aggregate_animation_info.total_result_views +
-              current_animation_info.total_result_views >=
-          aggregate_animation_info.first_animated_result_view_index) {
-        force_animation = true;
-      }
-      if (force_animation)
-        schedule_animation(result_view);
-
-      ++current_animation_info.total_views;
-      ++current_animation_info.total_result_views;
-    }
-  }
-
-  return current_animation_info;
-}
-
 void SearchResultListView::AppendShownResultMetadata(
     std::vector<SearchResultAimationMetadata>* result_metadata_) {
   for (size_t i = 0; i < search_result_views_.size(); ++i) {
@@ -347,62 +262,6 @@
   }
 }
 
-bool SearchResultListView::HasAnimatingChildView() {
-  auto is_animating = [](views::View* view) {
-    return (view->GetVisible() && view->layer() &&
-            view->layer()->GetAnimator() &&
-            view->layer()->GetAnimator()->is_animating());
-  };
-
-  if (is_animating(title_label_))
-    return true;
-
-  for (size_t i = 0; i < search_result_views_.size(); ++i) {
-    if (is_animating(GetResultViewAt(i)))
-      return true;
-  }
-  return false;
-}
-
-void SearchResultListView::ShowViewWithAnimation(views::View* view,
-                                                 int position,
-                                                 bool use_short_animations) {
-  DCHECK(view->layer()->GetAnimator());
-
-  // Abort any in-progress layer animation.
-  view->layer()->GetAnimator()->AbortAllAnimations();
-
-  // Animation spec:
-  //
-  // Y Position: Down (offset) → End position
-  // offset: position * kAnimatedOffsetMultiplier px
-  // Duration: 200ms
-  // Ease: (0.00, 0.00, 0.20, 1.00)
-
-  // Opacity: 0% -> 100%
-  // Duration: 100 ms
-  // Ease: Linear
-
-  gfx::Transform translate_down;
-  translate_down.Translate(0, position * kAnimatedOffsetMultiplier);
-
-  views::AnimationBuilder()
-      .SetPreemptionStrategy(
-          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
-      .Once()
-      .SetOpacity(view, 0.0f)
-      .SetTransform(view, translate_down)
-      .Then()
-      .SetOpacity(view, 1.0f, gfx::Tween::LINEAR)
-      .SetDuration(use_short_animations ? kFastFadeInDuration : kFadeInDuration)
-      .At(base::TimeDelta())
-      .SetDuration(
-          use_short_animations
-              ? app_list_features::DynamicSearchUpdateAnimationDuration()
-              : kIdentityTranslationDuration)
-      .SetTransform(view, gfx::Transform(), gfx::Tween::LINEAR_OUT_SLOW_IN);
-}
-
 void SearchResultListView::OnSelectedResultChanged() {
   for (SearchResultView* view : search_result_views_)
     view->OnSelectedResultChanged();
@@ -446,6 +305,27 @@
   return displayed_results.size();
 }
 
+void SearchResultListView::UpdateResultsVisibility(bool force_hide) {
+  SetVisible(num_results() > 0 && enabled_ && !force_hide);
+  for (size_t i = 0; i < search_result_views_.size(); ++i) {
+    SearchResultView* result_view = GetResultViewAt(i);
+    result_view->SetVisible(i < num_results() && !force_hide);
+  }
+}
+
+views::View* SearchResultListView::GetTitleLabel() {
+  return title_label_.get();
+}
+
+std::vector<views::View*> SearchResultListView::GetViewsToAnimate() {
+  std::vector<views::View*> results;
+  for (size_t i = 0; i < search_result_views_.size() && i < num_results();
+       ++i) {
+    results.push_back(GetResultViewAt(i));
+  }
+  return results;
+}
+
 void SearchResultListView::Layout() {
   results_container_->SetBoundsRect(GetLocalBounds());
 }
@@ -580,16 +460,8 @@
     } else {
       result_view->SetResult(nullptr);
     }
-    // If result updates are animated, the result visibility will be updated in
-    // `ScheduleResultAnimations()`
-    if (!animates_result_updates_)
-      result_view->SetVisible(i < num_results);
   }
 
-  // If result updates are animated, the container visibility will be updated in
-  // `ScheduleResultAnimations()`
-  if (!animates_result_updates_)
-    SetVisible(num_results > 0);
   return display_results;
 }
 
diff --git a/ash/app_list/views/search_result_list_view.h b/ash/app_list/views/search_result_list_view.h
index 63308406..803adcbb 100644
--- a/ash/app_list/views/search_result_list_view.h
+++ b/ash/app_list/views/search_result_list_view.h
@@ -75,7 +75,6 @@
       AppListViewDelegate* view_delegate,
       SearchResultPageDialogController* dialog_controller,
       SearchResultView::SearchResultViewType search_result_view_type,
-      bool animates_result_updates,
       absl::optional<size_t> productivity_launcher_index);
 
   SearchResultListView(const SearchResultListView&) = delete;
@@ -99,18 +98,8 @@
 
   // Overridden from SearchResultContainerView:
   SearchResultView* GetResultViewAt(size_t index) override;
-  absl::optional<ResultsAnimationInfo> ScheduleResultAnimations(
-      const ResultsAnimationInfo& aggregate_animation_info) override;
   void AppendShownResultMetadata(
       std::vector<SearchResultAimationMetadata>* result_metadata_) override;
-  bool HasAnimatingChildView() override;
-
-  // Fades the view in and animates a vertical transform based on the view's
-  // position in the overall search container view. Returns whether fast
-  // animations were used.
-  void ShowViewWithAnimation(views::View* view,
-                             int position,
-                             bool use_short_animations);
 
   // Gets all the SearchResultListTypes that should be used when categorical
   // search is enabled.
@@ -129,6 +118,9 @@
   // Overridden from SearchResultContainerView:
   void OnSelectedResultChanged() override;
   int DoUpdate() override;
+  void UpdateResultsVisibility(bool force_hide) override;
+  views::View* GetTitleLabel() override;
+  std::vector<views::View*> GetViewsToAnimate() override;
 
   // Overridden from views::View:
   void Layout() override;
@@ -152,11 +144,6 @@
   bool FilterSearchResultsByCategory(const SearchResult::Category& category,
                                      const SearchResult& result) const;
 
-  // Whether the result updates will be animated. If set,
-  // `ScheduleResultAnimations()` is expected to be called whenever list of
-  // results shown in the list changes.
-  const bool animates_result_updates_;
-
   raw_ptr<views::View, ExperimentalAsh> results_container_;
 
   std::vector<SearchResultView*> search_result_views_;  // Not owned.
@@ -173,12 +160,6 @@
   // category is const as for kBestMatch.
   const absl::optional<size_t> productivity_launcher_index_;
 
-  // A search result list view may be disabled if there are fewer search result
-  // categories than there are search result list views in the
-  // 'productivity_launcher_search_view_'. A disabled view does not query the
-  // search model.
-  bool enabled_ = true;
-
   const SearchResultView::SearchResultViewType search_result_view_type_;
 
   // Set of results that have been removed from the result list using remove
diff --git a/ash/app_list/views/search_result_list_view_unittest.cc b/ash/app_list/views/search_result_list_view_unittest.cc
index ece2735..7aa04b5 100644
--- a/ash/app_list/views/search_result_list_view_unittest.cc
+++ b/ash/app_list/views/search_result_list_view_unittest.cc
@@ -59,15 +59,14 @@
 
     default_view_ = std::make_unique<SearchResultListView>(
         &view_delegate_, nullptr,
-        SearchResultView::SearchResultViewType::kDefault, true, absl::nullopt);
+        SearchResultView::SearchResultViewType::kDefault, absl::nullopt);
     default_view_->SetListType(
         SearchResultListView::SearchResultListType::kBestMatch);
     default_view_->SetActive(true);
 
     answer_card_view_ = std::make_unique<SearchResultListView>(
         &view_delegate_, nullptr,
-        SearchResultView::SearchResultViewType::kAnswerCard, true,
-        absl::nullopt);
+        SearchResultView::SearchResultViewType::kAnswerCard, absl::nullopt);
     answer_card_view_->SetListType(
         SearchResultListView::SearchResultListType::kAnswerCard);
     answer_card_view_->SetActive(true);
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 9f37399..0f0d2f0 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -3655,11 +3655,14 @@
       <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_SHOW_EMOJI_PICKER" desc="Label for accelerator action - Open Emoji Picker.">
         Open Emoji Picker
       </message>
+      <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_STOP_SCREEN_RECORDING" desc="Label for accelerator action - Stop screen recording.">
+        Stop screen recording
+      </message>
       <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_TOGGLE_IME_MENU_BUBBLE" desc="Label for accelerator action - Show list of available input methods.">
         Show list of available input methods
       </message>
       <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_SHOW_SHORTCUT_VIEWER" desc="Label for accelerator action - Open Keyboard shortcuts app.">
-        Open Keyboard shortcuts app
+        Open Key Shortcuts app
       </message>
       <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_SHOW_STYLUS_TOOLS" desc="Label for accelerator action - Show stylus tools.">
         Show stylus tools
@@ -5944,7 +5947,7 @@
 
       <!-- Shortcut Customization App -->
       <message name="IDS_ASH_SHORTCUT_CUSTOMIZATION_APP_TITLE" desc="The title of the keyboard shortcuts system web app. Keyboard shortcuts lets users to customize their system shortcuts.">
-        Keyboard shortcuts
+        Key Shortcuts
       </message>
 
       <message name="IDS_ASH_SHIMLESS_RMA_APP_TITLE" translateable="false" desc="The title of shimless RMA flow SWA. Shimless RMA guides repair technicians through step-by-step repair flow.">
diff --git a/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_SHOW_SHORTCUT_VIEWER.png.sha1 b/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_SHOW_SHORTCUT_VIEWER.png.sha1
index bdddc6e..d889a67 100644
--- a/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_SHOW_SHORTCUT_VIEWER.png.sha1
+++ b/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_SHOW_SHORTCUT_VIEWER.png.sha1
@@ -1 +1 @@
-fa30745e4e223cda202907829f455ed56acd0541
\ No newline at end of file
+e7302804630250cb3c0270cbb84796e6821523c3
\ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_STOP_SCREEN_RECORDING.png.sha1 b/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_STOP_SCREEN_RECORDING.png.sha1
new file mode 100644
index 0000000..b7c27306
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_STOP_SCREEN_RECORDING.png.sha1
@@ -0,0 +1 @@
+7e18d091617f1f5f080d966f8054b8913d273f42
\ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_SHORTCUT_CUSTOMIZATION_APP_TITLE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SHORTCUT_CUSTOMIZATION_APP_TITLE.png.sha1
index f3e6c2e..5b109eb8 100644
--- a/ash/ash_strings_grd/IDS_ASH_SHORTCUT_CUSTOMIZATION_APP_TITLE.png.sha1
+++ b/ash/ash_strings_grd/IDS_ASH_SHORTCUT_CUSTOMIZATION_APP_TITLE.png.sha1
@@ -1 +1 @@
-ea74002db10748bcfcbac5bdd4f134a30f2b677c
\ No newline at end of file
+4e96e549ab45c04fea3839b0bae59c9b6d60a0c9
\ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_camera_unittests.cc b/ash/capture_mode/capture_mode_camera_unittests.cc
index 6d4ecc2..88cd4bb 100644
--- a/ash/capture_mode/capture_mode_camera_unittests.cc
+++ b/ash/capture_mode/capture_mode_camera_unittests.cc
@@ -76,10 +76,6 @@
 
 namespace {
 
-constexpr char kDefaultCameraDeviceId[] = "/dev/videoX";
-constexpr char kDefaultCameraDisplayName[] = "Default Cam";
-constexpr char kDefaultCameraModelId[] = "0def:c000";
-
 // The app ID used for the capture mode camera and microphone recording privacy
 // indicators.
 constexpr char kCaptureModePrivacyIndicatorId[] = "system-capture-mode";
@@ -91,11 +87,6 @@
 constexpr int kMinRegionLengthForCameraToIntersectLabelButton =
     capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera + 20;
 
-TestCaptureModeDelegate* GetTestDelegate() {
-  return static_cast<TestCaptureModeDelegate*>(
-      CaptureModeController::Get()->delegate_for_testing());
-}
-
 CaptureModeCameraController* GetCameraController() {
   return CaptureModeController::Get()->camera_controller();
 }
@@ -124,45 +115,6 @@
   return sibling_index > 0 && children[sibling_index - 1] == window;
 }
 
-// Defines a waiter for the camera devices change notifications.
-class CameraDevicesChangeWaiter : public CaptureModeCameraController::Observer {
- public:
-  CameraDevicesChangeWaiter() { GetCameraController()->AddObserver(this); }
-  CameraDevicesChangeWaiter(const CameraDevicesChangeWaiter&) = delete;
-  CameraDevicesChangeWaiter& operator=(const CameraDevicesChangeWaiter&) =
-      delete;
-  ~CameraDevicesChangeWaiter() override {
-    GetCameraController()->RemoveObserver(this);
-  }
-
-  int camera_change_event_count() const { return camera_change_event_count_; }
-  int selected_camera_change_event_count() const {
-    return selected_camera_change_event_count_;
-  }
-
-  void Wait() { loop_.Run(); }
-
-  // CaptureModeCameraController::Observer:
-  void OnAvailableCamerasChanged(const CameraInfoList& cameras) override {
-    ++camera_change_event_count_;
-    loop_.Quit();
-  }
-
-  void OnSelectedCameraChanged(const CameraId& camera_id) override {
-    ++selected_camera_change_event_count_;
-  }
-
- private:
-  base::RunLoop loop_;
-
-  // Tracks the number of times the observer call `OnAvailableCamerasChanged()`
-  // was triggered.
-  int camera_change_event_count_ = 0;
-
-  // Tracks the number of times `OnSelectedCameraChanged()` was triggered.
-  int selected_camera_change_event_count_ = 0;
-};
-
 gfx::Rect GetTooSmallToFitCameraRegion() {
   return {100, 100,
           capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera - 1,
@@ -211,30 +163,6 @@
     EXPECT_TRUE(controller->is_recording_in_progress());
   }
 
-  void AddFakeCamera(const std::string& device_id,
-                     const std::string& display_name,
-                     const std::string& model_id,
-                     media::VideoFacingMode camera_facing_mode =
-                         media::MEDIA_VIDEO_FACING_NONE) {
-    CameraDevicesChangeWaiter waiter;
-    GetTestDelegate()->video_source_provider()->AddFakeCamera(
-        device_id, display_name, model_id, camera_facing_mode);
-    waiter.Wait();
-  }
-
-  void RemoveFakeCamera(const std::string& device_id) {
-    CameraDevicesChangeWaiter waiter;
-    GetTestDelegate()->video_source_provider()->RemoveFakeCamera(device_id);
-    waiter.Wait();
-  }
-
-  void AddDefaultCamera() {
-    AddFakeCamera(kDefaultCameraDeviceId, kDefaultCameraDisplayName,
-                  kDefaultCameraModelId);
-  }
-
-  void RemoveDefaultCamera() { RemoveFakeCamera(kDefaultCameraDeviceId); }
-
   // Adds the default camera, sets it as the selected camera, then removes it,
   // which triggers the camera disconnection grace period. Returns a pointer to
   // the `CaptureModeCameraController`.
diff --git a/ash/capture_mode/capture_mode_game_dashboard_unittests.cc b/ash/capture_mode/capture_mode_game_dashboard_unittests.cc
index 99f256b..4fa53f9 100644
--- a/ash/capture_mode/capture_mode_game_dashboard_unittests.cc
+++ b/ash/capture_mode/capture_mode_game_dashboard_unittests.cc
@@ -211,4 +211,26 @@
   EXPECT_FALSE(GetPreviewNotification());
 }
 
+// Tests that the camera preview widget shows up when starting the game
+// dashboard initiated capture mode session for the first time.
+TEST_F(GameDashboardCaptureModeTest, CameraPreviewWidgetTest) {
+  AddDefaultCamera();
+  auto* camera_controller = CaptureModeController::Get()->camera_controller();
+  EXPECT_FALSE(camera_controller->selected_camera().is_valid());
+
+  auto* controller = StartGameCaptureModeSession();
+  EXPECT_TRUE(camera_controller->selected_camera().is_valid());
+  EXPECT_TRUE(camera_controller->should_show_preview());
+  GetEventGenerator()->MoveMouseToCenterOf(game_window());
+  EXPECT_TRUE(camera_controller->camera_preview_widget());
+
+  controller->StartVideoRecordingImmediatelyForTesting();
+  EXPECT_TRUE(camera_controller->should_show_preview());
+  EXPECT_TRUE(camera_controller->camera_preview_widget());
+
+  controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
+  EXPECT_FALSE(camera_controller->should_show_preview());
+  EXPECT_FALSE(camera_controller->camera_preview_widget());
+}
+
 }  // namespace ash
diff --git a/ash/capture_mode/capture_mode_metrics.h b/ash/capture_mode/capture_mode_metrics.h
index 600e971..5237d1a 100644
--- a/ash/capture_mode/capture_mode_metrics.h
+++ b/ash/capture_mode/capture_mode_metrics.h
@@ -39,7 +39,8 @@
   kProjectorTranscriptionError,
   kLowDriveFsQuota,
   kVideoEncoderReconfigurationFailure,
-  kMaxValue = kVideoEncoderReconfigurationFailure,
+  kKeyboardShortcut,
+  kMaxValue = kKeyboardShortcut,
 };
 
 // Enumeration of capture bar buttons that can be pressed while in capture mode.
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc
index 505c97b1..22ce4406 100644
--- a/ash/capture_mode/capture_mode_session.cc
+++ b/ash/capture_mode/capture_mode_session.cc
@@ -527,15 +527,16 @@
 
   UpdateFloatingPanelBoundsIfNeeded();
 
-  // call `OnCaptureTypeChanged` after capture bar's initialization is done
-  // instead of in the initialization of the capture mode type view, since
-  // `OnCaptureTypeChanged` may trigger `ShowCaptureToast` which depends on the
-  // capture bar.
-  // Also please note we should call `OnCaptureTypeChanged` in
+  // `OnCaptureTypeChanged()` should be called after the initialization of the
+  // capture bar rather than in that of the capture mode type view, since
+  // `OnCaptureTypeChanged()` may trigger `ShowCaptureToast()` which has
+  // dependencies on the capture bar.
+  // Also please note we should call `OnCaptureTypeChanged()` in
   // `CaptureModeBarView` instead of `CaptureModeSession`, since this is during
   // the initialization of the capture session, the type change is not triggered
   // by the user.
   capture_mode_bar_view_->OnCaptureTypeChanged(controller_->type());
+  MaybeUpdateSelfieCamInSessionVisibility();
   MaybeCreateUserNudge();
 
   if (active_behavior_->ShouldAutoSelectFirstCamera()) {
@@ -700,6 +701,7 @@
 
 void CaptureModeSession::OnCaptureTypeChanged(CaptureModeType new_type) {
   capture_mode_bar_view_->OnCaptureTypeChanged(new_type);
+  MaybeUpdateSelfieCamInSessionVisibility();
   UpdateCaptureLabelWidget(CaptureLabelAnimation::kNone);
   UpdateCursor(display::Screen::GetScreen()->GetCursorScreenPoint(),
                /*is_touch=*/false);
@@ -1609,6 +1611,22 @@
   capture_toast_controller_.MaybeRepositionCaptureToast();
 }
 
+void CaptureModeSession::MaybeUpdateSelfieCamInSessionVisibility() {
+  auto* camera_controller = controller_->camera_controller();
+  CHECK(camera_controller);
+
+  // Set the value to true for `SetShouldShowPreview` when the capture type is
+  // `kVideo` with no video recording in progress.
+  // Don't trigger `SetShouldShowPreview` if there's a video recording in
+  // progress, since the capture type is restricted to `kImage` at this use case
+  // and we don't want to affect the camera preview for the in_progress video
+  // recording.
+  if (!controller_->is_recording_in_progress()) {
+    camera_controller->SetShouldShowPreview(controller_->type() ==
+                                            CaptureModeType::kVideo);
+  }
+}
+
 void CaptureModeSession::MaybeCreateUserNudge() {
   user_nudge_controller_.reset();
 
diff --git a/ash/capture_mode/capture_mode_session.h b/ash/capture_mode/capture_mode_session.h
index 591c41e..71f210d 100644
--- a/ash/capture_mode/capture_mode_session.h
+++ b/ash/capture_mode/capture_mode_session.h
@@ -301,6 +301,10 @@
   // `current_root_` is different`.
   void RefreshBarWidgetBounds();
 
+  // Triggers a selfie camera visibility update during capture mode session on
+  // capture mode type changed.
+  void MaybeUpdateSelfieCamInSessionVisibility();
+
   // If possible, this recreates and shows the nudge that alerts the user about
   // the new folder selection settings. The nudge will be created on top of the
   // the settings button on the capture mode bar.
diff --git a/ash/capture_mode/capture_mode_session_focus_cycler.cc b/ash/capture_mode/capture_mode_session_focus_cycler.cc
index 0c6f9b9da..2ffa904 100644
--- a/ash/capture_mode/capture_mode_session_focus_cycler.cc
+++ b/ash/capture_mode/capture_mode_session_focus_cycler.cc
@@ -757,11 +757,14 @@
 bool CaptureModeSessionFocusCycler::IsGroupAvailable(FocusGroup group) const {
   switch (group) {
     case FocusGroup::kNone:
-    case FocusGroup::kTypeSource:
     case FocusGroup::kSettingsClose:
     case FocusGroup::kPendingSettings:
     case FocusGroup::kPendingRecordingType:
       return true;
+    case FocusGroup::kTypeSource: {
+      CaptureModeBarView* bar_view = session_->capture_mode_bar_view_;
+      return bar_view->GetCaptureTypeView() && bar_view->GetCaptureSourceView();
+    }
     case FocusGroup::kSelection:
     case FocusGroup::kCaptureButton: {
       // The selection UI and capture button are focusable only when it is
@@ -806,9 +809,7 @@
       CaptureModeBarView* bar_view = session_->capture_mode_bar_view_;
       CaptureModeTypeView* type_view = bar_view->GetCaptureTypeView();
       CaptureModeSourceView* source_view = bar_view->GetCaptureSourceView();
-      if (!type_view || !source_view) {
-        break;
-      }
+      CHECK(type_view && source_view);
       for (auto* button :
            {type_view->image_toggle_button(), type_view->video_toggle_button(),
             source_view->fullscreen_toggle_button(),
diff --git a/ash/capture_mode/capture_mode_test_util.cc b/ash/capture_mode/capture_mode_test_util.cc
index 62be723..05e5de9 100644
--- a/ash/capture_mode/capture_mode_test_util.cc
+++ b/ash/capture_mode/capture_mode_test_util.cc
@@ -13,6 +13,7 @@
 #include "ash/capture_mode/capture_mode_session_test_api.h"
 #include "ash/capture_mode/capture_mode_source_view.h"
 #include "ash/capture_mode/capture_mode_type_view.h"
+#include "ash/capture_mode/fake_video_source_provider.h"
 #include "ash/capture_mode/test_capture_mode_delegate.h"
 #include "ash/public/cpp/capture_mode/capture_mode_test_api.h"
 #include "ash/public/cpp/projector/projector_controller.h"
@@ -47,6 +48,7 @@
 namespace {
 
 constexpr char kScreenCaptureNotificationId[] = "capture_mode_notification";
+constexpr char kDefaultCameraDisplayName[] = "Default Cam";
 
 // Dispatch the simulated virtual key event to the WindowEventDispatcher.
 void DispatchVKEvent(ui::test::EventGenerator* event_generator,
@@ -77,6 +79,11 @@
   return controller;
 }
 
+TestCaptureModeDelegate* GetTestDelegate() {
+  return static_cast<TestCaptureModeDelegate*>(
+      CaptureModeController::Get()->delegate_for_testing());
+}
+
 void ClickOnView(const views::View* view,
                  ui::test::EventGenerator* event_generator) {
   DCHECK(view);
@@ -356,6 +363,31 @@
   notification->delegate()->Click(button_index, absl::nullopt);
 }
 
+void AddFakeCamera(const std::string& device_id,
+                   const std::string& display_name,
+                   const std::string& model_id,
+                   media::VideoFacingMode camera_facing_mode) {
+  CameraDevicesChangeWaiter waiter;
+  GetTestDelegate()->video_source_provider()->AddFakeCamera(
+      device_id, display_name, model_id, camera_facing_mode);
+  waiter.Wait();
+}
+
+void RemoveFakeCamera(const std::string& device_id) {
+  CameraDevicesChangeWaiter waiter;
+  GetTestDelegate()->video_source_provider()->RemoveFakeCamera(device_id);
+  waiter.Wait();
+}
+
+void AddDefaultCamera() {
+  AddFakeCamera(kDefaultCameraDeviceId, kDefaultCameraDisplayName,
+                kDefaultCameraModelId);
+}
+
+void RemoveDefaultCamera() {
+  RemoveFakeCamera(kDefaultCameraDeviceId);
+}
+
 // -----------------------------------------------------------------------------
 // ProjectorCaptureModeIntegrationHelper:
 
@@ -445,4 +477,30 @@
   }
 }
 
+// -----------------------------------------------------------------------------
+// CameraDevicesChangeWaiter:
+
+CameraDevicesChangeWaiter::CameraDevicesChangeWaiter() {
+  CaptureModeController::Get()->camera_controller()->AddObserver(this);
+}
+
+CameraDevicesChangeWaiter::~CameraDevicesChangeWaiter() {
+  CaptureModeController::Get()->camera_controller()->RemoveObserver(this);
+}
+
+void CameraDevicesChangeWaiter::Wait() {
+  loop_.Run();
+}
+
+void CameraDevicesChangeWaiter::OnAvailableCamerasChanged(
+    const CameraInfoList& cameras) {
+  ++camera_change_event_count_;
+  loop_.Quit();
+}
+
+void CameraDevicesChangeWaiter::OnSelectedCameraChanged(
+    const CameraId& camera_id) {
+  ++selected_camera_change_event_count_;
+}
+
 }  // namespace ash
diff --git a/ash/capture_mode/capture_mode_test_util.h b/ash/capture_mode/capture_mode_test_util.h
index 6554d40e..8808549 100644
--- a/ash/capture_mode/capture_mode_test_util.h
+++ b/ash/capture_mode/capture_mode_test_util.h
@@ -7,7 +7,10 @@
 
 #include <string>
 
+#include "ash/capture_mode/capture_mode_camera_controller.h"
+#include "ash/capture_mode/capture_mode_controller.h"
 #include "ash/capture_mode/capture_mode_types.h"
+#include "ash/capture_mode/test_capture_mode_delegate.h"
 #include "ash/capture_mode/user_nudge_controller.h"
 #include "ash/public/cpp/test/mock_projector_client.h"
 #include "base/memory/raw_ptr.h"
@@ -48,10 +51,17 @@
 class CaptureModeController;
 class CaptureModeBarView;
 
+// Fake camera info used for testing.
+constexpr char kDefaultCameraDeviceId[] = "/dev/videoX";
+constexpr char kDefaultCameraModelId[] = "0def:c000";
+
 // Starts the capture mode session with given `source` and `type`.
 CaptureModeController* StartCaptureSession(CaptureModeSource source,
                                            CaptureModeType type);
 
+// Returns the test delegate of `CaptureModeController`.
+TestCaptureModeDelegate* GetTestDelegate();
+
 void ClickOnView(const views::View* view,
                  ui::test::EventGenerator* event_generator);
 
@@ -152,6 +162,16 @@
 // Clicks on the area in the notification specified by the `button_index`.
 void ClickOnNotification(absl::optional<int> button_index);
 
+// Test util APIs to simulate the camera adding and removing operations.
+void AddFakeCamera(
+    const std::string& device_id,
+    const std::string& display_name,
+    const std::string& model_id,
+    media::VideoFacingMode camera_facing_mode = media::MEDIA_VIDEO_FACING_NONE);
+void RemoveFakeCamera(const std::string& device_id);
+void AddDefaultCamera();
+void RemoveDefaultCamera();
+
 // Defines a helper class to allow setting up and testing the Projector feature
 // in multiple test fixtures. Note that this helper initializes the Projector-
 // related features in its constructor, so test fixtures that use this should
@@ -218,6 +238,37 @@
   base::RunLoop run_loop_;
 };
 
+// Defines a waiter for the camera devices change notifications.
+class CameraDevicesChangeWaiter : public CaptureModeCameraController::Observer {
+ public:
+  CameraDevicesChangeWaiter();
+  CameraDevicesChangeWaiter(const CameraDevicesChangeWaiter&) = delete;
+  CameraDevicesChangeWaiter& operator=(const CameraDevicesChangeWaiter&) =
+      delete;
+  ~CameraDevicesChangeWaiter() override;
+
+  int camera_change_event_count() const { return camera_change_event_count_; }
+  int selected_camera_change_event_count() const {
+    return selected_camera_change_event_count_;
+  }
+
+  void Wait();
+
+  // CaptureModeCameraController::Observer:
+  void OnAvailableCamerasChanged(const CameraInfoList& cameras) override;
+  void OnSelectedCameraChanged(const CameraId& camera_id) override;
+
+ private:
+  base::RunLoop loop_;
+
+  // Tracks the number of times the observer call `OnAvailableCamerasChanged()`
+  // was triggered.
+  int camera_change_event_count_ = 0;
+
+  // Tracks the number of times `OnSelectedCameraChanged()` was triggered.
+  int selected_camera_change_event_count_ = 0;
+};
+
 }  // namespace ash
 
 #endif  // ASH_CAPTURE_MODE_CAPTURE_MODE_TEST_UTIL_H_
diff --git a/ash/capture_mode/capture_mode_type_view.cc b/ash/capture_mode/capture_mode_type_view.cc
index 2f4a3c8..2e79fad 100644
--- a/ash/capture_mode/capture_mode_type_view.cc
+++ b/ash/capture_mode/capture_mode_type_view.cc
@@ -73,18 +73,6 @@
 
   if (image_toggle_button_)
     image_toggle_button_->SetToggled(!is_video);
-
-  auto* camera_controller = controller->camera_controller();
-  DCHECK(camera_controller);
-  // Set the value to true for `SetShouldShowPreview` when the capture mode
-  // session is started and switched to a video recording mode before recording
-  // starts. False when it is switched to image capture mode.
-  // Don't trigger `SetShouldShowPreview` if there's a video recording in
-  // progress, since the capture type is restricted to `kImage` at this use case
-  // and we don't want to affect the camera preview for the in_progress video
-  // recording.
-  if (!controller->is_recording_in_progress())
-    camera_controller->SetShouldShowPreview(is_video);
 }
 
 void CaptureModeTypeView::OnImageToggle() {
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc
index 6e05e8d..8e60271 100644
--- a/ash/capture_mode/capture_mode_unittests.cc
+++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -4660,6 +4660,37 @@
   expected_behavior();
 }
 
+// Tests that the capture mode session can be started with the keyboard shortcut
+// 'Ctrl + Shift + Overview' with `kImage` as the default type and `kRegion` as
+// the default source. And the screen recording can be ended with the keyboard
+// shortcut 'Search + Shift + X'.
+TEST_F(CaptureModeTest, KeyboardShortcutTest) {
+  base::HistogramTester histogram_tester;
+  histogram_tester.ExpectBucketCount(
+      kEndRecordingReasonInClamshellHistogramName,
+      EndRecordingReason::kKeyboardShortcut, 0);
+
+  auto* event_generator = GetEventGenerator();
+  event_generator->PressAndReleaseKey(ui::VKEY_MEDIA_LAUNCH_APP1,
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
+  auto* controller = CaptureModeController::Get();
+  EXPECT_TRUE(controller->IsActive());
+  EXPECT_EQ(controller->type(), CaptureModeType::kImage);
+  EXPECT_EQ(controller->source(), CaptureModeSource::kRegion);
+  controller->SetType(CaptureModeType::kVideo);
+  controller->SetSource(CaptureModeSource::kFullscreen);
+
+  StartVideoRecordingImmediately();
+  EXPECT_TRUE(controller->is_recording_in_progress());
+
+  event_generator->PressAndReleaseKey(ui::VKEY_X,
+                                      ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN);
+  EXPECT_FALSE(controller->is_recording_in_progress());
+  histogram_tester.ExpectBucketCount(
+      kEndRecordingReasonInClamshellHistogramName,
+      EndRecordingReason::kKeyboardShortcut, 1);
+}
+
 namespace {
 
 // -----------------------------------------------------------------------------
diff --git a/ash/components/arc/BUILD.gn b/ash/components/arc/BUILD.gn
index ed6c816..dff8801 100644
--- a/ash/components/arc/BUILD.gn
+++ b/ash/components/arc/BUILD.gn
@@ -16,6 +16,8 @@
     "bluetooth/bluetooth_type_converters.h",
     "camera/arc_camera_bridge.cc",
     "camera/arc_camera_bridge.h",
+    "chrome_feature_flags/arc_chrome_feature_flags_bridge.cc",
+    "chrome_feature_flags/arc_chrome_feature_flags_bridge.h",
     "clipboard/arc_clipboard_bridge.cc",
     "clipboard/arc_clipboard_bridge.h",
     "compat_mode/arc_resize_lock_manager.cc",
@@ -317,6 +319,8 @@
     "test/fake_backup_settings_instance.h",
     "test/fake_bluetooth_instance.cc",
     "test/fake_bluetooth_instance.h",
+    "test/fake_chrome_feature_flags_instance.cc",
+    "test/fake_chrome_feature_flags_instance.h",
     "test/fake_clipboard_instance.cc",
     "test/fake_clipboard_instance.h",
     "test/fake_compatibility_mode_instance.cc",
@@ -403,6 +407,7 @@
     "bluetooth/bluetooth_mojom_traits_unittest.cc",
     "bluetooth/bluetooth_type_converters_unittest.cc",
     "camera/arc_camera_bridge_unittest.cc",
+    "chrome_feature_flags/arc_chrome_feature_flags_bridge_unittest.cc",
     "clipboard/arc_clipboard_bridge_unittest.cc",
     "compat_mode/arc_resize_lock_manager_unittest.cc",
     "compat_mode/arc_splash_screen_dialog_view_unittest.cc",
diff --git a/ash/components/arc/arc_features.cc b/ash/components/arc/arc_features.cc
index 769ef47..e5d7741 100644
--- a/ash/components/arc/arc_features.cc
+++ b/ash/components/arc/arc_features.cc
@@ -84,7 +84,7 @@
 // Only applies on Android T+.
 BASE_FEATURE(kEnableReadOnlyPermissions,
              "ArcEnableReadOnlyPermissions",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Controls whether we should delegate audio focus requests from ARC to Chrome.
 BASE_FEATURE(kEnableUnifiedAudioFocusFeature,
diff --git a/ash/components/arc/chrome_feature_flags/OWNERS b/ash/components/arc/chrome_feature_flags/OWNERS
new file mode 100644
index 0000000..f1f254e
--- /dev/null
+++ b/ash/components/arc/chrome_feature_flags/OWNERS
@@ -0,0 +1 @@
+toshikikikuchi@chromium.org
diff --git a/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.cc b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.cc
new file mode 100644
index 0000000..186ad85
--- /dev/null
+++ b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.cc
@@ -0,0 +1,83 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.h"
+
+#include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h"
+#include "ash/components/arc/session/arc_bridge_service.h"
+#include "ash/components/arc/session/arc_service_manager.h"
+#include "ash/constants/ash_features.h"
+#include "base/memory/singleton.h"
+
+namespace arc {
+
+namespace {
+
+// Singleton factory for ArcChromeFeatureFlagsBridge.
+class ArcChromeFeatureFlagsBridgeFactory
+    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
+          ArcChromeFeatureFlagsBridge,
+          ArcChromeFeatureFlagsBridgeFactory> {
+ public:
+  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
+  static constexpr const char* kName = "ArcChromeFeatureFlagsBridgeFactory";
+
+  static ArcChromeFeatureFlagsBridgeFactory* GetInstance() {
+    return base::Singleton<ArcChromeFeatureFlagsBridgeFactory>::get();
+  }
+
+ private:
+  friend base::DefaultSingletonTraits<ArcChromeFeatureFlagsBridgeFactory>;
+  ArcChromeFeatureFlagsBridgeFactory() = default;
+  ~ArcChromeFeatureFlagsBridgeFactory() override = default;
+};
+
+}  // namespace
+
+// static
+ArcChromeFeatureFlagsBridge* ArcChromeFeatureFlagsBridge::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return ArcChromeFeatureFlagsBridgeFactory::GetForBrowserContext(context);
+}
+
+// static
+ArcChromeFeatureFlagsBridge*
+ArcChromeFeatureFlagsBridge::GetForBrowserContextForTesting(
+    content::BrowserContext* context) {
+  return ArcChromeFeatureFlagsBridgeFactory::GetForBrowserContextForTesting(
+      context);
+}
+
+ArcChromeFeatureFlagsBridge::ArcChromeFeatureFlagsBridge(
+    content::BrowserContext* context,
+    ArcBridgeService* bridge_service)
+    : arc_bridge_service_(bridge_service) {
+  arc_bridge_service_->chrome_feature_flags()->AddObserver(this);
+}
+
+ArcChromeFeatureFlagsBridge::~ArcChromeFeatureFlagsBridge() {
+  arc_bridge_service_->chrome_feature_flags()->RemoveObserver(this);
+}
+
+void ArcChromeFeatureFlagsBridge::OnConnectionReady() {
+  NotifyQsRevamp();
+}
+
+void ArcChromeFeatureFlagsBridge::NotifyQsRevamp() {
+  mojom::ChromeFeatureFlagsInstance* chrome_feature_flags_instance =
+      ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->chrome_feature_flags(),
+                                  NotifyQsRevamp);
+  if (!chrome_feature_flags_instance) {
+    return;
+  }
+  chrome_feature_flags_instance->NotifyQsRevamp(
+      ash::features::IsQsRevampEnabled());
+}
+
+// static
+void ArcChromeFeatureFlagsBridge::EnsureFactoryBuilt() {
+  ArcChromeFeatureFlagsBridgeFactory::GetInstance();
+}
+
+}  // namespace arc
diff --git a/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.h b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.h
new file mode 100644
index 0000000..467a1da7
--- /dev/null
+++ b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.h
@@ -0,0 +1,59 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_COMPONENTS_ARC_CHROME_FEATURE_FLAGS_ARC_CHROME_FEATURE_FLAGS_BRIDGE_H_
+#define ASH_COMPONENTS_ARC_CHROME_FEATURE_FLAGS_ARC_CHROME_FEATURE_FLAGS_BRIDGE_H_
+
+#include "ash/components/arc/mojom/chrome_feature_flags.mojom.h"
+#include "ash/components/arc/session/connection_observer.h"
+#include "base/memory/raw_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+namespace arc {
+
+class ArcBridgeService;
+
+// This class notifies the Chrome feature flag states to the ARC.
+class ArcChromeFeatureFlagsBridge
+    : public KeyedService,
+      public ConnectionObserver<mojom::ChromeFeatureFlagsInstance> {
+ public:
+  // Returns singleton instance for the given BrowserContext,
+  // or nullptr if the browser |context| is not allowed to use ARC.
+  static ArcChromeFeatureFlagsBridge* GetForBrowserContext(
+      content::BrowserContext* context);
+  static ArcChromeFeatureFlagsBridge* GetForBrowserContextForTesting(
+      content::BrowserContext* context);
+
+  ArcChromeFeatureFlagsBridge(content::BrowserContext* context,
+                              ArcBridgeService* bridge_service);
+
+  ArcChromeFeatureFlagsBridge(const ArcChromeFeatureFlagsBridge&) = delete;
+  ArcChromeFeatureFlagsBridge& operator=(const ArcChromeFeatureFlagsBridge&) =
+      delete;
+
+  ~ArcChromeFeatureFlagsBridge() override;
+
+  // ConnectionObserver<mojom::ChromeFeatureFlagsInstance> overrides:
+  void OnConnectionReady() override;
+
+  static void EnsureFactoryBuilt();
+
+ private:
+  THREAD_CHECKER(thread_checker_);
+
+  void NotifyQsRevamp();
+
+  const raw_ptr<ArcBridgeService, ExperimentalAsh>
+      arc_bridge_service_;  // Owned by ArcServiceManager.
+};
+
+}  // namespace arc
+
+#endif  // ASH_COMPONENTS_ARC_CHROME_FEATURE_FLAGS_ARC_CHROME_FEATURE_FLAGS_BRIDGE_H_
diff --git a/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge_unittest.cc b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge_unittest.cc
new file mode 100644
index 0000000..7949221c
--- /dev/null
+++ b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge_unittest.cc
@@ -0,0 +1,79 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.h"
+
+#include "ash/components/arc/session/arc_bridge_service.h"
+#include "ash/components/arc/session/arc_service_manager.h"
+#include "ash/components/arc/test/fake_chrome_feature_flags_instance.h"
+#include "ash/components/arc/test/test_browser_context.h"
+#include "ash/constants/ash_features.h"
+#include "base/memory/raw_ptr.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+namespace {
+
+class ArcChromeFeatureFlagsBridgeTest : public testing::Test {
+ protected:
+  ArcChromeFeatureFlagsBridgeTest()
+      : bridge_(ArcChromeFeatureFlagsBridge::GetForBrowserContextForTesting(
+            &context_)) {}
+  ArcChromeFeatureFlagsBridgeTest(const ArcChromeFeatureFlagsBridgeTest&) =
+      delete;
+  ArcChromeFeatureFlagsBridgeTest& operator=(
+      const ArcChromeFeatureFlagsBridgeTest&) = delete;
+  ~ArcChromeFeatureFlagsBridgeTest() override = default;
+
+  void TearDown() override {
+    ArcServiceManager::Get()
+        ->arc_bridge_service()
+        ->chrome_feature_flags()
+        ->CloseInstance(&instance_);
+    bridge_->Shutdown();
+  }
+
+  void Connect() {
+    ArcServiceManager::Get()
+        ->arc_bridge_service()
+        ->chrome_feature_flags()
+        ->SetInstance(&instance_);
+  }
+
+  ArcChromeFeatureFlagsBridge* bridge() { return bridge_; }
+  FakeChromeFeatureFlagsInstance* instance() { return &instance_; }
+  base::test::ScopedFeatureList* scoped_feature_list() {
+    return &scoped_feature_list_;
+  }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_;
+  ArcServiceManager arc_service_manager_;
+  TestBrowserContext context_;
+  FakeChromeFeatureFlagsInstance instance_;
+  base::test::ScopedFeatureList scoped_feature_list_;
+  const raw_ptr<ArcChromeFeatureFlagsBridge, ExperimentalAsh> bridge_;
+};
+
+TEST_F(ArcChromeFeatureFlagsBridgeTest, ConstructDestruct) {
+  Connect();
+  EXPECT_NE(nullptr, bridge());
+}
+
+TEST_F(ArcChromeFeatureFlagsBridgeTest, NotifyQsRevamp_Enabled) {
+  scoped_feature_list()->InitAndEnableFeature(ash::features::kQsRevamp);
+  Connect();
+  EXPECT_TRUE(instance()->qs_revamp_called_value().value());
+}
+
+TEST_F(ArcChromeFeatureFlagsBridgeTest, NotifyQsRevamp_Disabled) {
+  scoped_feature_list()->InitAndDisableFeature(ash::features::kQsRevamp);
+  Connect();
+  EXPECT_FALSE(instance()->qs_revamp_called_value().value());
+}
+
+}  // namespace
+}  // namespace arc
diff --git a/ash/components/arc/mojom/BUILD.gn b/ash/components/arc/mojom/BUILD.gn
index 79b5f7fc..88a44176 100644
--- a/ash/components/arc/mojom/BUILD.gn
+++ b/ash/components/arc/mojom/BUILD.gn
@@ -22,6 +22,7 @@
     "bluetooth.mojom",
     "boot_phase_monitor.mojom",
     "camera.mojom",
+    "chrome_feature_flags.mojom",
     "clipboard.mojom",
     "compatibility_mode.mojom",
     "crash_collector.mojom",
diff --git a/ash/components/arc/mojom/arc_bridge.mojom b/ash/components/arc/mojom/arc_bridge.mojom
index 095867e..7cdb757 100644
--- a/ash/components/arc/mojom/arc_bridge.mojom
+++ b/ash/components/arc/mojom/arc_bridge.mojom
@@ -15,6 +15,7 @@
 import "ash/components/arc/mojom/bluetooth.mojom";
 import "ash/components/arc/mojom/boot_phase_monitor.mojom";
 import "ash/components/arc/mojom/camera.mojom";
+import "ash/components/arc/mojom/chrome_feature_flags.mojom";
 import "ash/components/arc/mojom/clipboard.mojom";
 import "ash/components/arc/mojom/compatibility_mode.mojom";
 import "ash/components/arc/mojom/crash_collector.mojom";
@@ -64,9 +65,9 @@
 import "ash/components/arc/mojom/wallpaper.mojom";
 import "ash/components/arc/mojom/webapk.mojom";
 
-// Next MinVersion: 65
+// Next MinVersion: 66
 // Deprecated method IDs: 101, 105, 121, 132, 136, 153, 154, 160
-// Next method ID: 170
+// Next method ID: 171
 interface ArcBridgeHost {
   // Keep the entries alphabetical. In order to do so without breaking
   // compatibility with the ARC instance, explicitly assign each interface a
@@ -115,6 +116,10 @@
   [MinVersion=46] OnCameraInstanceReady@151(
       pending_remote<CameraInstance> instance_remote);
 
+  // Notifies Chrome that the ChromeFeatureFlagsInstance interface is ready.
+  [MinVersion=65] OnChromeFeatureFlagsInstanceReady@170(
+      pending_remote<ChromeFeatureFlagsInstance> instance_remote);
+
   // Notifies Chrome that the ClipboardInstance interface is ready.
   [MinVersion=2] OnClipboardInstanceReady@109(
       pending_remote<ClipboardInstance> instance_remote);
diff --git a/ash/components/arc/mojom/chrome_feature_flags.mojom b/ash/components/arc/mojom/chrome_feature_flags.mojom
new file mode 100644
index 0000000..2d8c886
--- /dev/null
+++ b/ash/components/arc/mojom/chrome_feature_flags.mojom
@@ -0,0 +1,16 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Next MinVersion: 1
+
+module arc.mojom;
+
+// This interface provides methods to propagate the feature flag status to
+// ARC++.
+//
+// Next method ID: 1
+interface ChromeFeatureFlagsInstance {
+  // Notifies ARC whether chrome://flags#QsRevamp is enabled.
+  NotifyQsRevamp@0(bool enabled);
+};
\ No newline at end of file
diff --git a/ash/components/arc/session/arc_bridge_host_impl.cc b/ash/components/arc/session/arc_bridge_host_impl.cc
index e44f643..44ba462 100644
--- a/ash/components/arc/session/arc_bridge_host_impl.cc
+++ b/ash/components/arc/session/arc_bridge_host_impl.cc
@@ -17,6 +17,7 @@
 #include "ash/components/arc/mojom/bluetooth.mojom.h"
 #include "ash/components/arc/mojom/boot_phase_monitor.mojom.h"
 #include "ash/components/arc/mojom/camera.mojom.h"
+#include "ash/components/arc/mojom/chrome_feature_flags.mojom.h"
 #include "ash/components/arc/mojom/clipboard.mojom.h"
 #include "ash/components/arc/mojom/compatibility_mode.mojom.h"
 #include "ash/components/arc/mojom/crash_collector.mojom.h"
@@ -153,6 +154,13 @@
   OnInstanceReady(arc_bridge_service_->camera(), std::move(camera_remote));
 }
 
+void ArcBridgeHostImpl::OnChromeFeatureFlagsInstanceReady(
+    mojo::PendingRemote<mojom::ChromeFeatureFlagsInstance>
+        chrome_feature_flags_remote) {
+  OnInstanceReady(arc_bridge_service_->chrome_feature_flags(),
+                  std::move(chrome_feature_flags_remote));
+}
+
 void ArcBridgeHostImpl::OnClipboardInstanceReady(
     mojo::PendingRemote<mojom::ClipboardInstance> clipboard_remote) {
   OnInstanceReady(arc_bridge_service_->clipboard(),
diff --git a/ash/components/arc/session/arc_bridge_host_impl.h b/ash/components/arc/session/arc_bridge_host_impl.h
index 47bd514b..1773800 100644
--- a/ash/components/arc/session/arc_bridge_host_impl.h
+++ b/ash/components/arc/session/arc_bridge_host_impl.h
@@ -70,6 +70,9 @@
           boot_phase_monitor_remote) override;
   void OnCameraInstanceReady(
       mojo::PendingRemote<mojom::CameraInstance> camera_remote) override;
+  void OnChromeFeatureFlagsInstanceReady(
+      mojo::PendingRemote<mojom::ChromeFeatureFlagsInstance>
+          chrome_feature_flags_remote) override;
   void OnClipboardInstanceReady(
       mojo::PendingRemote<mojom::ClipboardInstance> clipboard_remote) override;
   void OnCompatibilityModeInstanceReady(
diff --git a/ash/components/arc/session/arc_bridge_service.h b/ash/components/arc/session/arc_bridge_service.h
index 77b2ab3..9e7028e 100644
--- a/ash/components/arc/session/arc_bridge_service.h
+++ b/ash/components/arc/session/arc_bridge_service.h
@@ -34,6 +34,7 @@
 class BootPhaseMonitorInstance;
 class CameraHost;
 class CameraInstance;
+class ChromeFeatureFlagsInstance;
 class CastReceiverInstance;
 class ClipboardHost;
 class ClipboardInstance;
@@ -194,6 +195,9 @@
   ConnectionHolder<mojom::CastReceiverInstance>* cast_receiver() {
     return &cast_receiver_;
   }
+  ConnectionHolder<mojom::ChromeFeatureFlagsInstance>* chrome_feature_flags() {
+    return &chrome_feature_flags_;
+  }
   ConnectionHolder<mojom::ClipboardInstance, mojom::ClipboardHost>*
   clipboard() {
     return &clipboard_;
@@ -361,6 +365,7 @@
       boot_phase_monitor_;
   ConnectionHolder<mojom::CameraInstance, mojom::CameraHost> camera_;
   ConnectionHolder<mojom::CastReceiverInstance> cast_receiver_;
+  ConnectionHolder<mojom::ChromeFeatureFlagsInstance> chrome_feature_flags_;
   ConnectionHolder<mojom::ClipboardInstance, mojom::ClipboardHost> clipboard_;
   ConnectionHolder<mojom::CompatibilityModeInstance> compatibility_mode_;
   ConnectionHolder<mojom::CrashCollectorInstance, mojom::CrashCollectorHost>
diff --git a/ash/components/arc/test/fake_arc_bridge_host.cc b/ash/components/arc/test/fake_arc_bridge_host.cc
index 981dcecc..6bff627e 100644
--- a/ash/components/arc/test/fake_arc_bridge_host.cc
+++ b/ash/components/arc/test/fake_arc_bridge_host.cc
@@ -104,6 +104,10 @@
 void FakeArcBridgeHost::OnCameraInstanceReady(
     mojo::PendingRemote<mojom::CameraInstance> camera_remote) {}
 
+void FakeArcBridgeHost::OnChromeFeatureFlagsInstanceReady(
+    mojo::PendingRemote<mojom::ChromeFeatureFlagsInstance>
+        chrome_feature_flags_remote) {}
+
 void FakeArcBridgeHost::OnClipboardInstanceReady(
     mojo::PendingRemote<mojom::ClipboardInstance> clipboard_remote) {}
 
diff --git a/ash/components/arc/test/fake_arc_bridge_host.h b/ash/components/arc/test/fake_arc_bridge_host.h
index 0d87745e..3261beb 100644
--- a/ash/components/arc/test/fake_arc_bridge_host.h
+++ b/ash/components/arc/test/fake_arc_bridge_host.h
@@ -47,6 +47,9 @@
           boot_phase_monitor_remote) override;
   void OnCameraInstanceReady(
       mojo::PendingRemote<mojom::CameraInstance> camera_remote) override;
+  void OnChromeFeatureFlagsInstanceReady(
+      mojo::PendingRemote<mojom::ChromeFeatureFlagsInstance>
+          chrome_feature_flags_remote) override;
   void OnClipboardInstanceReady(
       mojo::PendingRemote<mojom::ClipboardInstance> clipboard_remote) override;
   void OnCompatibilityModeInstanceReady(
diff --git a/ash/components/arc/test/fake_chrome_feature_flags_instance.cc b/ash/components/arc/test/fake_chrome_feature_flags_instance.cc
new file mode 100644
index 0000000..babb5a4
--- /dev/null
+++ b/ash/components/arc/test/fake_chrome_feature_flags_instance.cc
@@ -0,0 +1,18 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/components/arc/test/fake_chrome_feature_flags_instance.h"
+#include "base/functional/callback_helpers.h"
+
+namespace arc {
+
+FakeChromeFeatureFlagsInstance::FakeChromeFeatureFlagsInstance() = default;
+
+FakeChromeFeatureFlagsInstance::~FakeChromeFeatureFlagsInstance() = default;
+
+void FakeChromeFeatureFlagsInstance::NotifyQsRevamp(bool enabled) {
+  qs_revamp_called_value_ = enabled;
+}
+
+}  // namespace arc
diff --git a/ash/components/arc/test/fake_chrome_feature_flags_instance.h b/ash/components/arc/test/fake_chrome_feature_flags_instance.h
new file mode 100644
index 0000000..1d927450
--- /dev/null
+++ b/ash/components/arc/test/fake_chrome_feature_flags_instance.h
@@ -0,0 +1,38 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_COMPONENTS_ARC_TEST_FAKE_CHROME_FEATURE_FLAGS_INSTANCE_H_
+#define ASH_COMPONENTS_ARC_TEST_FAKE_CHROME_FEATURE_FLAGS_INSTANCE_H_
+
+#include "ash/components/arc/mojom/chrome_feature_flags.mojom.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+
+namespace arc {
+
+class FakeChromeFeatureFlagsInstance
+    : public mojom::ChromeFeatureFlagsInstance {
+ public:
+  FakeChromeFeatureFlagsInstance();
+
+  FakeChromeFeatureFlagsInstance(const FakeChromeFeatureFlagsInstance&) =
+      delete;
+  FakeChromeFeatureFlagsInstance& operator=(
+      const FakeChromeFeatureFlagsInstance&) = delete;
+
+  ~FakeChromeFeatureFlagsInstance() override;
+
+  absl::optional<bool> qs_revamp_called_value() {
+    return qs_revamp_called_value_;
+  }
+
+  // mojom::ChromeFeatureFlagsInstance overrides:
+  void NotifyQsRevamp(bool enabled) override;
+
+ private:
+  absl::optional<bool> qs_revamp_called_value_;
+};
+
+}  // namespace arc
+
+#endif  // ASH_COMPONENTS_ARC_TEST_FAKE_CHROME_FEATURE_FLAGS_INSTANCE_H_
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 9ad6738..3b193d8 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -687,13 +687,6 @@
              "EnableLocalSearchService",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-// Enables using DiagnosticsLogController to manage lifetime of logs for the
-// diagnostics app routines, network events, and system snapshot.
-// TODO(ashleydp): Remove this after the feature is launched.
-BASE_FEATURE(kEnableLogControllerForDiagnosticsApp,
-             "EnableLogControllerForDiagnosticsApp",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // Enables OAuth support when printing via the IPP protocol.
 BASE_FEATURE(kEnableOAuthIpp,
              "EnableOAuthIpp",
@@ -1733,7 +1726,7 @@
 // Enables user to provision PasspointARCSupport credentials.
 BASE_FEATURE(kPasspointARCSupport,
              "PasspointARCSupport",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Enables user to display Passpoint credentials in the UI.
 BASE_FEATURE(kPasspointSettings,
@@ -1752,11 +1745,6 @@
 // currently active desk.
 BASE_FEATURE(kPerDeskShelf, "PerDeskShelf", base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Enables Jelly features in Personalization App.
-BASE_FEATURE(kPersonalizationJelly,
-             "PersonalizationJelly",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // Provides a UI for users to view information about their Android phone
 // and perform phone-side actions within ChromeOS.
 BASE_FEATURE(kPhoneHub, "PhoneHub", base::FEATURE_ENABLED_BY_DEFAULT);
@@ -2148,15 +2136,28 @@
              "SmartLockUIRevamp",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+// Enables the consumer and enterprise support for provisioning eSIM profiles
+// using Subscription Manager Discovery Service (SM-DS). This flag is a no-op
+// unless the SmdsSupportEuiccUpload and SmdsDbusMigration flags are enabled.
+// These additional flags are required since the functionality they impelemnt is
+// required by this flag, such as:
+//  - Using the newly added RefreshSmdxProfiles API.
+//  - Tracking when an eSIM profile has already been installed for a
+//    policy-defined cellular network.
 BASE_FEATURE(kSmdsSupport, "SmdsSupport", base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Enables tracking when a policy-defined cellular network configured to use
+// SM-DS has already been applied and an eSIM profile for the network was
+// installed.
 BASE_FEATURE(kSmdsSupportEuiccUpload,
              "SmdsSupportEuiccUpload",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Enables the usage of DBus APIs that improve the stability around performing
+// SM-DS scans.
 BASE_FEATURE(kSmdsDbusMigration,
              "SmdsDbusMigration",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Controls whether the snap group feature is enabled or not.
 BASE_FEATURE(kSnapGroup, "SnapGroup", base::FEATURE_DISABLED_BY_DEFAULT);
@@ -3087,10 +3088,6 @@
       kLockScreenHideSensitiveNotificationsSupport);
 }
 
-bool IsLogControllerForDiagnosticsAppEnabled() {
-  return base::FeatureList::IsEnabled(kEnableLogControllerForDiagnosticsApp);
-}
-
 bool IsEducationEnrollmentOobeFlowEnabled() {
   return base::FeatureList::IsEnabled(kEducationEnrollmentOobeFlow);
 }
@@ -3301,8 +3298,7 @@
 }
 
 bool IsPersonalizationJellyEnabled() {
-  return base::FeatureList::IsEnabled(kPersonalizationJelly) &&
-         chromeos::features::IsJellyEnabled();
+  return chromeos::features::IsJellyEnabled();
 }
 
 bool IsPhoneHubCameraRollEnabled() {
@@ -3496,13 +3492,12 @@
 
 bool IsSmdsSupportEnabled() {
   return base::FeatureList::IsEnabled(kSmdsDbusMigration) &&
-         base::FeatureList::IsEnabled(kSmdsSupport);
+         base::FeatureList::IsEnabled(kSmdsSupport) &&
+         base::FeatureList::IsEnabled(kSmdsSupportEuiccUpload);
 }
 
 bool IsSmdsSupportEuiccUploadEnabled() {
-  return base::FeatureList::IsEnabled(kSmdsDbusMigration) &&
-         base::FeatureList::IsEnabled(kSmdsSupport) &&
-         base::FeatureList::IsEnabled(kSmdsSupportEuiccUpload);
+  return base::FeatureList::IsEnabled(kSmdsSupportEuiccUpload);
 }
 
 bool IsSmdsDbusMigrationEnabled() {
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index fd46a37..777e64bc 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -209,8 +209,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kEnableLazyLoginWebUILoading);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kEnableLocalSearchService);
-COMPONENT_EXPORT(ASH_CONSTANTS)
-BASE_DECLARE_FEATURE(kEnableLogControllerForDiagnosticsApp);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kEnableOAuthIpp);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kEnableOobeChromeVoxHint);
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -507,7 +505,6 @@
 BASE_DECLARE_FEATURE(kPcieBillboardNotification);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPerDeskShelf);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPerUserMetrics);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPersonalizationJelly);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPhoneHub);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPhoneHubCameraRoll);
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -849,7 +846,6 @@
 bool IsLockScreenHideSensitiveNotificationsSupported();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsLockScreenInlineReplyEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsLockScreenNotificationsEnabled();
-COMPONENT_EXPORT(ASH_CONSTANTS) bool IsLogControllerForDiagnosticsAppEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool IsLoginScreenDeviceTrustConnectorFeatureEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsMacAddressRandomizationEnabled();
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc
index fda531b..f3ea55b0 100644
--- a/ash/constants/ash_pref_names.cc
+++ b/ash/constants/ash_pref_names.cc
@@ -1530,6 +1530,14 @@
 const char kKeyEventRemappedToSixPackPageDown[] =
     "ash.settings.key_event_remapped_to_six_pack_page_down";
 
+// This pref saves the absolute session start time for UMA.
+const char kAshLoginSessionStartedTime[] = "ash.Login.SessionStarted.Time";
+
+// This pref saves the "first user session after user was added to the device"
+// flag for UMA.
+const char kAshLoginSessionStartedIsFirstSession[] =
+    "ash.Login.SessionStarted.IsFirstSession";
+
 // NOTE: New prefs should start with the "ash." prefix. Existing prefs moved
 // into this file should not be renamed, since they may be synced.
 
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h
index 7954331..6883e70 100644
--- a/ash/constants/ash_pref_names.h
+++ b/ash/constants/ash_pref_names.h
@@ -723,6 +723,12 @@
 
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const char kKeyEventRemappedToSixPackPageDown[];
+
+COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const char kAshLoginSessionStartedTime[];
+
+COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const char kAshLoginSessionStartedIsFirstSession[];
 }  // namespace prefs
 }  // namespace ash
 
diff --git a/ash/public/cpp/accelerator_actions.h b/ash/public/cpp/accelerator_actions.h
index 0e720b3..a505181 100644
--- a/ash/public/cpp/accelerator_actions.h
+++ b/ash/public/cpp/accelerator_actions.h
@@ -107,6 +107,7 @@
   ACCELERATOR_ACTION_ENTRY(ShowStylusTools)                             \
   ACCELERATOR_ACTION_ENTRY(ShowTaskManager)                             \
   ACCELERATOR_ACTION_ENTRY(StartAssistant)                              \
+  ACCELERATOR_ACTION_ENTRY(StopScreenRecording)                         \
   ACCELERATOR_ACTION_ENTRY(Suspend)                                     \
   ACCELERATOR_ACTION_ENTRY(SwapPrimaryDisplay)                          \
   /* Switch to another IME depending on the accelerator. */             \
diff --git a/ash/public/cpp/accelerators.cc b/ash/public/cpp/accelerators.cc
index baa14b9..97efb439 100644
--- a/ash/public/cpp/accelerators.cc
+++ b/ash/public/cpp/accelerators.cc
@@ -197,6 +197,8 @@
      AcceleratorAction::kToggleMessageCenterBubble},
     {true, ui::VKEY_P, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
      AcceleratorAction::kShowStylusTools},
+    {true, ui::VKEY_X, ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN,
+     AcceleratorAction::kStopScreenRecording},
     {true, ui::VKEY_S, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
      AcceleratorAction::kToggleSystemTrayBubble},
     // Until we have unified settings and notifications the "hamburger"
diff --git a/ash/public/cpp/app_list/app_list_metrics.h b/ash/public/cpp/app_list/app_list_metrics.h
index 1e9f51ea..054b8b9d 100644
--- a/ash/public/cpp/app_list/app_list_metrics.h
+++ b/ash/public/cpp/app_list/app_list_metrics.h
@@ -53,7 +53,8 @@
   kAssistantEntryPoint = 6,
   kScrollFromShelf = 7,
   kBrowser = 8,
-  kMaxValue = kBrowser,
+  kWelcomeTour = 9,
+  kMaxValue = kWelcomeTour,
 };
 
 // Tracks the conclusion of each search session starting from the search box.
diff --git a/ash/public/cpp/ash_view_ids.h b/ash/public/cpp/ash_view_ids.h
index 79237d5..5dcde2d 100644
--- a/ash/public/cpp/ash_view_ids.h
+++ b/ash/public/cpp/ash_view_ids.h
@@ -71,6 +71,8 @@
   VIEW_ID_QS_DISPLAY_TILE_CONTAINER,
   VIEW_ID_QS_DISPLAY_MAX = VIEW_ID_QS_DISPLAY_TILE_CONTAINER,
 
+  VIEW_ID_QS_POWER_BUTTON_CHEVRON_ICON,
+
   // Status area trays:
   VIEW_ID_SA_MIN,
   VIEW_ID_SA_DATE_TRAY = VIEW_ID_SA_MIN,
diff --git a/ash/public/cpp/shell_window_ids.h b/ash/public/cpp/shell_window_ids.h
index dd480a5..6ccaecf 100644
--- a/ash/public/cpp/shell_window_ids.h
+++ b/ash/public/cpp/shell_window_ids.h
@@ -164,6 +164,12 @@
   // notifier elements such as notification popups and system nudges.
   kShellWindowId_SettingBubbleContainer,
 
+  // The container for help bubbles which are anchored to views for the purpose
+  // of user education. In the case of the Welcome Tour, which walks new users
+  // through ChromeOS System UI, a background blur will be applied to the
+  // container with a masked cut out for the help bubble anchor view.
+  kShellWindowId_HelpBubbleContainer,
+
   // Contains special accessibility windows that can inset the display work area
   // (e.g. the ChromeVox spoken feedback window).
   // TODO(jamescook): Consolidate this with DockedMagnifierContainer.
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 71d2fad..553d462 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -1302,6 +1302,12 @@
   settings_bubble_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
   settings_bubble_container->SetProperty(kLockedToRootKey, true);
 
+  aura::Window* help_bubble_container =
+      CreateContainer(kShellWindowId_HelpBubbleContainer, "HelpBubbleContainer",
+                      lock_screen_related_containers);
+  ::wm::SetChildWindowVisibilityChangesAnimated(help_bubble_container);
+  help_bubble_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
+
   aura::Window* virtual_keyboard_parent_container = CreateContainer(
       kShellWindowId_ImeWindowParentContainer, "ImeWindowParentContainer",
       lock_screen_related_containers);
diff --git a/ash/session/session_controller_impl.cc b/ash/session/session_controller_impl.cc
index cb7522d..2b392ea 100644
--- a/ash/session/session_controller_impl.cc
+++ b/ash/session/session_controller_impl.cc
@@ -70,6 +70,10 @@
 void SessionControllerImpl::RegisterUserProfilePrefs(
     PrefRegistrySimple* registry) {
   registry->RegisterTimePref(prefs::kTimeOfLastSessionActivation, base::Time());
+  registry->RegisterTimePref(ash::prefs::kAshLoginSessionStartedTime,
+                             base::Time());
+  registry->RegisterBooleanPref(
+      ash::prefs::kAshLoginSessionStartedIsFirstSession, false);
 }
 
 int SessionControllerImpl::NumberOfLoggedInUsers() const {
diff --git a/ash/shell.cc b/ash/shell.cc
index 0fd90af6..66f57bc 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -1170,10 +1170,8 @@
   }
 
   // Manages lifetime of DiagnosticApp logs.
-  if (features::IsLogControllerForDiagnosticsAppEnabled()) {
-    diagnostics_log_controller_ =
-        std::make_unique<diagnostics::DiagnosticsLogController>();
-  }
+  diagnostics_log_controller_ =
+      std::make_unique<diagnostics::DiagnosticsLogController>();
 
   pcie_peripheral_notification_controller_ =
       std::make_unique<PciePeripheralNotificationController>(
diff --git a/ash/style/pill_button.cc b/ash/style/pill_button.cc
index 2e0b96f..31945304 100644
--- a/ash/style/pill_button.cc
+++ b/ash/style/pill_button.cc
@@ -212,15 +212,6 @@
   return GetButtonHeight(type_);
 }
 
-void PillButton::OnThemeChanged() {
-  // If the button is not added to a widget, we don't have to update the color.
-  if (!GetWidget())
-    return;
-
-  views::LabelButton::OnThemeChanged();
-  UpdateTextColor();
-}
-
 gfx::Insets PillButton::GetInsets() const {
   const int vertical_spacing = (GetButtonHeight(type_) - kIconSize) / 2;
   const int icon_padding = IsIconPillButton(type_)
@@ -364,11 +355,7 @@
   if (!GetWidget())
     return;
 
-  // TODO(b:272787322): When LabelButton is able to use color ID, directly
-  // use color ID for default text color.
-  auto* color_provider = GetColorProvider();
-  SetTextColor(views::Button::STATE_DISABLED,
-               color_provider->GetColor(cros_tokens::kCrosSysDisabled));
+  SetTextColorId(views::Button::STATE_DISABLED, cros_tokens::kCrosSysDisabled);
 
   // If custom text color is set, use it to set text color.
   if (text_color_) {
@@ -380,8 +367,7 @@
   // color.
   auto default_color_id = GetDefaultButtonTextIconColorId(type_);
   DCHECK(default_color_id);
-  SetEnabledTextColors(color_provider->GetColor(
-      text_color_id_.value_or(default_color_id.value())));
+  SetEnabledTextColorIds(text_color_id_.value_or(default_color_id.value()));
 }
 
 void PillButton::UpdateIconColor() {
diff --git a/ash/style/pill_button.h b/ash/style/pill_button.h
index 438a26c..28da63d 100644
--- a/ash/style/pill_button.h
+++ b/ash/style/pill_button.h
@@ -175,7 +175,6 @@
   void AddedToWidget() override;
   gfx::Size CalculatePreferredSize() const override;
   int GetHeightForWidth(int width) const override;
-  void OnThemeChanged() override;
   gfx::Insets GetInsets() const override;
   void UpdateBackgroundColor() override;
 
diff --git a/ash/system/accessibility/accessibility_detailed_view.cc b/ash/system/accessibility/accessibility_detailed_view.cc
index a233d954..148b28f 100644
--- a/ash/system/accessibility/accessibility_detailed_view.cc
+++ b/ash/system/accessibility/accessibility_detailed_view.cc
@@ -349,10 +349,7 @@
       controller->cursor_highlight().enabled()) {
     highlight_mouse_cursor_top_view_ = AddHighlightMouseCursorView(container);
   }
-  // Focus highlighting can't be on when spoken feedback is on because
-  // ChromeVox does its own focus highlighting.
-  if (!controller->spoken_feedback().enabled() &&
-      controller->IsFocusHighlightSettingVisibleInTray() &&
+  if (controller->IsFocusHighlightSettingVisibleInTray() &&
       controller->focus_highlight().enabled()) {
     highlight_keyboard_focus_top_view_ =
         AddHighlightKeyboardFocusView(container);
@@ -438,10 +435,8 @@
   if (controller->IsCursorHighlightSettingVisibleInTray()) {
     highlight_mouse_cursor_view_ = AddHighlightMouseCursorView(container);
   }
-  // Focus highlighting can't be on when spoken feedback is on because
-  // ChromeVox does its own focus highlighting.
-  if (!controller->spoken_feedback().enabled() &&
-      controller->IsFocusHighlightSettingVisibleInTray()) {
+
+  if (controller->IsFocusHighlightSettingVisibleInTray()) {
     highlight_keyboard_focus_view_ = AddHighlightKeyboardFocusView(container);
   }
 
diff --git a/ash/system/accessibility/accessibility_detailed_view_unittest.cc b/ash/system/accessibility/accessibility_detailed_view_unittest.cc
index 7eac51fb..fb33656 100644
--- a/ash/system/accessibility/accessibility_detailed_view_unittest.cc
+++ b/ash/system/accessibility/accessibility_detailed_view_unittest.cc
@@ -420,6 +420,11 @@
   }
 
   bool IsStickyKeysEnabledOnDetailMenu() const {
+    // The sticky_keys_view_ is not created when Spoken Feedback is enabled.
+    if (IsSpokenFeedbackEnabledOnDetailMenu()) {
+      DCHECK(!detailed_menu_->sticky_keys_view_);
+      return false;
+    }
     return IsEnabledOnDetailMenu(controller_->sticky_keys().enabled(),
                                  detailed_menu_->sticky_keys_view_);
   }
@@ -1380,6 +1385,30 @@
   CloseDetailMenu();
 }
 
+TEST_F(AccessibilityDetailedViewLoginScreenTest,
+       SpokenFeedbackConflictingFeatures) {
+  EnableStickyKeys(true);
+  SetFocusHighlightEnabled(true);
+  CreateDetailedMenu();
+  EXPECT_TRUE(IsStickyKeysEnabledOnDetailMenu());
+  EXPECT_TRUE(IsHighlightKeyboardFocusEnabledOnDetailMenu());
+  CloseDetailMenu();
+
+  // When ChromeVox is on, even though sticky keys and focus highlight were
+  // enabled, they will not be shown.
+  EnableSpokenFeedback(true);
+  CreateDetailedMenu();
+  EXPECT_FALSE(IsStickyKeysEnabledOnDetailMenu());
+  EXPECT_FALSE(IsHighlightKeyboardFocusEnabledOnDetailMenu());
+  CloseDetailMenu();
+
+  EnableSpokenFeedback(false);
+  CreateDetailedMenu();
+  EXPECT_TRUE(IsStickyKeysEnabledOnDetailMenu());
+  EXPECT_TRUE(IsHighlightKeyboardFocusEnabledOnDetailMenu());
+  CloseDetailMenu();
+}
+
 TEST_F(AccessibilityDetailedViewLoginScreenTest, SelectToSpeak) {
   // Enabling select to speak.
   EnableSelectToSpeak(true);
@@ -2086,7 +2115,8 @@
   EXPECT_TRUE(IsHighlightMouseCursorEnabledOnDetailMenu());
   // Focus highlighting can't be on when spoken feedback is on
   EXPECT_FALSE(IsHighlightKeyboardFocusEnabledOnDetailMenu());
-  EXPECT_TRUE(IsStickyKeysEnabledOnDetailMenu());
+  // Sticky keys can't be on when spoken feedback is on.
+  EXPECT_FALSE(IsStickyKeysEnabledOnDetailMenu());
   EXPECT_TRUE(IsSwitchAccessEnabledOnDetailMenu());
   CloseDetailMenu();
 
diff --git a/ash/system/diagnostics/diagnostics_log_controller_unittest.cc b/ash/system/diagnostics/diagnostics_log_controller_unittest.cc
index 80fef66..ed10fa3e 100644
--- a/ash/system/diagnostics/diagnostics_log_controller_unittest.cc
+++ b/ash/system/diagnostics/diagnostics_log_controller_unittest.cc
@@ -74,9 +74,7 @@
 
   void SetUp() override {
     feature_list_.InitWithFeatures(
-        /* enabled_features=*/{ash::features::
-                                   kEnableLogControllerForDiagnosticsApp,
-                               ash::features::kEnableInputInDiagnosticsApp},
+        /* enabled_features=*/{ash::features::kEnableInputInDiagnosticsApp},
         /* disabled_features=*/{});
 
     NoSessionAshTestBase::SetUp();
diff --git a/ash/system/human_presence/snooping_protection_notification_blocker_unittest.cc b/ash/system/human_presence/snooping_protection_notification_blocker_unittest.cc
index 5e035801..b1df2221 100644
--- a/ash/system/human_presence/snooping_protection_notification_blocker_unittest.cc
+++ b/ash/system/human_presence/snooping_protection_notification_blocker_unittest.cc
@@ -194,7 +194,7 @@
               {"SnoopingProtection_positive_score_threshold", "0"},
               {"SnoopingProtection_negative_score_threshold", "0"},
           }}},
-        {ash::features::kQuickDim});
+        {ash::features::kQuickDim, ash::features::kQsRevamp});
     scoped_command_line_.GetProcessCommandLine()->AppendSwitch(
         switches::kHasHps);
   }
diff --git a/ash/system/input_device_settings/input_device_notifier.cc b/ash/system/input_device_settings/input_device_notifier.cc
index d9773b3..bbff0cf54 100644
--- a/ash/system/input_device_settings/input_device_notifier.cc
+++ b/ash/system/input_device_settings/input_device_notifier.cc
@@ -33,7 +33,7 @@
 template <class DeviceMojomPtr>
 bool IsDeviceASuspectedImposter(BluetoothDevicesObserver* bluetooth_observer,
                                 const ui::InputDevice& device) {
-  return device.suspected_imposter;
+  return false;
 }
 
 template <>
@@ -97,7 +97,7 @@
     return true;
   }
 
-  return device.suspected_imposter;
+  return false;
 }
 
 template <typename T>
diff --git a/ash/system/input_device_settings/input_device_notifier_unittest.cc b/ash/system/input_device_settings/input_device_notifier_unittest.cc
index af13ac9..904dea50 100644
--- a/ash/system/input_device_settings/input_device_notifier_unittest.cc
+++ b/ash/system/input_device_settings/input_device_notifier_unittest.cc
@@ -533,6 +533,11 @@
   ui::DeviceDataManagerTestApi()
       .NotifyObserversMouseDeviceConfigurationChanged();
   ASSERT_EQ(2u, devices_to_add_.size());
+
+  // Needed to reset the `bluetooth_adapter_`.
+  ON_CALL(*bluetooth_adapter_, GetDevices)
+      .WillByDefault(
+          testing::Return(std::vector<const device::BluetoothDevice*>()));
 }
 
 }  // namespace ash
diff --git a/ash/system/message_center/ash_notification_view_pixeltest.cc b/ash/system/message_center/ash_notification_view_pixeltest.cc
index 9ef5bcd..e7cda7b 100644
--- a/ash/system/message_center/ash_notification_view_pixeltest.cc
+++ b/ash/system/message_center/ash_notification_view_pixeltest.cc
@@ -17,6 +17,7 @@
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "ui/base/models/image_model.h"
 #include "ui/message_center/views/message_popup_view.h"
 #include "ui/message_center/views/message_view.h"
@@ -211,14 +212,23 @@
 
 class ScreenCaptureNotificationPixelTest
     : public AshNotificationViewPixelTestBase,
-      public testing::WithParamInterface<DisplayType> {
+      public testing::WithParamInterface<
+          std::tuple<bool /*IsQsRevampEnabled()*/, DisplayType>> {
  public:
   // AshNotificationViewPixelTestBase:
   void SetUp() override {
+    std::vector<base::test::FeatureRef> features = {features::kQsRevamp,
+                                                    chromeos::features::kJelly};
+    std::vector<base::test::FeatureRef> enabled_features;
+    std::vector<base::test::FeatureRef> disabled_features;
+    (std::get<0>(GetParam()) ? enabled_features : disabled_features)
+        .swap(features);
+    scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
+
     AshNotificationViewPixelTestBase::SetUp();
 
     // Change the display size depending on the test param.
-    switch (GetParam()) {
+    switch (GetDisplayType()) {
       case DisplayType::kNormal:
         break;
       case DisplayType::kUltraWidth:
@@ -243,16 +253,23 @@
     AshNotificationViewPixelTestBase::TearDown();
   }
 
+  bool IsQsRevampEnabled() const { return std::get<0>(GetParam()); }
+
+  const DisplayType& GetDisplayType() const { return std::get<1>(GetParam()); }
+
  private:
+  base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<aura::Window> window1_;
   std::unique_ptr<aura::Window> window2_;
 };
 
-INSTANTIATE_TEST_SUITE_P(DisplaySize,
-                         ScreenCaptureNotificationPixelTest,
-                         testing::ValuesIn({DisplayType::kNormal,
-                                            DisplayType::kUltraWidth,
-                                            DisplayType::kUltraHeight}));
+INSTANTIATE_TEST_SUITE_P(
+    DisplaySize,
+    ScreenCaptureNotificationPixelTest,
+    testing::Combine(/*IsQsRevampEnabled()=*/testing::Bool(),
+                     testing::ValuesIn({DisplayType::kNormal,
+                                        DisplayType::kUltraWidth,
+                                        DisplayType::kUltraHeight})));
 
 // Verifies the notification popup of a full screenshot.
 TEST_P(ScreenCaptureNotificationPixelTest, VerifyPopup) {
@@ -270,7 +287,7 @@
   // Get the notification view.
   EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
       base::StrCat({"screen_capture_popup_notification_",
-                    GetDisplayTypeName(GetParam())}),
+                    GetDisplayTypeName(GetDisplayType())}),
       /*revision_number=*/1,
       test_api()->GetPopupViewForId(kScreenCaptureNotificationId)));
 }
diff --git a/ash/system/unified/power_button.cc b/ash/system/unified/power_button.cc
index f3c49a9..4b11560 100644
--- a/ash/system/unified/power_button.cc
+++ b/ash/system/unified/power_button.cc
@@ -346,6 +346,7 @@
       kUnifiedMenuPowerIcon, cros_tokens::kCrosSysOnSurface));
   power_icon_->SetImageSize(kIconSize);
   arrow_icon_ = AddChildView(std::make_unique<views::ImageView>());
+  arrow_icon_->SetID(VIEW_ID_QS_POWER_BUTTON_CHEVRON_ICON);
   arrow_icon_->SetImage(ui::ImageModel::FromVectorIcon(
       kChevronDownSmallIcon, cros_tokens::kCrosSysOnSurface));
   arrow_icon_->SetImageSize(kIconSize);
@@ -368,8 +369,8 @@
                                  : cros_tokens::kCrosSysOnSurface;
   power_icon_->SetImage(
       ui::ImageModel::FromVectorIcon(kUnifiedMenuPowerIcon, icon_color_id));
-  arrow_icon_->SetImage(
-      ui::ImageModel::FromVectorIcon(kChevronDownSmallIcon, icon_color_id));
+  arrow_icon_->SetImage(ui::ImageModel::FromVectorIcon(
+      is_active ? kChevronUpSmallIcon : kChevronDownSmallIcon, icon_color_id));
 }
 
 PowerButton::PowerButton(UnifiedSystemTrayController* tray_controller)
diff --git a/ash/system/unified/power_button_unittest.cc b/ash/system/unified/power_button_unittest.cc
index 3863c82..c5969ba 100644
--- a/ash/system/unified/power_button_unittest.cc
+++ b/ash/system/unified/power_button_unittest.cc
@@ -23,8 +23,11 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "components/user_manager/user_type.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/compositor/layer.h"
 #include "ui/events/base_event_utils.h"
+#include "ui/gfx/skia_util.h"
+#include "ui/views/controls/image_view.h"
 #include "ui/views/controls/menu/menu_item_view.h"
 #include "ui/views/test/views_test_utils.h"
 #include "ui/views/view.h"
@@ -98,11 +101,42 @@
 
   PowerButton* GetPowerButton() { return button_; }
 
+  views::ImageView* GetPowerChevronIcon() {
+    auto* icon = button_->button_content_->GetViewByID(
+        VIEW_ID_QS_POWER_BUTTON_CHEVRON_ICON);
+    CHECK(icon);
+    return static_cast<views::ImageView*>(icon);
+  }
+
   ui::Layer* GetBackgroundLayer() { return button_->background_view_->layer(); }
 
   // Simulates mouse press event on the power button.
   void SimulatePowerButtonPress() { LeftClickOn(button_->button_content_); }
 
+  ui::ImageModel GetExpectedChevronImageModel(bool use_up_chevron) {
+    auto icon_color_id = use_up_chevron
+                             ? cros_tokens::kCrosSysSystemOnPrimaryContainer
+                             : cros_tokens::kCrosSysOnSurface;
+
+    return ui::ImageModel::FromVectorIcon(
+        use_up_chevron ? kChevronUpSmallIcon : kChevronDownSmallIcon,
+        icon_color_id);
+  }
+
+  bool ChevronIconsMatch(bool use_up_chevron) {
+    const auto* power_chevron_icon = GetPowerChevronIcon();
+
+    return gfx::BitmapsAreEqual(
+        *power_chevron_icon->GetImage().bitmap(),
+        *GetExpectedChevronImageModel(use_up_chevron)
+             .Rasterize(power_chevron_icon->GetColorProvider())
+             .bitmap());
+  }
+
+  bool IsUpChevron() { return ChevronIconsMatch(/*use_up_chevron=*/true); }
+
+  bool IsDownChevron() { return ChevronIconsMatch(/*use_up_chevron=*/false); }
+
   // Owned by view hierarchy.
   raw_ptr<PowerButton, ExperimentalAsh> button_ = nullptr;
 
@@ -395,8 +429,8 @@
   EXPECT_EQ(gfx::RoundedCornersF(4, 16, 16, 16),
             GetBackgroundLayer()->rounded_corner_radii());
 
-  // Click on a random button to close the menu.
-  LeftClickOn(GetLockButton());
+  // Click the power button again to close the menu.
+  SimulatePowerButtonPress();
 
   // Sets a RTL locale.
   base::i18n::SetICUDefaultLocale("ar");
@@ -422,4 +456,23 @@
   EXPECT_TRUE(GetRestartButton());
 }
 
+TEST_F(PowerButtonTest, ChevronFlipsWhenMenuIsShowing) {
+  CreateUserSessions(1);
+
+  EXPECT_TRUE(GetPowerButton()->GetVisible());
+  EXPECT_FALSE(IsMenuShowing());
+  EXPECT_TRUE(IsDownChevron());
+
+  SimulatePowerButtonPress();
+
+  EXPECT_TRUE(IsMenuShowing());
+  EXPECT_TRUE(IsUpChevron());
+
+  // Click the power button again to close the menu.
+  SimulatePowerButtonPress();
+
+  EXPECT_FALSE(IsMenuShowing());
+  EXPECT_TRUE(IsDownChevron());
+}
+
 }  // namespace ash
diff --git a/ash/system/video_conference/video_conference_tray_controller.cc b/ash/system/video_conference/video_conference_tray_controller.cc
index 51e572c..89553cc 100644
--- a/ash/system/video_conference/video_conference_tray_controller.cc
+++ b/ash/system/video_conference/video_conference_tray_controller.cc
@@ -22,8 +22,10 @@
 #include "ash/system/video_conference/video_conference_common.h"
 #include "ash/system/video_conference/video_conference_tray.h"
 #include "base/check.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/notreached.h"
 #include "base/time/time.h"
+#include "base/timer/timer.h"
 #include "chromeos/ash/components/audio/cras_audio_handler.h"
 #include "chromeos/crosapi/mojom/video_conference.mojom.h"
 #include "components/prefs/pref_service.h"
@@ -46,6 +48,8 @@
 // The cool down duration for speak-on-mute detection notification in seconds.
 constexpr int KSpeakOnMuteNotificationCoolDownDuration = 60;
 
+constexpr auto kRepeatedShowTimerInterval = base::Milliseconds(100);
+
 VideoConferenceTrayController* g_controller_instance = nullptr;
 
 bool IsAnyShelfAutoHidden() {
@@ -69,7 +73,12 @@
 
 }  // namespace
 
-VideoConferenceTrayController::VideoConferenceTrayController() {
+VideoConferenceTrayController::VideoConferenceTrayController()
+    : repeated_shows_timer_(
+          FROM_HERE,
+          kRepeatedShowTimerInterval,
+          this,
+          &VideoConferenceTrayController::RecordRepeatedShows) {
   DCHECK(!g_controller_instance);
   g_controller_instance = this;
 }
@@ -310,6 +319,12 @@
 
   if (new_tray_target_visibility && !old_tray_target_visibility) {
     effects_manager_.RecordInitialStates();
+
+    // Keeps increment the count to track the number of times the view flickers.
+    // When the delay of `kRepeatedShowTimerInterval` has reached, record that
+    // count.
+    ++count_repeated_shows_;
+    repeated_shows_timer_.Reset();
   }
 
   if (state_.has_media_app != old_state.has_media_app) {
@@ -468,4 +483,17 @@
           std::ref(disable_shelf_autohide_locks_)));
 }
 
+void VideoConferenceTrayController::RecordRepeatedShows() {
+  // Note that we also record the metric when `count_repeated_shows_` is one
+  // even though this is not a bad signal. This is because we want to record
+  // proper shows so we can analyze the repeated shows in context.
+  if (count_repeated_shows_ == 0) {
+    return;
+  }
+
+  base::UmaHistogramCounts100("Ash.VideoConference.NumberOfRepeatedShows",
+                              count_repeated_shows_);
+  count_repeated_shows_ = 0;
+}
+
 }  // namespace ash
diff --git a/ash/system/video_conference/video_conference_tray_controller.h b/ash/system/video_conference/video_conference_tray_controller.h
index ab0d0df..bd41835 100644
--- a/ash/system/video_conference/video_conference_tray_controller.h
+++ b/ash/system/video_conference/video_conference_tray_controller.h
@@ -11,6 +11,7 @@
 #include "ash/system/video_conference/video_conference_common.h"
 #include "base/observer_list_types.h"
 #include "base/time/time.h"
+#include "base/timer/timer.h"
 #include "chromeos/ash/components/audio/cras_audio_handler.h"
 #include "chromeos/crosapi/mojom/video_conference.mojom-forward.h"
 #include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"
@@ -167,6 +168,9 @@
   // of active `MediaApp`'s to force the shelf to show or hide.
   void UpdateShelfAutoHide(MediaApps apps);
 
+  // Records repeated shows metric when the timer is stop.
+  void RecordRepeatedShows();
+
   // The number of capturing apps, fetched from `VideoConferenceManagerAsh`.
   int capturing_apps_ = 0;
 
@@ -210,6 +214,10 @@
   raw_ptr<VideoConferenceManagerBase> video_conference_manager_ = nullptr;
   bool initialized_ = false;
 
+  // Used to record metrics of repeated shows per 100 ms.
+  int count_repeated_shows_ = 0;
+  base::DelayTimer repeated_shows_timer_;
+
   base::WeakPtrFactory<VideoConferenceTrayController> weak_ptr_factory_{this};
 };
 
diff --git a/ash/system/video_conference/video_conference_tray_controller_unittest.cc b/ash/system/video_conference/video_conference_tray_controller_unittest.cc
index 6ee8748..0d92454 100644
--- a/ash/system/video_conference/video_conference_tray_controller_unittest.cc
+++ b/ash/system/video_conference/video_conference_tray_controller_unittest.cc
@@ -16,6 +16,7 @@
 #include "ash/system/video_conference/video_conference_tray.h"
 #include "ash/test/ash_test_base.h"
 #include "base/command_line.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chromeos/ash/components/audio/cras_audio_handler.h"
 #include "chromeos/crosapi/mojom/video_conference.mojom.h"
@@ -32,6 +33,9 @@
 constexpr char kVideoConferenceTrayUseWhileDisabledNudgeId[] =
     "video_conference_tray_nudge_ids.use_while_disabled";
 
+constexpr char kRepeatedShowsHistogramName[] =
+    "Ash.VideoConference.NumberOfRepeatedShows";
+
 bool IsNudgeShown(const std::string& id) {
   return Shell::Get()->anchored_nudge_manager()->IsNudgeShown(id);
 }
@@ -48,7 +52,8 @@
 
 class VideoConferenceTrayControllerTest : public AshTestBase {
  public:
-  VideoConferenceTrayControllerTest() = default;
+  VideoConferenceTrayControllerTest()
+      : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
   VideoConferenceTrayControllerTest(const VideoConferenceTrayControllerTest&) =
       delete;
   VideoConferenceTrayControllerTest& operator=(
@@ -342,4 +347,57 @@
   EXPECT_TRUE(IsNudgeShown(nudge_id));
 }
 
+TEST_F(VideoConferenceTrayControllerTest, RecordRepeatedShows) {
+  // Set up 2 displays. Note that only one instance should be recorded for the
+  // primary display when there are repeated shows.
+  UpdateDisplay("100x200,300x400");
+
+  base::HistogramTester histograms;
+
+  auto flicker_vc_tray = [](int number_of_flicker,
+                            FakeVideoConferenceTrayController* controller,
+                            base::test::TaskEnvironment* task_environment) {
+    // Makes the view flicker (show then hide) for `number_of_flicker` of times.
+    for (auto i = 0; i < number_of_flicker; i++) {
+      VideoConferenceMediaState state;
+      state.has_media_app = true;
+      controller->UpdateWithMediaState(state);
+
+      state.has_media_app = false;
+      controller->UpdateWithMediaState(state);
+
+      task_environment->FastForwardBy(base::Milliseconds(80));
+    }
+    task_environment->FastForwardBy(base::Milliseconds(100));
+  };
+
+  int expected_sample = 6;
+  flicker_vc_tray(expected_sample, controller(), task_environment());
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, expected_sample, 1);
+
+  // Makes one more flickering after 100ms. This flicker should not count
+  // towards the previous ones, but this will be counted in a bucket for 1 show.
+  VideoConferenceMediaState state;
+  state.has_media_app = true;
+  controller()->UpdateWithMediaState(state);
+
+  state.has_media_app = false;
+  controller()->UpdateWithMediaState(state);
+  task_environment()->FastForwardBy(base::Milliseconds(100));
+
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, expected_sample + 1,
+                               0);
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, 1, 1);
+
+  // Make sure it works again.
+  flicker_vc_tray(8, controller(), task_environment());
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, 8, 1);
+
+  flicker_vc_tray(2, controller(), task_environment());
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, 2, 1);
+
+  flicker_vc_tray(1, controller(), task_environment());
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, 1, 2);
+}
+
 }  // namespace ash
diff --git a/ash/user_education/views/help_bubble_view_ash.cc b/ash/user_education/views/help_bubble_view_ash.cc
index 55cb4c5..bbd4265 100644
--- a/ash/user_education/views/help_bubble_view_ash.cc
+++ b/ash/user_education/views/help_bubble_view_ash.cc
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "ash/bubble/bubble_utils.h"
+#include "ash/public/cpp/shell_window_ids.h"
 #include "ash/style/style_util.h"
 #include "ash/style/typography.h"
 #include "ash/user_education/user_education_types.h"
@@ -24,6 +25,7 @@
 #include "components/user_education/common/help_bubble_params.h"
 #include "components/vector_icons/vector_icons.h"
 #include "third_party/skia/include/core/SkPath.h"
+#include "ui/aura/window.h"
 #include "ui/base/interaction/element_identifier.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_header_macros.h"
@@ -629,6 +631,9 @@
   SetButtons(ui::DIALOG_BUTTON_NONE);
   set_close_on_deactivate(false);
   set_focus_traversable_from_anchor_view(false);
+  set_parent_window(
+      anchor_widget()->GetNativeWindow()->GetRootWindow()->GetChildById(
+          kShellWindowId_HelpBubbleContainer));
 
   views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this);
 
diff --git a/ash/user_education/views/help_bubble_view_ash_unittest.cc b/ash/user_education/views/help_bubble_view_ash_unittest.cc
index 9dab1c2..84f50c5 100644
--- a/ash/user_education/views/help_bubble_view_ash_unittest.cc
+++ b/ash/user_education/views/help_bubble_view_ash_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <vector>
 
+#include "ash/public/cpp/shell_window_ids.h"
 #include "ash/user_education/user_education_types.h"
 #include "ash/user_education/views/help_bubble_view_ash_test_base.h"
 #include "ash/wm/window_util.h"
@@ -71,6 +72,23 @@
 
 }  // namespace
 
+// HelpBubbleViewAshTest -------------------------------------------------------
+
+// Base class for tests of `HelpBubbleViewAsh`.
+using HelpBubbleViewAshTest = HelpBubbleViewAshTestBase;
+
+// Tests -----------------------------------------------------------------------
+
+// Verifies that help bubbles are contained within the correct parent window.
+TEST_F(HelpBubbleViewAshTest, ParentWindow) {
+  auto* const help_bubble_view = CreateHelpBubbleView(HelpBubbleStyle::kDialog);
+  EXPECT_TRUE(help_bubble_view->anchor_widget()
+                  ->GetNativeWindow()
+                  ->GetRootWindow()
+                  ->GetChildById(kShellWindowId_HelpBubbleContainer)
+                  ->Contains(help_bubble_view->GetWidget()->GetNativeWindow()));
+}
+
 // HelpBubbleViewAshStyleTest --------------------------------------------------
 
 // Base class for tests of `HelpBubbleViewAsh` parameterized by style.
diff --git a/ash/user_education/welcome_tour/welcome_tour_controller.cc b/ash/user_education/welcome_tour/welcome_tour_controller.cc
index 20191cb7b6..3b65f51 100644
--- a/ash/user_education/welcome_tour/welcome_tour_controller.cc
+++ b/ash/user_education/welcome_tour/welcome_tour_controller.cc
@@ -4,6 +4,8 @@
 
 #include "ash/user_education/welcome_tour/welcome_tour_controller.h"
 
+#include "ash/app_list/app_list_controller_impl.h"
+#include "ash/public/cpp/app_list/app_list_metrics.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -18,6 +20,7 @@
 #include "ui/base/interaction/element_identifier.h"
 #include "ui/base/interaction/element_tracker.h"
 #include "ui/base/interaction/interaction_sequence.h"
+#include "ui/events/base_event_utils.h"
 #include "ui/views/interaction/element_tracker_views.h"
 #include "ui/views/view.h"
 
@@ -29,10 +32,14 @@
 
 // Helpers ---------------------------------------------------------------------
 
+int64_t GetPrimaryDisplayId() {
+  return display::Screen::GetScreen()->GetPrimaryDisplay().id();
+}
+
 views::View* GetMatchingViewInPrimaryRootWindow(
     ui::ElementIdentifier element_id) {
-  return user_education_util::GetMatchingViewInRootWindow(
-      display::Screen::GetScreen()->GetPrimaryDisplay().id(), element_id);
+  return user_education_util::GetMatchingViewInRootWindow(GetPrimaryDisplayId(),
+                                                          element_id);
 }
 
 views::TrackedElementViews* GetMatchingElementInPrimaryRootWindow(
@@ -152,7 +159,11 @@
           .SetBubbleBodyText(IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_BODY_TEXT)
           .SetExtendedProperties(user_education_util::CreateExtendedProperties(
               HelpBubbleId::kWelcomeTourHomeButton))
-          .AddDefaultNextButton());
+          .AddCustomNextButton(base::BindRepeating([](ui::TrackedElement*) {
+            Shell::Get()->app_list_controller()->Show(
+                GetPrimaryDisplayId(), AppListShowSource::kWelcomeTour,
+                ui::EventTimeForNow(), /*should_record_metrics=*/true);
+          })));
 
   // Step 4: Search box.
   tutorial_description.steps.emplace_back(
@@ -160,7 +171,8 @@
           .SetBubbleBodyText(IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_BODY_TEXT)
           .SetExtendedProperties(user_education_util::CreateExtendedProperties(
               HelpBubbleId::kWelcomeTourSearchBox))
-          .AddDefaultNextButton());
+          .AddDefaultNextButton()
+          .InAnyContext());
 
   // Step 5: Settings app.
   tutorial_description.steps.emplace_back(
diff --git a/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc b/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
index 354165a..ac20cc9 100644
--- a/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
+++ b/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
@@ -21,23 +21,13 @@
     : webui_(webui) {
   // Configure providers with logs from DiagnosticsLogController when flag
   // enabled.
-  if (features::IsLogControllerForDiagnosticsAppEnabled() &&
-      DiagnosticsLogController::IsInitialized()) {
+  if (DiagnosticsLogController::IsInitialized()) {
     system_data_provider_ = std::make_unique<SystemDataProvider>(
         DiagnosticsLogController::Get()->GetTelemetryLog());
     system_routine_controller_ = std::make_unique<SystemRoutineController>(
         DiagnosticsLogController::Get()->GetRoutineLog());
     network_health_provider_ = std::make_unique<NetworkHealthProvider>(
         DiagnosticsLogController::Get()->GetNetworkingLog());
-  } else {
-    // TODO(b/226574520): Remove else block as part of DiagnosticsLogController
-    // flag clean up.
-    system_data_provider_ = std::make_unique<SystemDataProvider>(
-        session_log_handler->GetTelemetryLog());
-    system_routine_controller_ = std::make_unique<SystemRoutineController>(
-        session_log_handler->GetRoutineLog());
-    network_health_provider_ = std::make_unique<NetworkHealthProvider>(
-        session_log_handler->GetNetworkingLog());
   }
 }
 
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler.cc b/ash/webui/diagnostics_ui/backend/session_log_handler.cc
index dc25374..d37bda0 100644
--- a/ash/webui/diagnostics_ui/backend/session_log_handler.cc
+++ b/ash/webui/diagnostics_ui/backend/session_log_handler.cc
@@ -89,31 +89,15 @@
                                      int index,
                                      void* params) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(session_log_handler_sequence_checker_);
-  // TODO(b/226574520): Remove SessionLogHandler::CreateSessionLog and
-  // condition as part of flag clean up.
-  if (ash::features::IsLogControllerForDiagnosticsAppEnabled()) {
-    task_runner_->PostTaskAndReplyWithResult(
-        FROM_HERE,
-        base::BindOnce(
-            &DiagnosticsLogController::GenerateSessionLogOnBlockingPool,
-            // base::Unretained safe here because ~DiagnosticsLogController is
-            // called during shutdown of ash::Shell and will out-live
-            // SessionLogHandler.
-            base::Unretained(DiagnosticsLogController::Get()), path),
-        base::BindOnce(&SessionLogHandler::OnSessionLogCreated, weak_ptr_,
-                       path));
-  } else {
-    task_runner_->PostTaskAndReplyWithResult(
-        FROM_HERE,
-        base::BindOnce(&SessionLogAsyncHelper::CreateSessionLogOnBlockingPool,
-                       // base::Unretained safe because lifetime is managed by
-                       // base::OnTaskRunnerDeleter.
-                       base::Unretained(async_helper_.get()), path,
-                       telemetry_log_.get(), routine_log_.get(),
-                       networking_log_.get()),
-        base::BindOnce(&SessionLogHandler::OnSessionLogCreated, weak_ptr_,
-                       path));
-  }
+  task_runner_->PostTaskAndReplyWithResult(
+      FROM_HERE,
+      base::BindOnce(
+          &DiagnosticsLogController::GenerateSessionLogOnBlockingPool,
+          // base::Unretained safe here because ~DiagnosticsLogController is
+          // called during shutdown of ash::Shell and will out-live
+          // SessionLogHandler.
+          base::Unretained(DiagnosticsLogController::Get()), path),
+      base::BindOnce(&SessionLogHandler::OnSessionLogCreated, weak_ptr_, path));
   select_file_dialog_.reset();
 }
 
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc b/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
index df89bdd..c959c08f 100644
--- a/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
@@ -8,7 +8,6 @@
 #include <string>
 #include <utility>
 
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/holding_space/mock_holding_space_client.h"
 #include "ash/system/diagnostics/diagnostics_browser_delegate.h"
 #include "ash/system/diagnostics/diagnostics_log_controller.h"
@@ -26,7 +25,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/test/bind.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/values.h"
@@ -434,9 +432,6 @@
 // Validates CreateSessionLog task does not trigger a Use-After-Free error
 // when SessionLogHandler is destroyed before task is run. See crbug/1328708.
 TEST_F(SessionLogHandlerTest, NoUseAfterFree) {
-  base::test::ScopedFeatureList features;
-  features.InitAndDisableFeature(
-      ash::features::kEnableLogControllerForDiagnosticsApp);
   base::FilePath log_path = temp_dir_.GetPath().AppendASCII("test_path");
   ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory(log_path));
   base::Value::List args;
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
index a94e7d7..391c1eb 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -932,8 +932,7 @@
 }
 
 void ShimlessRmaService::SaveLog(SaveLogCallback callback) {
-  if (features::IsLogControllerForDiagnosticsAppEnabled() &&
-      diagnostics::DiagnosticsLogController::IsInitialized()) {
+  if (diagnostics::DiagnosticsLogController::IsInitialized()) {
     task_runner_->PostTaskAndReplyWithResult(
         FROM_HERE,
         base::BindOnce(
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
index 2eaa4c4..93afbfe 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
@@ -145,10 +145,7 @@
   ~ShimlessRmaServiceTest() override {}
 
   void SetUp() override {
-    scoped_feature_list_.InitWithFeatures(
-        {features::kShimlessRMAOsUpdate,
-         features::kEnableLogControllerForDiagnosticsApp},
-        {});
+    scoped_feature_list_.InitWithFeatures({features::kShimlessRMAOsUpdate}, {});
     chromeos::PowerManagerClient::InitializeFake();
     // VersionUpdater depends on UpdateEngineClient.
     UpdateEngineClient::InitializeFake();
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.h b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.h
index 0a3da04..55e58e79 100644
--- a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.h
+++ b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.h
@@ -284,6 +284,12 @@
      mojom::AcceleratorSubcategory::kGeneralControls,
      /*locked=*/false, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAsh},
+    {AcceleratorAction::kStopScreenRecording,
+     IDS_ASH_ACCELERATOR_DESCRIPTION_STOP_SCREEN_RECORDING,
+     mojom::AcceleratorCategory::kGeneral,
+     mojom::AcceleratorSubcategory::kGeneralControls,
+     /*locked=*/false, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAsh},
     {AcceleratorAction::kLockScreen,
      IDS_ASH_ACCELERATOR_DESCRIPTION_LOCK_SCREEN,
      mojom::AcceleratorCategory::kGeneral,
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_lookup_manager.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_lookup_manager.ts
index 416f430..3acfff5 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_lookup_manager.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_lookup_manager.ts
@@ -6,7 +6,7 @@
 
 import {mojoString16ToString} from './mojo_utils.js';
 import {Accelerator, AcceleratorCategory, AcceleratorId, AcceleratorInfo, AcceleratorSource, AcceleratorState, AcceleratorSubcategory, AcceleratorType, LayoutInfo, LayoutStyle, MojoAcceleratorConfig, MojoAcceleratorInfo, MojoLayoutInfo, StandardAcceleratorInfo, TextAcceleratorInfo} from './shortcut_types.js';
-import {areAcceleratorsEqual, getAccelerator, getAcceleratorId, isStandardAcceleratorInfo, isTextAcceleratorInfo} from './shortcut_utils.js';
+import {areAcceleratorsEqual, getAccelerator, getAcceleratorId, getSourceAndActionFromAcceleratorId, isStandardAcceleratorInfo, isTextAcceleratorInfo} from './shortcut_utils.js';
 
 // Convert from Mojo types to the app types.
 function createSanitizedAccelInfo(info: MojoAcceleratorInfo):
@@ -114,6 +114,10 @@
     return style === LayoutStyle.kDefault;
   }
 
+  isStandardAcceleratorById(id: AcceleratorId): boolean {
+    return this.standardAcceleratorLookup.has(id);
+  }
+
   getAcceleratorLayout(
       category: AcceleratorCategory,
       subCategory: AcceleratorSubcategory): LayoutInfo[] {
@@ -345,6 +349,31 @@
     return accel.locked;
   }
 
+  isCategoryLocked(category: AcceleratorCategory): boolean {
+    const acceleratorIds =
+        this.layoutInfoProvider.getAcceleratorIdsByCategory(category);
+
+    for (const acceleratorId of acceleratorIds) {
+      // Skip TextAccelerators as they are always locked.
+      if (!this.isStandardAcceleratorById(acceleratorId)) {
+        continue;
+      }
+      const {source, action} =
+          getSourceAndActionFromAcceleratorId(acceleratorId);
+      const acceleratorInfos = this.getStandardAcceleratorInfos(source, action);
+
+      for (const acceleratorInfo of acceleratorInfos) {
+        // Return false early when accelerator is editable, which is when
+        // acceleratorInfo is not locked and source is kAsh(Only ash
+        // accelerator is editable).
+        if (!acceleratorInfo.locked && source === AcceleratorSource.kAsh) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
   /**
    * Called to either remove or disable (if locked) an accelerator.
    */
@@ -355,10 +384,8 @@
       return;
     }
 
-    // Split '{source}-{action}` into [source][action].
-    const uuidSplit = uuid.split('-');
-    const source: AcceleratorSource = parseInt(uuidSplit[0], 10);
-    const action = parseInt(uuidSplit[1], 10);
+    // Get source and action from acceleratorId.
+    const {source, action} = getSourceAndActionFromAcceleratorId(uuid);
     const accelInfos = this.getStandardAcceleratorInfos(source, action);
     const foundIdx = this.getAcceleratorInfoIndex(source, action, accelerator);
 
@@ -439,6 +466,8 @@
     Map<AcceleratorCategory, Map<AcceleratorSubcategory, LayoutInfo[]>>;
 type AcceleratorNameLookupMap = Map<AcceleratorId, AcceleratorName>;
 type AcceleratorCategoryLookupMap = Map<AcceleratorId, AcceleratorCategory>;
+type AcceleratorIdsByCategoryLookupMap =
+    Map<AcceleratorCategory, AcceleratorId[]>;
 
 interface LayoutProviderInterface {
   getAcceleratorLayout(
@@ -450,6 +479,7 @@
       AcceleratorName;
   getAcceleratorCategory(source: number|string, action: number|string):
       AcceleratorCategory;
+  getAcceleratorIdsByCategory(category: AcceleratorCategory): AcceleratorId[];
   initializeLayoutInfo(layoutInfoList: MojoLayoutInfo[]): void;
   resetLookupMaps(): void;
 }
@@ -477,6 +507,12 @@
    * the value corresponding to the accelerator's category.
    */
   private acceleratorCategoryLookup: AcceleratorCategoryLookupMap = new Map();
+  /**
+   * A map with the key "category" and the value corresponding to the
+   * accelerators under the category.
+   */
+  private acceleratorIdsByCategoryLookup: AcceleratorIdsByCategoryLookupMap =
+      new Map();
 
   getAcceleratorLayout(
       category: AcceleratorCategory,
@@ -511,6 +547,12 @@
     return acceleratorCategory;
   }
 
+  getAcceleratorIdsByCategory(category: AcceleratorCategory): AcceleratorId[] {
+    const acceleratorIds = this.acceleratorIdsByCategoryLookup.get(category);
+    assert(acceleratorIds);
+    return acceleratorIds;
+  }
+
   initializeLayoutInfo(layoutInfoList: MojoLayoutInfo[]): void {
     this.initializeCategoryMaps(layoutInfoList);
     for (const entry of layoutInfoList) {
@@ -524,10 +566,13 @@
       const layoutInfo = createSanitizedLayoutInfo(entry);
       this.getAcceleratorLayout(entry.category, entry.subCategory)
           .push(layoutInfo);
-      this.addEntrytoAcceleratorCategoryLookup(
-          getAcceleratorId(entry.source, entry.action), entry.category);
-      this.addEntrytoAcceleratorNameLookup(
-          getAcceleratorId(entry.source, entry.action), layoutInfo.description);
+
+      const acceleratorId = getAcceleratorId(entry.source, entry.action);
+      this.addEntryToAcceleratorNameLookup(
+          acceleratorId, layoutInfo.description);
+      this.addEntryToAcceleratorCategoryLookup(acceleratorId, entry.category);
+      this.addEntryToAcceleratorsByCategoryLookup(
+          acceleratorId, entry.category);
     }
   }
 
@@ -544,19 +589,28 @@
     }
   }
 
-  private addEntrytoAcceleratorNameLookup(uuid: string, description: string):
+  private addEntryToAcceleratorNameLookup(uuid: string, description: string):
       void {
     this.acceleratorNameLookup.set(uuid, description);
   }
 
-  private addEntrytoAcceleratorCategoryLookup(
+  private addEntryToAcceleratorCategoryLookup(
       uuid: string, category: AcceleratorCategory): void {
     this.acceleratorCategoryLookup.set(uuid, category);
   }
 
+  private addEntryToAcceleratorsByCategoryLookup(
+      uuid: string, category: AcceleratorCategory): void {
+    const acceleratorIds =
+        this.acceleratorIdsByCategoryLookup.get(category) || [];
+    acceleratorIds.push(uuid);
+    this.acceleratorIdsByCategoryLookup.set(category, acceleratorIds);
+  }
+
   resetLookupMaps(): void {
     this.acceleratorLayoutLookup.clear();
     this.acceleratorNameLookup.clear();
     this.acceleratorCategoryLookup.clear();
+    this.acceleratorIdsByCategoryLookup.clear();
   }
 }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_subsection.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_subsection.ts
index 333e304..ae5ade8e0 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_subsection.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_subsection.ts
@@ -11,7 +11,7 @@
 import {AcceleratorLookupManager} from './accelerator_lookup_manager.js';
 import {getTemplate} from './accelerator_subsection.html.js';
 import {AcceleratorCategory, AcceleratorInfo, AcceleratorState, AcceleratorSubcategory, AcceleratorType, LayoutInfo} from './shortcut_types.js';
-import {compareAcceleratorInfos, getSubcategoryNameStringId, isCategoryLocked, isCustomizationDisabled} from './shortcut_utils.js';
+import {compareAcceleratorInfos, getSubcategoryNameStringId, isCustomizationDisabled} from './shortcut_utils.js';
 
 /**
  * This interface is used to hold all the data needed by an
@@ -154,7 +154,10 @@
   // Show lock icon next to subcategory if customization is enabled and the
   // category is locked.
   private shouldShowLockIcon(): boolean {
-    return !isCustomizationDisabled() && isCategoryLocked(this.category);
+    if (isCustomizationDisabled()) {
+      return false;
+    }
+    return this.lookupManager.isCategoryLocked(this.category);
   }
 }
 
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts
index cb15ba3..e5de72b 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts
@@ -19,7 +19,7 @@
 import {mojoString16ToString} from './mojo_utils.js';
 import {ModifierKeyCodes} from './shortcut_input.js';
 import {Accelerator, AcceleratorConfigResult, AcceleratorSource, Modifier, ShortcutProviderInterface, StandardAcceleratorInfo} from './shortcut_types.js';
-import {areAcceleratorsEqual, createEmptyAcceleratorInfo, getAccelerator, getModifiersForAcceleratorInfo, isCategoryLocked, isCustomizationDisabled, isFunctionKey} from './shortcut_utils.js';
+import {areAcceleratorsEqual, createEmptyAcceleratorInfo, getAccelerator, getModifiersForAcceleratorInfo, isCustomizationDisabled, isFunctionKey} from './shortcut_utils.js';
 
 export interface AcceleratorViewElement {
   $: {
@@ -130,6 +130,7 @@
   source: AcceleratorSource;
   sourceIsLocked: boolean;
   showEditIcon: boolean;
+  categoryIsLocked: boolean;
   protected pendingAcceleratorInfo: StandardAcceleratorInfo;
   private modifiers: string[];
   private acceleratorOnHold: string;
@@ -138,6 +139,13 @@
   private lookupManager: AcceleratorLookupManager =
       AcceleratorLookupManager.getInstance();
 
+  override connectedCallback(): void {
+    super.connectedCallback();
+
+    this.categoryIsLocked = this.lookupManager.isCategoryLocked(
+        this.lookupManager.getAcceleratorCategory(this.source, this.action));
+  }
+
   private getModifiers(): string[] {
     return getModifiersForAcceleratorInfo(this.acceleratorInfo);
   }
@@ -451,25 +459,22 @@
   private shouldShowLockIcon(): boolean {
     // Do not show lock icon in each row if customization is disabled or its
     // category is locked.
-    if (isCustomizationDisabled() ||
-        isCategoryLocked(this.lookupManager.getAcceleratorCategory(
-            this.source, this.action))) {
+    if (isCustomizationDisabled() || this.categoryIsLocked) {
       return false;
     }
-
+    // Show lock icon if accelerator is locked.
     return (this.acceleratorInfo && this.acceleratorInfo.locked) ||
         this.sourceIsLocked;
   }
 
   private shouldShowEditIcon(): boolean {
-    // Do not show edit icon in each row if customization is disabled, category
-    // is locked, or the row is displayed in edit-dialog.
+    // Do not show edit icon in each row if customization is disabled, the row
+    // is displayed in edit-dialog(!showEditIcon) or category is locked.
     if (isCustomizationDisabled() || !this.showEditIcon ||
-        isCategoryLocked(this.lookupManager.getAcceleratorCategory(
-            this.source, this.action))) {
+        this.categoryIsLocked) {
       return false;
     }
-
+    // Show edit icon if accelerator is not locked.
     return !(this.acceleratorInfo && this.acceleratorInfo.locked) &&
         !this.sourceIsLocked;
   }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts b/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts
index 5079b847..e173432 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts
@@ -7,7 +7,7 @@
 import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js';
 import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
 
-import {Accelerator, AcceleratorCategory, AcceleratorId, AcceleratorInfo, AcceleratorState, AcceleratorSubcategory, AcceleratorType, Modifier, MojoAcceleratorInfo, MojoSearchResult, StandardAcceleratorInfo, TextAcceleratorInfo} from './shortcut_types.js';
+import {Accelerator, AcceleratorCategory, AcceleratorId, AcceleratorInfo, AcceleratorSource, AcceleratorState, AcceleratorSubcategory, AcceleratorType, Modifier, MojoAcceleratorInfo, MojoSearchResult, StandardAcceleratorInfo, TextAcceleratorInfo} from './shortcut_types.js';
 
 // TODO(jimmyxgong): ChromeOS currently supports up to F24 but can be updated to
 // F32. Update here when F32 is available.
@@ -250,11 +250,12 @@
   return keycode >= kF11 && keycode <= kF24;
 };
 
-// TODO(longbowei): Update to dynamically check if all shortcuts within a
-// category are locked instead of hardcoding specific categories.
-export const isCategoryLocked = (category: AcceleratorCategory): boolean => {
-  return (
-      category === AcceleratorCategory.kBrowser ||
-      category === AcceleratorCategory.kText ||
-      category === AcceleratorCategory.kAccessibility);
-};
+export const getSourceAndActionFromAcceleratorId =
+    (uuid: AcceleratorId): {source: number, action: number} => {
+      // Split '{source}-{action}` into [source][action].
+      const uuidSplit = uuid.split('-');
+      const source: AcceleratorSource = parseInt(uuidSplit[0], 10);
+      const action = parseInt(uuidSplit[1], 10);
+
+      return {source, action};
+    };
diff --git a/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.ts b/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.ts
index 209cf97c..fb54228b 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.ts
@@ -14,7 +14,7 @@
 import {InputKeyElement, KeyInputState} from './input_key.js';
 import {mojoString16ToString} from './mojo_utils.js';
 import {AcceleratorSource, TextAcceleratorInfo, TextAcceleratorPart, TextAcceleratorPartType} from './shortcut_types.js';
-import {isCategoryLocked, isCustomizationDisabled, isTextAcceleratorInfo} from './shortcut_utils.js';
+import {isCustomizationDisabled, isTextAcceleratorInfo} from './shortcut_utils.js';
 import {getTemplate} from './text_accelerator.html.js';
 
 /**
@@ -145,9 +145,11 @@
   private shouldShowLockIcon(): boolean {
     // Show lock icon in each row if customization is enabled and its
     // category is not locked.
-    return !isCustomizationDisabled() &&
-        !isCategoryLocked(this.lookupManager.getAcceleratorCategory(
-            this.source, this.action));
+    if (isCustomizationDisabled()) {
+      return false;
+    }
+    return !this.lookupManager.isCategoryLocked(
+        this.lookupManager.getAcceleratorCategory(this.source, this.action));
   }
 
   private areAllPartsTextParts(): boolean {
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc
index 28c4c17..1413fdc 100644
--- a/ash/wm/overview/overview_controller.cc
+++ b/ash/wm/overview/overview_controller.cc
@@ -484,8 +484,7 @@
   return session_controller->GetSessionState() ==
              session_manager::SessionState::ACTIVE &&
          !Shell::IsSystemModalWindowOpen() &&
-         !Shell::Get()->screen_pinning_controller()->IsPinned() &&
-         !session_controller->IsRunningInAppMode();
+         !Shell::Get()->screen_pinning_controller()->IsPinned();
 }
 
 bool OverviewController::CanEndOverview(OverviewEnterExitType type) {
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc
index 07c0ef98..2239289 100644
--- a/ash/wm/overview/overview_item.cc
+++ b/ash/wm/overview/overview_item.cc
@@ -235,13 +235,6 @@
 
   // `item_widget_` may be null during shutdown if the window is minimized.
   if (item_widget_) {
-    // When a template is being launched, this overview item will be hidden
-    // first so that the library widget fade out animation can take place. Once
-    // the fade out animation is done, the hide will be reverted. Here we need
-    // to make sure header and shadow are sync'ed with the item window.
-    UpdateHeaderLayout(OVERVIEW_ANIMATION_NONE);
-    UpdateRoundedCornersAndShadow();
-
     PerformFadeInLayer(item_widget_->GetLayer(), animate);
   }
 
@@ -397,11 +390,8 @@
   // header.
   if (!transform_window_.IsMinimized()) {
     SetItemBounds(target_bounds, new_animation_type, is_first_update);
-    // Update header only when the overview item window is visible.
-    if (GetWindow()->IsVisible()) {
-      UpdateHeaderLayout(is_first_update ? OVERVIEW_ANIMATION_NONE
-                                         : new_animation_type);
-    }
+    UpdateHeaderLayout(is_first_update ? OVERVIEW_ANIMATION_NONE
+                                       : new_animation_type);
     return;
   }
 
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc
index f885768..d4a8df4 100644
--- a/ash/wm/overview/overview_session.cc
+++ b/ash/wm/overview/overview_session.cc
@@ -176,7 +176,7 @@
     tablet_mode_observation_.Observe(Shell::Get()->tablet_mode_controller());
     hide_windows_for_saved_desks_grid_ =
         std::make_unique<ScopedOverviewHideWindows>(
-            /*windows=*/std::vector<aura::Window*>({}), /*forced_hidden=*/true);
+            /*windows=*/std::vector<aura::Window*>{}, /*forced_hidden=*/true);
   }
 
   hide_overview_windows_ = std::make_unique<ScopedOverviewHideWindows>(
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 4925a75..a2f4d91b 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -205,6 +205,18 @@
   flags = [ "ENABLE_MESSAGE_PUMP_EPOLL=$enable_message_pump_epoll" ]
 }
 
+if (is_apple) {
+  # TODO(https://crbug.com/1280317): Merge back into the `base` target once all
+  # .mm files are ARCed.
+  source_set("base_arc") {
+    sources = [
+      "apple/owned_objc.h",
+      "apple/owned_objc.mm",
+    ]
+    configs += [ "//build/config/compiler:enable_arc" ]
+  }
+}
+
 # Base and everything it depends on should be a static library rather than
 # a source set. Base is more of a "library" in the classic sense in that many
 # small parts of it are used in many different contexts. This combined with a
@@ -2092,6 +2104,7 @@
       "time/time_mac.mm",
     ]
     frameworks += [ "Security.framework" ]
+    public_deps += [ ":base_arc" ]
   }
 
   # Linux.
diff --git a/base/allocator/partition_allocator/pointers/raw_ptr.h b/base/allocator/partition_allocator/pointers/raw_ptr.h
index 344d71f..6ad9c9c 100644
--- a/base/allocator/partition_allocator/pointers/raw_ptr.h
+++ b/base/allocator/partition_allocator/pointers/raw_ptr.h
@@ -551,6 +551,8 @@
 class PA_TRIVIAL_ABI PA_GSL_POINTER raw_ptr {
  public:
   using Impl = typename raw_ptr_traits::TraitsToImpl<Traits>::Impl;
+  // Needed to make gtest Pointee matcher work with raw_ptr.
+  using element_type = T;
 
 #if !BUILDFLAG(USE_PARTITION_ALLOC)
   // See comment at top about `PA_RAW_PTR_CHECK()`.
diff --git a/base/allocator/partition_allocator/starscan/state_bitmap.h b/base/allocator/partition_allocator/starscan/state_bitmap.h
index cfd7b08..b9cec60 100644
--- a/base/allocator/partition_allocator/starscan/state_bitmap.h
+++ b/base/allocator/partition_allocator/starscan/state_bitmap.h
@@ -347,7 +347,7 @@
 template <size_t PageSize, size_t PageAlignment, size_t AllocationAlignment>
 bool StateBitmap<PageSize, PageAlignment, AllocationAlignment>::
     FilterQuarantine::operator()(CellType bits) const {
-  return __builtin_popcount(bits) == 1;
+  return __builtin_popcount(static_cast<unsigned>(bits)) == 1;
 }
 
 template <size_t PageSize, size_t PageAlignment, size_t AllocationAlignment>
diff --git a/base/allocator/partition_allocator/thread_cache_unittest.cc b/base/allocator/partition_allocator/thread_cache_unittest.cc
index adbf6a6..c6fbe72 100644
--- a/base/allocator/partition_allocator/thread_cache_unittest.cc
+++ b/base/allocator/partition_allocator/thread_cache_unittest.cc
@@ -502,11 +502,17 @@
   auto* parent_thread_tcache = root()->thread_cache_for_testing();
   ASSERT_TRUE(parent_thread_tcache);
 
+#if !BUILDFLAG(IS_APPLE) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
+  // iOS and MacOS 15 create worker threads internally(start_wqthread).
+  // So thread caches are created for the worker threads, because the threads
+  // allocate memory for initialization (_dispatch_calloc is invoked).
+  // We cannot assume that there is only 1 thread cache here.
   {
     internal::ScopedGuard lock(ThreadCacheRegistry::GetLock());
     EXPECT_EQ(parent_thread_tcache->prev_, nullptr);
     EXPECT_EQ(parent_thread_tcache->next_, nullptr);
   }
+#endif
 
   ThreadDelegateForThreadCacheRegistry delegate(parent_thread_tcache, root(),
                                                 GetParam());
@@ -516,9 +522,11 @@
                                                    &thread_handle);
   internal::base::PlatformThreadForTesting::Join(thread_handle);
 
+#if !BUILDFLAG(IS_APPLE) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
   internal::ScopedGuard lock(ThreadCacheRegistry::GetLock());
   EXPECT_EQ(parent_thread_tcache->prev_, nullptr);
   EXPECT_EQ(parent_thread_tcache->next_, nullptr);
+#endif
 }
 
 #if PA_CONFIG(THREAD_CACHE_ENABLE_STATISTICS)
@@ -577,10 +585,12 @@
  public:
   ThreadDelegateForMultipleThreadCachesAccounting(
       ThreadSafePartitionRoot* root,
+      const ThreadCacheStats& wqthread_stats,
       int alloc_count,
       BucketDistribution bucket_distribution)
       : root_(root),
         bucket_distribution_(bucket_distribution),
+        wqthread_stats_(wqthread_stats),
         alloc_count_(alloc_count) {}
 
   void ThreadMain() override {
@@ -593,30 +603,50 @@
     // 2* for this thread and the parent one.
     EXPECT_EQ(
         2 * root_->buckets[bucket_index].slot_size * kFillCountForMediumBucket,
-        stats.bucket_total_memory);
-    EXPECT_EQ(2 * sizeof(ThreadCache), stats.metadata_overhead);
+        stats.bucket_total_memory - wqthread_stats_.bucket_total_memory);
+    EXPECT_EQ(2 * sizeof(ThreadCache),
+              stats.metadata_overhead - wqthread_stats_.metadata_overhead);
 
     ThreadCacheStats this_thread_cache_stats{};
     root_->thread_cache_for_testing()->AccumulateStats(
         &this_thread_cache_stats);
     EXPECT_EQ(alloc_count_ + this_thread_cache_stats.alloc_count,
-              stats.alloc_count);
+              stats.alloc_count - wqthread_stats_.alloc_count);
   }
 
  private:
   ThreadSafePartitionRoot* root_ = nullptr;
   BucketDistribution bucket_distribution_;
+  const ThreadCacheStats wqthread_stats_;
   const int alloc_count_;
 };
 
 }  // namespace
 
 TEST_P(PartitionAllocThreadCacheTest, MultipleThreadCachesAccounting) {
+  ThreadCacheStats wqthread_stats{0};
+#if BUILDFLAG(IS_APPLE) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
+  {
+    // iOS and MacOS 15 create worker threads internally(start_wqthread).
+    // So thread caches are created for the worker threads, because the threads
+    // allocate memory for initialization (_dispatch_calloc is invoked).
+    // We need to count worker threads created by iOS and Mac system.
+    ThreadCacheRegistry::Instance().DumpStats(false, &wqthread_stats);
+
+    // Remove this thread's thread cache stats from wqthread_stats.
+    ThreadCacheStats this_stats;
+    ThreadCacheRegistry::Instance().DumpStats(true, &this_stats);
+
+    wqthread_stats.alloc_count -= this_stats.alloc_count;
+    wqthread_stats.metadata_overhead -= this_stats.metadata_overhead;
+    wqthread_stats.bucket_total_memory -= this_stats.bucket_total_memory;
+  }
+#endif
   FillThreadCacheAndReturnIndex(kMediumSize);
   uint64_t alloc_count = root()->thread_cache_for_testing()->stats_.alloc_count;
 
-  ThreadDelegateForMultipleThreadCachesAccounting delegate(root(), alloc_count,
-                                                           GetParam());
+  ThreadDelegateForMultipleThreadCachesAccounting delegate(
+      root(), wqthread_stats, alloc_count, GetParam());
 
   internal::base::PlatformThreadHandle thread_handle;
   internal::base::PlatformThreadForTesting::Create(0, &delegate,
diff --git a/base/apple/owned_objc.h b/base/apple/owned_objc.h
new file mode 100644
index 0000000..852199b8
--- /dev/null
+++ b/base/apple/owned_objc.h
@@ -0,0 +1,70 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_APPLE_OWNED_OBJC_H_
+#define BASE_APPLE_OWNED_OBJC_H_
+
+#include <memory>
+
+#include "build/build_config.h"
+
+// This file defines wrappers to allow C++ code to own Objective-C objects
+// without being Objective-C++ code themselves. These should not be used for
+// pure Objective-C++ code, in which the underlying Objective-C types should be
+// used, nor should they be used for the case where the pimpl idiom would work
+// (https://chromium.googlesource.com/chromium/src/+/main/docs/mac/mixing_cpp_and_objc.md).
+
+#if __OBJC__
+
+#define GENERATE_OWNED_OBJC_TYPE(name) @class name;
+#define GENERATE_OWNED_OBJC_PROTOCOL(name) @protocol name;
+#include "base/apple/owned_objc_types.h"
+#undef GENERATE_OWNED_OBJC_TYPE
+#undef GENERATE_OWNED_OBJC_PROTOCOL
+
+#endif  // __OBJC__
+
+// Define this class two ways: the full-fledged way that allows Objective-C code
+// to fully construct and access the inner Objective-C object, and a
+// C++-compatible way that does not expose any Objective-C code and only allows
+// default construction and validity checking.
+#if __OBJC__
+#define OWNED_TYPE_DECL_OBJC_ADDITIONS(name, objctype) \
+  explicit Owned##name(objctype obj);                  \
+  objctype Get() const;
+#else
+#define OWNED_TYPE_DECL_OBJC_ADDITIONS(name, objctype)
+#endif  // __OBJC__
+
+#define OWNED_OBJC_DECL(name, objctype)                      \
+  namespace base::apple {                                    \
+  class Owned##name {                                        \
+   public:                                                   \
+    /* Default-construct in a null state. */                 \
+    Owned##name();                                           \
+    ~Owned##name();                                          \
+    Owned##name(const Owned##name&);                         \
+    Owned##name& operator=(const Owned##name&);              \
+    /* Returns whether the object contains a valid object.*/ \
+    bool IsValid() const;                                    \
+    /* Objective-C-only constructor and getter. */           \
+    OWNED_TYPE_DECL_OBJC_ADDITIONS(name, objctype)           \
+                                                             \
+   private:                                                  \
+    struct ObjCStorage;                                      \
+    std::unique_ptr<ObjCStorage> objc_storage_;              \
+  };                                                         \
+  }  // namespace base::apple
+
+#define GENERATE_OWNED_OBJC_TYPE(name) OWNED_OBJC_DECL(name, name*)
+#define GENERATE_OWNED_OBJC_PROTOCOL(name) OWNED_OBJC_DECL(name, id<name>)
+
+#include "base/apple/owned_objc_types.h"
+
+#undef GENERATE_OWNED_OBJC_TYPE
+#undef GENERATE_OWNED_OBJC_PROTOCOL
+#undef OWNED_OBJC_DECL
+#undef OWNED_TYPE_DECL_OBJC_ADDITIONS
+
+#endif  // BASE_APPLE_OWNED_OBJC_H_
diff --git a/base/apple/owned_objc.mm b/base/apple/owned_objc.mm
new file mode 100644
index 0000000..f919df9
--- /dev/null
+++ b/base/apple/owned_objc.mm
@@ -0,0 +1,48 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/apple/owned_objc.h"
+
+#include <MacTypes.h>  // For nil, to avoid having to bring in frameworks.
+
+#include "build/build_config.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+#define OWNED_OBJC_IMPL(name, objctype)                                \
+  namespace base::apple {                                              \
+  struct Owned##name::ObjCStorage {                                    \
+    objctype __strong obj;                                             \
+  };                                                                   \
+  Owned##name::Owned##name()                                           \
+      : objc_storage_(std::make_unique<ObjCStorage>()) {}              \
+  Owned##name::~Owned##name() = default;                               \
+  Owned##name::Owned##name(objctype obj) : Owned##name() {             \
+    objc_storage_->obj = obj;                                          \
+  }                                                                    \
+  Owned##name::Owned##name(const Owned##name& other) : Owned##name() { \
+    objc_storage_->obj = other.objc_storage_->obj;                     \
+  }                                                                    \
+  Owned##name& Owned##name::operator=(const Owned##name& other) {      \
+    objc_storage_->obj = other.objc_storage_->obj;                     \
+    return *this;                                                      \
+  }                                                                    \
+  bool Owned##name::IsValid() const {                                  \
+    return objc_storage_->obj != nil;                                  \
+  }                                                                    \
+  objctype Owned##name::Get() const {                                  \
+    return objc_storage_->obj;                                         \
+  }                                                                    \
+  }  // namespace base::apple
+
+#define GENERATE_OWNED_OBJC_TYPE(name) OWNED_OBJC_IMPL(name, name*)
+#define GENERATE_OWNED_OBJC_PROTOCOL(name) OWNED_OBJC_IMPL(name, id<name>)
+
+#include "base/apple/owned_objc_types.h"
+
+#undef GENERATE_OWNED_OBJC_TYPE
+#undef GENERATE_OWNED_OBJC_PROTOCOL
+#undef OWNED_OBJC_IMPL
diff --git a/base/apple/owned_objc_types.h b/base/apple/owned_objc_types.h
new file mode 100644
index 0000000..68be95d
--- /dev/null
+++ b/base/apple/owned_objc_types.h
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file intentionally does not have header guards; it's included inside
+// macros to generate classes. The following lines silence a presubmit and
+// Tricium warning that would otherwise be triggered by this:
+//
+// no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
+
+#if !defined(BASE_APPLE_OWNED_OBJC_H_)
+#error Please #include "base/apple/owned_objc.h" instead of this file
+#endif
+
+#if BUILDFLAG(IS_MAC)
+GENERATE_OWNED_OBJC_TYPE(NSEvent)
+#elif BUILDFLAG(IS_IOS)
+GENERATE_OWNED_OBJC_TYPE(UIEvent)
+#endif
+GENERATE_OWNED_OBJC_PROTOCOL(MTLDevice)
+GENERATE_OWNED_OBJC_PROTOCOL(MTLSharedEvent)
diff --git a/base/profiler/unwinder.h b/base/profiler/unwinder.h
index 107fcf4..a0fbf7ef 100644
--- a/base/profiler/unwinder.h
+++ b/base/profiler/unwinder.h
@@ -8,7 +8,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_ptr.h"
 #include "base/profiler/frame.h"
 #include "base/profiler/module_cache.h"
 #include "base/profiler/register_context.h"
@@ -91,9 +91,7 @@
   ModuleCache* module_cache() const { return module_cache_; }
 
  private:
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #constexpr-ctor-field-initializer
-  RAW_PTR_EXCLUSION ModuleCache* module_cache_ = nullptr;
+  raw_ptr<ModuleCache> module_cache_ = nullptr;
 };
 
 }  // namespace base
diff --git a/base/task/sequence_manager/time_domain.h b/base/task/sequence_manager/time_domain.h
index 599a69d..8fe3ae1 100644
--- a/base/task/sequence_manager/time_domain.h
+++ b/base/task/sequence_manager/time_domain.h
@@ -7,7 +7,7 @@
 
 #include "base/base_export.h"
 #include "base/check.h"
-#include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_ptr.h"
 #include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/tasks.h"
 #include "base/time/tick_clock.h"
@@ -59,10 +59,7 @@
  private:
   friend class internal::SequenceManagerImpl;
 
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #constexpr-ctor-field-initializer
-  RAW_PTR_EXCLUSION internal::SequenceManagerImpl* sequence_manager_ =
-      nullptr;  // Not owned.
+  raw_ptr<internal::SequenceManagerImpl> sequence_manager_ = nullptr;
 };
 
 }  // namespace sequence_manager
diff --git a/base/test/power_monitor_test.h b/base/test/power_monitor_test.h
index 71c71c91..fd5785b 100644
--- a/base/test/power_monitor_test.h
+++ b/base/test/power_monitor_test.h
@@ -5,7 +5,7 @@
 #ifndef BASE_TEST_POWER_MONITOR_TEST_H_
 #define BASE_TEST_POWER_MONITOR_TEST_H_
 
-#include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_ptr.h"
 #include "base/power_monitor/power_monitor.h"
 #include "base/power_monitor/power_monitor_source.h"
 #include "base/power_monitor/power_observer.h"
@@ -54,10 +54,7 @@
 
  private:
   // Owned by PowerMonitor.
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #union
-  RAW_PTR_EXCLUSION PowerMonitorTestSource* power_monitor_test_source_ =
-      nullptr;
+  raw_ptr<PowerMonitorTestSource> power_monitor_test_source_ = nullptr;
 };
 
 class PowerMonitorTestObserver : public PowerSuspendObserver,
diff --git a/base/test/scoped_run_loop_timeout.h b/base/test/scoped_run_loop_timeout.h
index 46b88e09..ae80a78 100644
--- a/base/test/scoped_run_loop_timeout.h
+++ b/base/test/scoped_run_loop_timeout.h
@@ -11,7 +11,6 @@
 #include "base/gtest_prod_util.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
-#include "base/memory/raw_ptr_exclusion.h"
 #include "base/run_loop.h"
 #include "base/time/time.h"
 
@@ -88,9 +87,7 @@
   // Exposes the RunLoopTimeout to the friend tests (see above).
   static const RunLoop::RunLoopTimeout* GetTimeoutForCurrentThread();
 
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #union
-  RAW_PTR_EXCLUSION const RunLoop::RunLoopTimeout* const nested_timeout_;
+  raw_ptr<const RunLoop::RunLoopTimeout> const nested_timeout_;
   RunLoop::RunLoopTimeout run_timeout_;
 };
 
diff --git a/base/test/task_environment.h b/base/test/task_environment.h
index 322290f..b5ed0f9c 100644
--- a/base/test/task_environment.h
+++ b/base/test/task_environment.h
@@ -9,7 +9,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/functional/callback_forward.h"
-#include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/observer_list_types.h"
 #include "base/run_loop.h"
@@ -504,9 +504,7 @@
 #endif
 
   // Owned by the ThreadPoolInstance.
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #union
-  RAW_PTR_EXCLUSION TestTaskTracker* task_tracker_ = nullptr;
+  raw_ptr<TestTaskTracker> task_tracker_ = nullptr;
 
   // Ensures destruction of lazy TaskRunners when this is destroyed.
   std::unique_ptr<base::internal::ScopedLazyTaskRunnerListForTesting>
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc
index e323e70..58fb2f7a 100644
--- a/base/test/test_suite.cc
+++ b/base/test/test_suite.cc
@@ -26,7 +26,7 @@
 #include "base/i18n/rtl.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
-#include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_ptr.h"
 #include "base/no_destructor.h"
 #include "base/path_service.h"
 #include "base/process/launch.h"
@@ -225,18 +225,10 @@
   }
 
  private:
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #constexpr-ctor-field-initializer
-  RAW_PTR_EXCLUSION FeatureList* feature_list_set_before_test_ = nullptr;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #constexpr-ctor-field-initializer
-  RAW_PTR_EXCLUSION FeatureList* feature_list_set_before_case_ = nullptr;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #constexpr-ctor-field-initializer
-  RAW_PTR_EXCLUSION ThreadPoolInstance* thread_pool_set_before_test_ = nullptr;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #constexpr-ctor-field-initializer
-  RAW_PTR_EXCLUSION ThreadPoolInstance* thread_pool_set_before_case_ = nullptr;
+  raw_ptr<FeatureList> feature_list_set_before_test_ = nullptr;
+  raw_ptr<FeatureList> feature_list_set_before_case_ = nullptr;
+  raw_ptr<ThreadPoolInstance> thread_pool_set_before_test_ = nullptr;
+  raw_ptr<ThreadPoolInstance> thread_pool_set_before_case_ = nullptr;
 };
 
 // iOS: base::Process is not available.
diff --git a/base/threading/hang_watcher.h b/base/threading/hang_watcher.h
index 4edf4284..470f627b 100644
--- a/base/threading/hang_watcher.h
+++ b/base/threading/hang_watcher.h
@@ -24,7 +24,6 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/memory/raw_ptr.h"
-#include "base/memory/raw_ptr_exclusion.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/template_util.h"
@@ -99,9 +98,7 @@
 
 #if DCHECK_IS_ON()
   // The previous WatchHangsInScope created on this thread.
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #union
-  RAW_PTR_EXCLUSION WatchHangsInScope* previous_watch_hangs_in_scope_;
+  raw_ptr<WatchHangsInScope> previous_watch_hangs_in_scope_;
 #endif
 };
 
diff --git a/base/threading/thread.h b/base/threading/thread.h
index 06dd7028..2990ee4 100644
--- a/base/threading/thread.h
+++ b/base/threading/thread.h
@@ -13,7 +13,7 @@
 #include "base/base_export.h"
 #include "base/check.h"
 #include "base/functional/callback.h"
-#include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_ptr.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/message_loop/timer_slack.h"
 #include "base/sequence_checker.h"
@@ -322,9 +322,8 @@
   // The thread's Delegate and RunLoop are valid only while the thread is
   // alive. Set by the created thread.
   std::unique_ptr<Delegate> delegate_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #union
-  RAW_PTR_EXCLUSION RunLoop* run_loop_ = nullptr;
+
+  raw_ptr<RunLoop> run_loop_ = nullptr;
 
   // Stores Options::timer_slack_ until the sequence manager has been bound to
   // a thread.
diff --git a/base/types/optional_ref.h b/base/types/optional_ref.h
index 8ba1ea8..1d69f354 100644
--- a/base/types/optional_ref.h
+++ b/base/types/optional_ref.h
@@ -9,7 +9,7 @@
 #include <type_traits>
 
 #include "base/check.h"
-#include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_ptr.h"
 #include "third_party/abseil-cpp/absl/base/attributes.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -184,9 +184,7 @@
   }
 
  private:
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #constexpr-ctor-field-initializer
-  RAW_PTR_EXCLUSION T* const ptr_ = nullptr;
+  raw_ptr<T> const ptr_ = nullptr;
 };
 
 template <typename T>
diff --git a/base/win/com_init_util.cc b/base/win/com_init_util.cc
index b7b973c..9867c15 100644
--- a/base/win/com_init_util.cc
+++ b/base/win/com_init_util.cc
@@ -4,11 +4,11 @@
 
 #include "base/win/com_init_util.h"
 
+#include <stdint.h>
 #include <windows.h>
-
 #include <winternl.h>
+
 #include "base/logging.h"
-#include "base/memory/raw_ptr_exclusion.h"
 #include "base/notreached.h"
 
 namespace base {
@@ -28,12 +28,8 @@
     MTA = 0x140,
   };
 
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #reinterpret-cast-trivial-type
-  RAW_PTR_EXCLUSION void* thread_base;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #reinterpret-cast-trivial-type
-  RAW_PTR_EXCLUSION void* sm_allocator;
+  uintptr_t thread_base;
+  uintptr_t sm_allocator;
   DWORD apartment_id;
   DWORD apartment_flags;
   // There are many more fields than this, but for our purposes, we only care
diff --git a/base/win/scoped_safearray.h b/base/win/scoped_safearray.h
index d83fdf99..ab604ff 100644
--- a/base/win/scoped_safearray.h
+++ b/base/win/scoped_safearray.h
@@ -107,8 +107,9 @@
       array_size_ = 0U;
     }
 
-    // This field is not a raw_ptr<> because it was filtered by the rewriter
-    // for: #union
+    // Cannot rewrite this pointer to raw_ptr<>, because this pointer
+    // comes from the operating system and may have been laundered
+    // if rewritten it may generate incorrect DPD error.
     RAW_PTR_EXCLUSION SAFEARRAY* safearray_ = nullptr;
     VARTYPE vartype_ = VT_EMPTY;
     pointer array_ = nullptr;
diff --git a/build/android/gyp/bytecode_processor.py b/build/android/gyp/bytecode_processor.py
index cc0a4c73..868f31b 100755
--- a/build/android/gyp/bytecode_processor.py
+++ b/build/android/gyp/bytecode_processor.py
@@ -56,6 +56,19 @@
   return dep_graph
 
 
+def _GnTargetToBuildFilePath(gn_target: str):
+  """Returns the relative BUILD.gn file path for this target from src root."""
+  assert gn_target.startswith('//'), f'Relative {gn_target} name not supported.'
+  ninja_target_name = gn_target[2:]
+
+  # Remove the colon at the end
+  colon_index = ninja_target_name.find(':')
+  if colon_index != -1:
+    ninja_target_name = ninja_target_name[:colon_index]
+
+  return os.path.join(ninja_target_name, 'BUILD.gn')
+
+
 def _EnsureDirectClasspathIsComplete(*, input_jar: str, gn_target: str,
                                      output_dir: str,
                                      direct_classpath_jars: List[str],
@@ -81,7 +94,7 @@
 
   transitive_deps = full_classpath_deps - direct_classpath_deps
 
-  missing_targets: Dict[str, Dict[str, str]] = collections.defaultdict(dict)
+  missing_targets: Dict[tuple, Dict[str, str]] = collections.defaultdict(dict)
   dep_graph = _ParseDepGraph(input_jar, output_dir)
   logging.info('Finding missing deps from %d classes', len(dep_graph))
   # dep_graph.keys() is a list of all the classes in the current input_jar. Skip
@@ -94,21 +107,29 @@
         continue
       seen_deps.add(dep_to)
       if dep_to in transitive_deps:
-        missing_target_names = sorted(dep_to_target[dep_to])
-        if len(missing_target_names) == 1:
-          missing_target_key = tuple(missing_target_names)[0]
-        else:
-          missing_target_key = f'One of {", ".join(missing_target_names)}'
-        missing_targets[missing_target_key][dep_to] = dep_from
+        missing_target_names = tuple(sorted(dep_to_target[dep_to]))
+        missing_targets[missing_target_names][dep_to] = dep_from
 
   if missing_targets:
     print('=' * 30 + ' Dependency Checks Failed ' + '=' * 30)
     print(f'Target: {gn_target}')
     print('Direct classpath is incomplete. To fix, add deps on:')
-    for missing_target_key, data in missing_targets.items():
-      print(f' * {missing_target_key}')
+    for missing_target_names, data in missing_targets.items():
+      if len(missing_target_names) > 1:
+        print(f' * One of {", ".join(missing_target_names)}')
+      else:
+        print(f' * {missing_target_names[0]}')
       for missing_class, used_by in data.items():
         print(f'     ** {missing_class} (needed by {used_by})')
+    if os.environ.get('AUTO_ADD_MISSING_DEPS') == '1':
+      cmd = [
+          'tools/android/modularization/gn/dep_operations.py', 'add', '--quiet',
+          '--file',
+          _GnTargetToBuildFilePath(gn_target), '--target', gn_target, '--deps'
+      ]
+      # For simplicity, always pick the first suggested target.
+      cmd += [names[0] for names in missing_targets.keys()]
+      build_utils.CheckOutput(cmd, cwd=build_utils.DIR_SOURCE_ROOT)
     if warnings_as_errors:
       sys.exit(1)
 
@@ -119,6 +140,7 @@
 
 
 def main(argv):
+  build_utils.InitLogging('BYTECODE_PROCESSOR_DEBUG')
   argv = build_utils.ExpandFileArgs(argv[1:])
   parser = argparse.ArgumentParser()
   parser.add_argument('--target-name', help='Fully qualified GN target name.')
diff --git a/build/chromeos/test_runner.py b/build/chromeos/test_runner.py
index 14c31e1..d4c1d23 100755
--- a/build/chromeos/test_runner.py
+++ b/build/chromeos/test_runner.py
@@ -399,6 +399,9 @@
         # inside as an RDB 'artifact'. (This could include system logs, screen
         # shots, etc.)
         artifacts = self.get_artifacts(test['outDir'])
+        html_artifact = debug_link
+        if result == base_test_result.ResultType.SKIP:
+          html_artifact = 'Test was skipped because: ' + test['skipReason']
         self._rdb_client.Post(
             test['name'],
             result,
@@ -407,7 +410,7 @@
             None,
             artifacts=artifacts,
             failure_reason=primary_error_message,
-            html_artifact=debug_link)
+            html_artifact=html_artifact)
 
     if self._rdb_client and self._logs_dir:
       # Attach artifacts from the device that don't apply to a single test.
diff --git a/build/config/fuchsia/test/README.md b/build/config/fuchsia/test/README.md
index d21cdb7..563dc26 100644
--- a/build/config/fuchsia/test/README.md
+++ b/build/config/fuchsia/test/README.md
@@ -9,7 +9,7 @@
 ### General Purpose Fragments
 
 #### archivist.shard.test-cml
-Runs an `archivist-without-attribution` with custom protocol routing for tests
+Runs an `archivist-for-embedding` with custom protocol routing for tests
 that want to intercept events written to a `LogSink` by a component.
 
 #### chromium_test_facet.shard.test-cml
diff --git a/build/config/fuchsia/test/archivist.shard.test-cml b/build/config/fuchsia/test/archivist.shard.test-cml
index b85162f..1e014a0 100644
--- a/build/config/fuchsia/test/archivist.shard.test-cml
+++ b/build/config/fuchsia/test/archivist.shard.test-cml
@@ -5,7 +5,7 @@
   children: [
     {
       name: "isolated_archivist",
-      url: "fuchsia-pkg://fuchsia.com/archivist-without-attribution#meta/archivist-without-attribution.cm",
+      url: "fuchsia-pkg://fuchsia.com/archivist-for-embedding#meta/archivist-for-embedding.cm",
     },
   ],
   use: [
@@ -20,9 +20,24 @@
       from: "#isolated_archivist",
     },
   ],
+  offer: [
+    {
+      event_stream: [
+        "capability_requested",
+        "directory_ready",
+      ],
+      from: "parent",
+      to: "#isolated_archivist",
+    },
+    {
+      protocol: "fuchsia.logger.LogSink",
+      from: "parent",
+      to: "#isolated_archivist",
+    },
+  ],
   facets: {
     "fuchsia.test": {
-        "deprecated-allowed-packages": [ "archivist-without-attribution" ],
+        "deprecated-allowed-packages": [ "archivist-for-embedding" ],
     },
   },
 }
diff --git a/build/toolchain/android/BUILD.gn b/build/toolchain/android/BUILD.gn
index e8989de..114f683 100644
--- a/build/toolchain/android/BUILD.gn
+++ b/build/toolchain/android/BUILD.gn
@@ -20,41 +20,16 @@
     assert(defined(invoker.toolchain_args),
            "toolchain_args must be defined for android_clang_toolchain()")
 
-    # Android toolchains need to declare .dwp files as outputs, so need to know
-    # the value of "use_debug_fission" when defining them.
-    # The derived value of "use_debug_fission" varies based on current_os, but
-    # toolchain definitions are evaluated under the default toolchain.
-    # Rather than computing the value under current_os="android", just disable
-    # it if target_os != "android".
-    _use_debug_fission = use_debug_fission && target_os == "android"
-
     toolchain_args = {
       forward_variables_from(invoker.toolchain_args, "*")
       current_os = "android"
-      use_debug_fission = _use_debug_fission
+      use_debug_fission = false
     }
 
     # Output linker map files for binary size analysis.
     enable_linker_map = true
 
     strip = rebase_path("$clang_base_path/bin/llvm-strip", root_build_dir)
-    if (_use_debug_fission) {
-      # llvm-dwp does not work with thin lto, so use binutils one.
-      # https://crbug.com/1264130
-      if (toolchain_args.current_cpu == "arm") {
-        _dwp = "arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-dwp"
-      } else if (toolchain_args.current_cpu == "arm64") {
-        _dwp = "aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-dwp"
-      } else if (toolchain_args.current_cpu == "x86") {
-        _dwp = "x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-dwp"
-      } else if (toolchain_args.current_cpu == "x64") {
-        _dwp = "x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-dwp"
-      } else {
-        _dwp = "llvm/prebuilt/linux-x86_64/bin/llvm-dwp"
-      }
-
-      dwp = rebase_path("$android_ndk_root/toolchains/$_dwp", root_build_dir)
-    }
 
     use_unstripped_as_runtime_outputs = android_unstripped_runtime_outputs
 
diff --git a/buildtools/reclient_cfgs/fetch_reclient_cfgs.py b/buildtools/reclient_cfgs/fetch_reclient_cfgs.py
index 4f16de2..89dd58d 100755
--- a/buildtools/reclient_cfgs/fetch_reclient_cfgs.py
+++ b/buildtools/reclient_cfgs/fetch_reclient_cfgs.py
@@ -39,7 +39,7 @@
       return None
     return subprocess.check_output(
         ['git', 'log', '-1', '--format=%H'],
-        cwd= nacl_dir,
+        cwd= nacl_dir, shell=os.name == 'nt',
     ).decode('utf-8').strip()
 
 class CipdError(Exception):
diff --git a/cc/base/features.cc b/cc/base/features.cc
index c51b10cf4..477a287b 100644
--- a/cc/base/features.cc
+++ b/cc/base/features.cc
@@ -47,7 +47,7 @@
 
 BASE_FEATURE(kMainRepaintScrollPrefersNewContent,
              "MainRepaintScrollPrefersNewContent",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 BASE_FEATURE(kFlushGpuAtDraw,
              "FlushGpuAtDraw",
diff --git a/chrome/VERSION b/chrome/VERSION
index db9949f0..02bf9aa 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=116
 MINOR=0
-BUILD=5791
+BUILD=5792
 PATCH=0
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index 3f10294b..0156180d 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -421,6 +421,9 @@
   "java/res/drawable/ic_turn_off_sync_48dp.xml",
   "java/res/drawable/ic_tv_options_input_settings_rotated_grey.xml",
   "java/res/drawable/ic_widgets.xml",
+  "java/res/drawable/improved_bookmark_save_flow_multi_pane_bottom_background.xml",
+  "java/res/drawable/improved_bookmark_save_flow_multi_pane_top_background.xml",
+  "java/res/drawable/improved_bookmark_save_flow_single_pane_background.xml",
   "java/res/drawable/incognito_history_placeholder_image.xml",
   "java/res/drawable/incognito_switch_track.xml",
   "java/res/drawable/infobar_autofill_cc.xml",
@@ -538,6 +541,7 @@
   "java/res/layout/improved_bookmark_row_folder_view_layout.xml",
   "java/res/layout/improved_bookmark_row_layout.xml",
   "java/res/layout/improved_bookmark_row_layout_visual.xml",
+  "java/res/layout/improved_bookmark_save_flow.xml",
   "java/res/layout/incognito_description_layout.xml",
   "java/res/layout/incognito_history_placeholder.xml",
   "java/res/layout/incognito_toggle_tabs.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 6e32fad..90e6deb 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -207,6 +207,9 @@
   "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java",
   "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowProperties.java",
   "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowViewBinder.java",
+  "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowProperties.java",
+  "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowView.java",
+  "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowViewBinder.java",
   "java/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandler.java",
   "java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkMetrics.java",
   "java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index b4f3358..5518769 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -87,6 +87,7 @@
   "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSearchBoxRowTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewRenderTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowRenderTest.java",
+  "javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowRenderTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowRenderTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipListRenderTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/ShoppingAccessoryViewRenderTest.java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
index 389a17df..49e3ad96 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
@@ -71,6 +71,13 @@
             new BooleanCachedFieldTrialParameter(ChromeFeatureList.TAB_STRIP_REDESIGN,
                     TAB_STRIP_REDESIGN_DISABLE_NTB_ANCHOR_PARAM, false);
 
+    // Field trial parameter for disabling button style for tab strip redesign. This includes
+    // disabling NTB anchor and button bg style.
+    private static final String TAB_STRIP_REDESIGN_DISABLE_BUTTON_STYLE_PARAM = "disable_btn_style";
+    public static final BooleanCachedFieldTrialParameter TAB_STRIP_REDESIGN_DISABLE_BUTTON_STYLE =
+            new BooleanCachedFieldTrialParameter(ChromeFeatureList.TAB_STRIP_REDESIGN,
+                    TAB_STRIP_REDESIGN_DISABLE_BUTTON_STYLE_PARAM, false);
+
     private static boolean sTabSelectionEditorLongPressEntryEnabled;
 
     /**
@@ -88,6 +95,13 @@
     }
 
     /**
+     * @return Whether button style for tab strip redesign is disabled.
+     */
+    public static boolean isTabStripButtonStyleDisabled() {
+        return TAB_STRIP_REDESIGN_DISABLE_BUTTON_STYLE.getValue();
+    }
+
+    /**
      * Whether the longpress entry for TabSelectionEditor is enabled. Currently only in tests.
      */
     public static boolean isTabSelectionEditorLongPressEntryEnabled() {
diff --git a/chrome/android/java/res/drawable/improved_bookmark_save_flow_multi_pane_bottom_background.xml b/chrome/android/java/res/drawable/improved_bookmark_save_flow_multi_pane_bottom_background.xml
new file mode 100644
index 0000000..8c3590b
--- /dev/null
+++ b/chrome/android/java/res/drawable/improved_bookmark_save_flow_multi_pane_bottom_background.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2023 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+
+<org.chromium.components.browser_ui.widget.SurfaceColorDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:shape="rectangle"
+    app:surfaceElevation="@dimen/default_elevation_1">
+    <corners android:topLeftRadius="@dimen/improved_bookmark_save_flow_inner_radius"
+             android:topRightRadius="@dimen/improved_bookmark_save_flow_inner_radius"
+             android:bottomLeftRadius="@dimen/improved_bookmark_save_flow_outer_radius"
+             android:bottomRightRadius="@dimen/improved_bookmark_save_flow_outer_radius" />
+</org.chromium.components.browser_ui.widget.SurfaceColorDrawable>
\ No newline at end of file
diff --git a/chrome/android/java/res/drawable/improved_bookmark_save_flow_multi_pane_top_background.xml b/chrome/android/java/res/drawable/improved_bookmark_save_flow_multi_pane_top_background.xml
new file mode 100644
index 0000000..624a8e29
--- /dev/null
+++ b/chrome/android/java/res/drawable/improved_bookmark_save_flow_multi_pane_top_background.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2023 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+
+<org.chromium.components.browser_ui.widget.SurfaceColorDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:shape="rectangle"
+    app:surfaceElevation="@dimen/default_elevation_1">
+    <corners android:topLeftRadius="@dimen/improved_bookmark_save_flow_outer_radius"
+             android:topRightRadius="@dimen/improved_bookmark_save_flow_outer_radius"
+             android:bottomLeftRadius="@dimen/improved_bookmark_save_flow_inner_radius"
+             android:bottomRightRadius="@dimen/improved_bookmark_save_flow_inner_radius" />
+</org.chromium.components.browser_ui.widget.SurfaceColorDrawable>
\ No newline at end of file
diff --git a/chrome/android/java/res/drawable/improved_bookmark_save_flow_single_pane_background.xml b/chrome/android/java/res/drawable/improved_bookmark_save_flow_single_pane_background.xml
new file mode 100644
index 0000000..2cf5c26
--- /dev/null
+++ b/chrome/android/java/res/drawable/improved_bookmark_save_flow_single_pane_background.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2023 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+
+<org.chromium.components.browser_ui.widget.SurfaceColorDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:shape="rectangle"
+    app:surfaceElevation="@dimen/default_elevation_1">
+    <corners android:topLeftRadius="@dimen/improved_bookmark_save_flow_outer_radius"
+             android:topRightRadius="@dimen/improved_bookmark_save_flow_outer_radius"
+             android:bottomLeftRadius="@dimen/improved_bookmark_save_flow_outer_radius"
+             android:bottomRightRadius="@dimen/improved_bookmark_save_flow_outer_radius" />
+</org.chromium.components.browser_ui.widget.SurfaceColorDrawable>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/improved_bookmark_save_flow.xml b/chrome/android/java/res/layout/improved_bookmark_save_flow.xml
new file mode 100644
index 0000000..ac244be7
--- /dev/null
+++ b/chrome/android/java/res/layout/improved_bookmark_save_flow.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2023 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+
+<org.chromium.chrome.browser.bookmarks.ImprovedBookmarkSaveFlowView
+    android:id="@+id/improved_bookmark_save_flow"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+  <androidx.constraintlayout.widget.ConstraintLayout
+      android:id="@+id/container"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:paddingTop="18dp"
+      android:paddingBottom="5dp"
+      android:paddingHorizontal="16dp">
+
+    <!--
+      The save flow can have multiple "panes" which represent the bookmark being saved and any
+      powers attached to it.
+    -->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/bookmark_container"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:paddingVertical="18dp"
+        android:paddingHorizontal="16dp"
+        android:contentDescription="@string/edit_folder"
+        android:foreground="@drawable/bookmark_save_flow_ripple"
+        android:focusable="true"
+        android:clickable="true" >
+
+      <org.chromium.components.browser_ui.widget.RoundedCornerImageView
+          android:id="@+id/bookmark_image"
+          app:layout_constraintStart_toStartOf="parent"
+          app:layout_constraintTop_toTopOf="parent"
+          android:layout_width="@dimen/improved_bookmark_save_flow_image_size"
+          android:layout_height="@dimen/improved_bookmark_save_flow_image_size"
+          android:scaleType="center"
+          app:cornerRadiusBottomStart="@dimen/default_rounded_corner_radius"
+          app:cornerRadiusBottomEnd="@dimen/default_rounded_corner_radius"
+          app:cornerRadiusTopStart="@dimen/default_rounded_corner_radius"
+          app:cornerRadiusTopEnd="@dimen/default_rounded_corner_radius"
+          android:background="@drawable/rounded_rectangle_surface_0"
+          android:importantForAccessibility="no"
+          android:focusable="false"
+          android:clickable="false" />
+
+      <LinearLayout
+          app:layout_constraintStart_toEndOf="@id/bookmark_image"
+          app:layout_constraintTop_toTopOf="parent"
+          app:layout_constraintBottom_toBottomOf="parent"
+          android:layout_gravity="center"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_marginStart="12dp"
+          android:orientation="vertical"
+          android:importantForAccessibility="no"
+          android:focusable="false"
+          android:clickable="false" >
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/bookmark_save_flow_title"
+            android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
+            android:importantForAccessibility="no"
+            android:focusable="false" />
+        <!-- Spans are used to mutate the color of part of this text at runtime. -->
+        <TextView
+            android:id="@+id/bookmark_subtitle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
+            android:importantForAccessibility="no"
+            android:focusable="false" />
+
+      </LinearLayout>
+      <ImageView
+          app:layout_constraintTop_toTopOf="parent"
+          app:layout_constraintBottom_toBottomOf="parent"
+          app:layout_constraintEnd_toEndOf="parent"
+          android:layout_width="@dimen/min_touch_target_size"
+          android:layout_height="match_parent"
+          android:scaleType="center"
+          android:src="@drawable/chevron_right"
+          android:importantForAccessibility="no"
+          android:focusable="false" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+      <!-- Price-tracking section. -->
+      <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/price_tracking_container"
+        android:visibility="gone"
+        app:layout_constraintTop_toBottomOf="@id/bookmark_container"
+        app:layout_constraintStart_toStartOf="parent"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:paddingVertical="16dp"
+        android:paddingHorizontal="16dp"
+        android:layout_marginTop="2dp" >
+
+      <ImageView
+          android:id="@+id/price_tracking_image"
+          app:layout_constraintStart_toStartOf="parent"
+          app:layout_constraintTop_toTopOf="parent"
+          app:layout_constraintBottom_toBottomOf="parent"
+          android:layout_width="24dp"
+          android:layout_height="24dp"
+          android:src="@drawable/price_tracking_disabled"
+          app:tint="@macro/default_icon_color"
+          android:importantForAccessibility="no" />
+
+      <LinearLayout
+          app:layout_constraintStart_toEndOf="@id/price_tracking_image"
+          app:layout_constraintTop_toTopOf="parent"
+          app:layout_constraintBottom_toBottomOf="parent"
+          android:layout_gravity="center"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_marginStart="12dp"
+          android:orientation="vertical">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/enable_price_tracking_menu_item"
+            android:textAppearance="@style/TextAppearance.TextMedium.Primary" />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/price_tracking_save_flow_notification_switch_subtitle"
+            android:textAppearance="@style/TextAppearance.TextSmall.Secondary" />
+      </LinearLayout>
+
+      <androidx.appcompat.widget.SwitchCompat
+          android:id="@+id/price_tracking_switch"
+          app:layout_constraintTop_toTopOf="parent"
+          app:layout_constraintBottom_toBottomOf="parent"
+          app:layout_constraintEnd_toEndOf="parent"
+          android:layout_width="wrap_content"
+          android:layout_height="match_parent"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+  </androidx.constraintlayout.widget.ConstraintLayout>
+
+</org.chromium.chrome.browser.bookmarks.ImprovedBookmarkSaveFlowView>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index b42af49..a92a25a 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -242,6 +242,11 @@
     <dimen name="improved_bookmark_icon_radius">24dp</dimen>
     <dimen name="bookmark_search_hint_horizontal_padding">30dp</dimen>
 
+    <!-- Improved bookamrk save flow properties-->
+    <dimen name="improved_bookmark_save_flow_outer_radius">8dp</dimen>
+    <dimen name="improved_bookmark_save_flow_inner_radius">4dp</dimen>
+    <dimen name="improved_bookmark_save_flow_image_size">75dp</dimen>
+
     <!-- Bookmark visual refresh dimensions. -->
      <dimen name="bookmark_refresh_preferred_start_icon_size">32dp</dimen>
      <dimen name="bookmark_refresh_circular_monogram_text_size">18dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index 9bc07a26..d9c28376 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -109,6 +109,7 @@
                 TabUiFeatureUtilities.ZOOMING_MIN_MEMORY, TabUiFeatureUtilities.SKIP_SLOW_ZOOMING,
                 TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO,
                 TabUiFeatureUtilities.TAB_STRIP_REDESIGN_DISABLE_NTB_ANCHOR,
+                TabUiFeatureUtilities.TAB_STRIP_REDESIGN_DISABLE_BUTTON_STYLE,
                 TabManagementFieldTrial.DELAY_TEMP_STRIP_TIMEOUT_MS,
                 TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_FOLIO,
                 TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_DETACHED,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java
index 3e01711..eb06469 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java
@@ -77,8 +77,7 @@
                         .with(ModalDialogProperties.CUSTOM_VIEW, mDialogView);
         mDialogModel = builder.build();
 
-        mEditorDialog = new EditorDialog(
-                activity, /*deleteRunnable=*/null, browserProfile, /*requiredIndicator=*/false);
+        mEditorDialog = new EditorDialog(activity, /*deleteRunnable=*/null, browserProfile);
         mEditorDialog.setShouldTriggerDoneCallbackBeforeCloseAnimation(true);
         AddressEditor.Delegate delegate = new AddressEditor.Delegate() {
             @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java
index 23a1c5b..b0d449d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java
@@ -103,7 +103,6 @@
     private final List<Spinner> mDropdownFields;
     private final InputFilter mCardNumberInputFilter;
     private final TextWatcher mCardNumberFormatter;
-    private final boolean mHasRequiredIndicator;
 
     @Nullable
     private TextWatcher mPhoneFormatter;
@@ -130,26 +129,13 @@
     private AlertDialog mConfirmationDialog;
 
     /**
-     * Builds the editor dialog with the required indicator enabled.
-     *
-     * @param activity          The activity on top of which the UI should be displayed.
-     * @param deleteRunnable    The runnable that when called will delete the profile.
-     * @param profile           The current profile that creates EditorDialog.
-     */
-    public EditorDialog(Activity activity, Runnable deleteRunnable, Profile profile) {
-        this(activity, deleteRunnable, profile, true);
-    }
-
-    /**
      * Builds the editor dialog.
      *
      * @param activity             The activity on top of which the UI should be displayed.
      * @param deleteRunnable       The runnable that when called will delete the profile.
      * @param profile              The current profile that creates EditorDialog.
-     * @param hasRequiredIndicator Whether the required (*) indicator is visible.
      */
-    public EditorDialog(Activity activity, Runnable deleteRunnable, Profile profile,
-            boolean requiredIndicator) {
+    public EditorDialog(Activity activity, Runnable deleteRunnable, Profile profile) {
         super(activity, R.style.ThemeOverlay_BrowserUI_Fullscreen);
         // Sets transparent background for animating content view.
         getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
@@ -201,7 +187,6 @@
         mCardNumberFormatter = new CreditCardNumberFormattingTextWatcher();
         mDeleteRunnable = deleteRunnable;
         mProfile = profile;
-        mHasRequiredIndicator = requiredIndicator;
     }
 
     /**
@@ -422,7 +407,7 @@
 
         TextView requiredFieldsNotice = mLayout.findViewById(R.id.required_fields_notice);
         int requiredFieldsNoticeVisibility = View.GONE;
-        if (mHasRequiredIndicator) {
+        if (mEditorModel.get(EditorProperties.SHOW_REQUIRED_INDICATOR)) {
             for (int i = 0; i < mFieldViews.size(); i++) {
                 if (mFieldViews.get(i).isRequired()) {
                     requiredFieldsNoticeVisibility = View.VISIBLE;
@@ -561,8 +546,9 @@
                     if (sObserverForTest != null) sObserverForTest.onEditorReadyToEdit();
                 }
             };
-            EditorDropdownField dropdownView = new EditorDropdownField(
-                    mActivity, parent, fieldModel, prepareEditorRunnable, mHasRequiredIndicator);
+            EditorDropdownField dropdownView =
+                    new EditorDropdownField(mActivity, parent, fieldModel, prepareEditorRunnable,
+                            mEditorModel.get(EditorProperties.SHOW_REQUIRED_INDICATOR));
             mFieldViews.add(dropdownView);
             mDropdownFields.add(dropdownView.getDropdown());
 
@@ -595,9 +581,9 @@
                 formatter = mPhoneFormatter;
             }
 
-            EditorTextField inputLayout =
-                    new EditorTextField(mActivity, fieldModel, mEditorActionListener, filter,
-                            formatter, /* focusAndShowKeyboard= */ false, mHasRequiredIndicator);
+            EditorTextField inputLayout = new EditorTextField(mActivity, fieldModel,
+                    mEditorActionListener, filter, formatter, /* focusAndShowKeyboard= */ false,
+                    mEditorModel.get(EditorProperties.SHOW_REQUIRED_INDICATOR));
             mFieldViews.add(inputLayout);
 
             EditText input = inputLayout.getEditText();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorProperties.java
index b66a5faf..8658f7c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorProperties.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorProperties.java
@@ -24,6 +24,8 @@
             new PropertyModel.ReadableObjectPropertyKey<>("delete_confirmation_title");
     public static final PropertyModel.ReadableObjectPropertyKey<String> DELETE_CONFIRMATION_TEXT =
             new PropertyModel.ReadableObjectPropertyKey<>("delete_confirmation_text");
+    public static final PropertyModel.ReadableBooleanPropertyKey SHOW_REQUIRED_INDICATOR =
+            new PropertyModel.ReadableBooleanPropertyKey("show_required_indicator");
 
     public static final PropertyModel
             .WritableObjectPropertyKey<List<EditorFieldModel>> EDITOR_FIELDS =
@@ -35,8 +37,8 @@
             new PropertyModel.ReadableObjectPropertyKey<>("cancel_callback");
 
     public static final PropertyKey[] ALL_KEYS = {EDITOR_TITLE, CUSTOM_DONE_BUTTON_TEXT,
-            FOOTER_MESSAGE, DELETE_CONFIRMATION_TITLE, DELETE_CONFIRMATION_TEXT, EDITOR_FIELDS,
-            DONE_RUNNABLE, CANCEL_RUNNABLE};
+            FOOTER_MESSAGE, DELETE_CONFIRMATION_TITLE, DELETE_CONFIRMATION_TEXT,
+            SHOW_REQUIRED_INDICATOR, EDITOR_FIELDS, DONE_RUNNABLE, CANCEL_RUNNABLE};
 
     private EditorProperties() {}
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java
index 7e4f291d..9bb977f4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java
@@ -13,6 +13,7 @@
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_FIELDS;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_TITLE;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.FOOTER_MESSAGE;
+import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.SHOW_REQUIRED_INDICATOR;
 
 import android.content.Context;
 import android.os.Handler;
@@ -592,6 +593,7 @@
                 .with(FOOTER_MESSAGE, getSourceNoticeText())
                 .with(DELETE_CONFIRMATION_TITLE, getDeleteConfirmationTitle())
                 .with(DELETE_CONFIRMATION_TEXT, getDeleteConfirmationText())
+                .with(SHOW_REQUIRED_INDICATOR, false)
                 .with(EDITOR_FIELDS,
                         buildEditorFieldList(AutofillAddress.getCountryCode(mProfileToEdit),
                                 mProfileToEdit.getLanguageCode()))
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragment.java
index 10f12309..dd77f1f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragment.java
@@ -247,7 +247,7 @@
             }
         };
 
-        return new EditorDialog(getActivity(), runnable, mProfile, false);
+        return new EditorDialog(getActivity(), runnable, mProfile);
     }
 
     @Nullable
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcher.java
index a6e4943..f676d2a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcher.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcher.java
@@ -11,6 +11,7 @@
 import android.util.Pair;
 
 import org.chromium.base.Callback;
+import org.chromium.base.CallbackController;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ui.favicon.FaviconUtils;
 import org.chromium.components.bookmarks.BookmarkId;
@@ -18,6 +19,7 @@
 import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
 import org.chromium.components.favicon.LargeIconBridge;
 import org.chromium.components.image_fetcher.ImageFetcher;
+import org.chromium.url.GURL;
 
 import java.util.Iterator;
 
@@ -28,6 +30,7 @@
     private final ImageFetcher mImageFetcher;
     private final LargeIconBridge mLargeIconBridge;
     private final int mFaviconFetchSize;
+    private final CallbackController mCallbackController = new CallbackController();
 
     private RoundedIconGenerator mRoundedIconGenerator;
     private int mImageSize;
@@ -56,6 +59,11 @@
         mFaviconSize = faviconSize;
     }
 
+    /** Destroys this object. */
+    public void destroy() {
+        mCallbackController.destroy();
+    }
+
     /**
      * Setup the properties required for fetching.
      * @param roundedIconGenerator Generates fallback images for bookmark favicons.
@@ -88,17 +96,17 @@
      */
     public void fetchImageForBookmarkWithFaviconFallback(
             BookmarkItem item, Callback<Drawable> callback) {
-        fetchImageForBookmark(item, drawable -> {
+        fetchImageForBookmark(item, mCallbackController.makeCancelable(drawable -> {
             if (drawable == null) {
                 fetchFaviconForBookmark(item, callback);
             } else {
                 callback.onResult(drawable);
             }
-        });
+        }));
     }
 
     /**
-     * Fetches a favicon for the given bookmarkid.
+     * Fetches a favicon for the given bookmark.
      * @param item The bookmark to fetch the image for.
      * @param callback The callback to receive the favicon.
      */
@@ -111,28 +119,60 @@
                 });
     }
 
-    private void fetchImageForBookmark(BookmarkItem item, Callback<Drawable> callback) {
-        final Callback<Bitmap> bookmarkImageCallback = (image) -> {
-            if (image == null) {
-                callback.onResult(null);
+    /**
+     * Fetch the given URL and fallback to {@link #fetchImageForBookmarkWithFaviconFallback}.
+     * @param url The url to fetch the image for.
+     * @param item The item to fallback on if the url fetch fails.
+     * @param callback The callback to receive the favicon.
+     */
+    public void fetchImageUrlWithFallbacks(
+            GURL url, BookmarkItem item, Callback<Drawable> callback) {
+        fetchImageUrl(url, drawable -> {
+            if (drawable == null) {
+                fetchImageForBookmarkWithFaviconFallback(item, callback);
             } else {
-                callback.onResult(new BitmapDrawable(mContext.getResources(), image));
+                callback.onResult(drawable);
             }
-        };
-
-        mBookmarkModel.getImageUrlForBookmark(item.getUrl(), (imageUrl) -> {
-            if (imageUrl == null) {
-                callback.onResult(null);
-                return;
-            }
-
-            mImageFetcher.fetchImage(
-                    ImageFetcher.Params.create(imageUrl, ImageFetcher.POWER_BOOKMARKS_CLIENT_NAME,
-                            mImageSize, mImageSize),
-                    bookmarkImageCallback);
         });
     }
 
+    private void fetchImageForBookmark(BookmarkItem item, Callback<Drawable> callback) {
+        final Callback<Bitmap> bookmarkImageCallback =
+                mCallbackController.makeCancelable((image) -> {
+                    if (image == null) {
+                        callback.onResult(null);
+                    } else {
+                        callback.onResult(new BitmapDrawable(mContext.getResources(), image));
+                    }
+                });
+
+        mBookmarkModel.getImageUrlForBookmark(
+                item.getUrl(), mCallbackController.makeCancelable((imageUrl) -> {
+                    if (imageUrl == null) {
+                        callback.onResult(null);
+                        return;
+                    }
+
+                    mImageFetcher.fetchImage(ImageFetcher.Params.create(imageUrl,
+                                                     ImageFetcher.POWER_BOOKMARKS_CLIENT_NAME,
+                                                     mImageSize, mImageSize),
+                            bookmarkImageCallback);
+                }));
+    }
+
+    private void fetchImageUrl(GURL url, Callback<Drawable> callback) {
+        mImageFetcher.fetchImage(
+                ImageFetcher.Params.create(
+                        url, ImageFetcher.POWER_BOOKMARKS_CLIENT_NAME, mImageSize, mImageSize),
+                (image) -> {
+                    if (image == null) {
+                        callback.onResult(null);
+                    } else {
+                        callback.onResult(new BitmapDrawable(mContext.getResources(), image));
+                    }
+                });
+    }
+
     private void fetchFirstTwoImagesForFolderImpl(Iterator<BookmarkId> childIdIterator,
             Drawable firstDrawable, Drawable secondDrawable,
             Callback<Pair<Drawable, Drawable>> callback) {
@@ -152,7 +192,7 @@
             return;
         }
 
-        fetchImageForBookmark(item, drawable -> {
+        fetchImageForBookmark(item, mCallbackController.makeCancelable(drawable -> {
             Drawable newFirstDrawable = firstDrawable;
             Drawable newSecondDrawable = secondDrawable;
             if (newFirstDrawable == null) {
@@ -162,6 +202,6 @@
             }
             fetchFirstTwoImagesForFolderImpl(
                     childIdIterator, newFirstDrawable, newSecondDrawable, callback);
-        });
+        }));
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
index c26b06b..037baae 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
@@ -403,6 +403,7 @@
         mIsDestroyed = true;
         mBookmarkModel.removeObserver(mBookmarkModelObserver);
 
+        mBookmarkImageFetcher.destroy();
         mLargeIconBridge.destroy();
         PartnerBookmarksReader.removeFaviconUpdateObserver(this);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowCoordinator.java
index 6e47aa4..5fc8b87 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowCoordinator.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.bookmarks;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.view.LayoutInflater;
 import android.view.View;
 
@@ -17,6 +18,7 @@
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref;
 import org.chromium.chrome.browser.commerce.PriceTrackingUtils;
 import org.chromium.chrome.browser.commerce.ShoppingFeatures;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -27,23 +29,23 @@
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver;
 import org.chromium.components.commerce.core.ShoppingService;
+import org.chromium.components.favicon.LargeIconBridge;
 import org.chromium.components.feature_engagement.FeatureConstants;
+import org.chromium.components.image_fetcher.ImageFetcherConfig;
+import org.chromium.components.image_fetcher.ImageFetcherFactory;
 import org.chromium.components.power_bookmarks.PowerBookmarkMeta;
 import org.chromium.ui.accessibility.AccessibilityState;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
-import org.chromium.ui.widget.ViewLookupCachingFrameLayout;
 
 /** Coordinates the bottom-sheet saveflow. */
 public class BookmarkSaveFlowCoordinator {
     private static final int AUTODISMISS_TIME_MS = 6000;
 
     private final Context mContext;
-    private final PropertyModel mPropertyModel =
-            new PropertyModel(BookmarkSaveFlowProperties.ALL_PROPERTIES);
-    private final PropertyModelChangeProcessor<PropertyModel, ViewLookupCachingFrameLayout,
-            PropertyKey> mChangeProcessor;
+    private final PropertyModel mPropertyModel;
+    private final PropertyModelChangeProcessor<PropertyModel, View, PropertyKey> mChangeProcessor;
     private final DestroyChecker mDestroyChecker;
     private final Profile mProfile;
 
@@ -68,17 +70,37 @@
         mContext = context;
         mBottomSheetController = bottomSheetController;
         mUserEducationHelper = userEducationHelper;
-        mBookmarkModel = BookmarkModel.getForProfile(Profile.getLastUsedRegularProfile());
+        mBookmarkModel = BookmarkModel.getForProfile(profile);
+        assert mBookmarkModel != null;
         mDestroyChecker = new DestroyChecker();
         mProfile = profile;
 
-        mBookmarkSaveFlowView = LayoutInflater.from(mContext).inflate(
-                org.chromium.chrome.R.layout.bookmark_save_flow, /*root=*/null);
-        mMediator = new BookmarkSaveFlowMediator(
-                mBookmarkModel, mPropertyModel, mContext, this::close, shoppingService);
-        mChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel,
-                (ViewLookupCachingFrameLayout) mBookmarkSaveFlowView,
-                new BookmarkSaveFlowViewBinder());
+        if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
+            mPropertyModel = new PropertyModel(ImprovedBookmarkSaveFlowProperties.ALL_KEYS);
+            mBookmarkSaveFlowView = LayoutInflater.from(mContext).inflate(
+                    org.chromium.chrome.R.layout.improved_bookmark_save_flow, /*root=*/null);
+            mChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel,
+                    mBookmarkSaveFlowView, ImprovedBookmarkSaveFlowViewBinder::bind);
+        } else {
+            mPropertyModel = new PropertyModel(BookmarkSaveFlowProperties.ALL_KEYS);
+            mBookmarkSaveFlowView = LayoutInflater.from(mContext).inflate(
+                    org.chromium.chrome.R.layout.bookmark_save_flow, /*root=*/null);
+            mChangeProcessor = PropertyModelChangeProcessor.create(
+                    mPropertyModel, mBookmarkSaveFlowView, new BookmarkSaveFlowViewBinder());
+        }
+
+        Resources res = mContext.getResources();
+        BookmarkImageFetcher bookmarkImageFetcher = new BookmarkImageFetcher(context,
+                mBookmarkModel,
+                ImageFetcherFactory.createImageFetcher(
+                        ImageFetcherConfig.DISK_CACHE_ONLY, mProfile.getProfileKey()),
+                new LargeIconBridge(mProfile),
+                BookmarkUtils.getRoundedIconGenerator(mContext, BookmarkRowDisplayPref.VISUAL),
+                res.getDimensionPixelSize(R.dimen.improved_bookmark_save_flow_image_size),
+                BookmarkUtils.getFaviconDisplaySize(res, BookmarkRowDisplayPref.VISUAL));
+
+        mMediator = new BookmarkSaveFlowMediator(mBookmarkModel, mPropertyModel, mContext,
+                this::close, shoppingService, bookmarkImageFetcher, mProfile);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java
index 0e4432a9..5b0656a9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java
@@ -5,10 +5,13 @@
 package org.chromium.chrome.browser.bookmarks;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.view.View;
 import android.widget.CompoundButton;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Callback;
@@ -16,6 +19,7 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref;
+import org.chromium.chrome.browser.bookmarks.ImprovedBookmarkSaveFlowProperties.FolderText;
 import org.chromium.chrome.browser.bookmarks.PowerBookmarkMetrics.PriceTrackingState;
 import org.chromium.chrome.browser.commerce.PriceTrackingUtils;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
@@ -29,21 +33,32 @@
 import org.chromium.components.feature_engagement.EventConstants;
 import org.chromium.components.power_bookmarks.PowerBookmarkMeta;
 import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.url.GURL;
 
-/** Controls the bookmarks save-flow. */
+/**
+ * Controls the bookmarks save-flow, which has 2 variants: standard, improved.
+ * The two variants have different properties, so each of the methods is branched to reflect that.
+ * BookmarkSaveFlowProperties shouldn't be used for the improved variant (it'll crash), and the
+ * same is true for ImprovedBookmarkSaveFlow properties with the standard variant.
+ * standard: The default save experience prior to android-improved-bookmarks.
+ * improved: The new experience for saving when android-improved-bookmarks is enabled.
+ */
 public class BookmarkSaveFlowMediator
         extends BookmarkModelObserver implements SubscriptionsObserver {
+    private static final String FOLDER_TEXT_TOKEN = "%1$s";
     private final Context mContext;
     private final Runnable mCloseRunnable;
+    private final BookmarkImageFetcher mBookmarkImageFetcher;
+    private final CallbackController mCallbackController = new CallbackController();
+    private final PropertyModel mPropertyModel;
+    private final BookmarkModel mBookmarkModel;
+    private final ShoppingService mShoppingService;
+    private final Profile mProfile;
 
-    private CallbackController mCallbackController = new CallbackController();
-    private PropertyModel mPropertyModel;
-    private BookmarkModel mBookmarkModel;
     private BookmarkId mBookmarkId;
     private PowerBookmarkMeta mPowerBookmarkMeta;
     private boolean mWasBookmarkMoved;
     private boolean mIsNewBookmark;
-    private ShoppingService mShoppingService;
     private CommerceSubscription mSubscription;
     private Callback<Boolean> mSubscriptionsManagerCallback;
     private String mFolderName;
@@ -55,9 +70,12 @@
      * @param context The {@link Context} associated with this mediator.
      * @param closeRunnable A {@link Runnable} which closes the bookmark save flow.
      * @param shoppingService Used to manage the price-tracking subscriptions.
+     * @param bookmarkImageFetcher Used to fetch images/favicons for bookmarks.
+     * @param profile The current chrome profile.
      */
     public BookmarkSaveFlowMediator(BookmarkModel bookmarkModel, PropertyModel propertyModel,
-            Context context, Runnable closeRunnable, ShoppingService shoppingService) {
+            Context context, Runnable closeRunnable, ShoppingService shoppingService,
+            BookmarkImageFetcher bookmarkImageFetcher, Profile profile) {
         mBookmarkModel = bookmarkModel;
         mBookmarkModel.addObserver(this);
 
@@ -69,6 +87,9 @@
         if (mShoppingService != null) {
             mShoppingService.addSubscriptionsObserver(this);
         }
+
+        mBookmarkImageFetcher = bookmarkImageFetcher;
+        mProfile = profile;
     }
 
     /**
@@ -92,64 +113,98 @@
         mWasBookmarkMoved = wasBookmarkMoved;
         mIsNewBookmark = isNewBookmark;
 
-        mPropertyModel.set(BookmarkSaveFlowProperties.EDIT_ONCLICK_LISTENER, (v) -> {
-            RecordUserAction.record("MobileBookmark.SaveFlow.EditBookmark");
-            BookmarkUtils.startEditActivity(mContext, mBookmarkId);
-            mCloseRunnable.run();
-        });
-        mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_ONCLICK_LISTENER, (v) -> {
-            RecordUserAction.record("MobileBookmark.SaveFlow.EditFolder");
-            BookmarkUtils.startFolderSelectActivity(mContext, mBookmarkId);
-            TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile())
-                    .notifyEvent(EventConstants.SHOPPING_LIST_SAVE_FLOW_FOLDER_TAP);
-            mCloseRunnable.run();
-        });
+        if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
+            mPropertyModel.set(ImprovedBookmarkSaveFlowProperties.BOOKMARK_ROW_CLICK_LISTENER,
+                    this::onEditClicked);
+        } else {
+            mPropertyModel.set(
+                    BookmarkSaveFlowProperties.EDIT_ONCLICK_LISTENER, this::onEditClicked);
+            mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_ONCLICK_LISTENER,
+                    this::onFolderSelectClicked);
+        }
 
         if (meta != null) {
             mSubscription = PowerBookmarkUtils.createCommerceSubscriptionForPowerBookmarkMeta(meta);
         }
-        bindBookmarkProperties(mBookmarkId, mPowerBookmarkMeta, mWasBookmarkMoved);
-        bindPowerBookmarkProperties(mBookmarkId, mPowerBookmarkMeta, fromExplicitTrackUi);
+
+        BookmarkItem item = mBookmarkModel.getBookmarkById(bookmarkId);
+        bindBookmarkProperties(item, mPowerBookmarkMeta, mWasBookmarkMoved);
+        bindPowerBookmarkProperties(mPowerBookmarkMeta, fromExplicitTrackUi);
+        if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
+            bindImage(item, meta);
+        }
     }
 
     private void bindBookmarkProperties(
-            BookmarkId bookmarkId, PowerBookmarkMeta meta, boolean wasBookmarkMoved) {
-        BookmarkItem item = mBookmarkModel.getBookmarkById(bookmarkId);
+            BookmarkItem item, PowerBookmarkMeta meta, boolean wasBookmarkMoved) {
         mFolderName = mBookmarkModel.getBookmarkTitle(item.getParentId());
-        mPropertyModel.set(BookmarkSaveFlowProperties.TITLE_TEXT,
-                mContext.getResources().getString(wasBookmarkMoved
-                                ? R.string.bookmark_save_flow_title_move
-                                : R.string.bookmark_save_flow_title));
-        mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_ICON,
-                BookmarkUtils.getFolderIcon(
-                        mContext, bookmarkId.getType(), BookmarkRowDisplayPref.COMPACT));
-        mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_ICON_ENABLED,
-                BookmarkUtils.isMovable(item));
-        mPropertyModel.set(BookmarkSaveFlowProperties.SUBTITLE_TEXT,
-                mContext.getResources().getString(wasBookmarkMoved
-                                ? R.string.bookmark_page_moved_location
-                                : R.string.bookmark_page_saved_location,
-                        mFolderName));
+
+        if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
+            String folderDisplayTextRaw = getFolderDisplayTextRaw(wasBookmarkMoved);
+            String folderDisplayText = getFolderDisplayText(wasBookmarkMoved);
+            mPropertyModel.set(ImprovedBookmarkSaveFlowProperties.FOLDER_TEXT,
+                    new FolderText(folderDisplayText,
+                            folderDisplayTextRaw.indexOf(FOLDER_TEXT_TOKEN), mFolderName.length()));
+        } else {
+            mPropertyModel.set(BookmarkSaveFlowProperties.TITLE_TEXT,
+                    mContext.getResources().getString(wasBookmarkMoved
+                                    ? R.string.bookmark_save_flow_title_move
+                                    : R.string.bookmark_save_flow_title));
+            mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_ICON,
+                    BookmarkUtils.getFolderIcon(
+                            mContext, item.getId().getType(), BookmarkRowDisplayPref.COMPACT));
+            mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_ICON_ENABLED,
+                    BookmarkUtils.isMovable(item));
+            mPropertyModel.set(BookmarkSaveFlowProperties.SUBTITLE_TEXT,
+                    getFolderDisplayText(wasBookmarkMoved));
+        }
     }
 
     private void bindPowerBookmarkProperties(
-            BookmarkId bookmarkId, @Nullable PowerBookmarkMeta meta, boolean fromExplicitTrackUi) {
+            @Nullable PowerBookmarkMeta meta, boolean fromExplicitTrackUi) {
         if (meta == null) return;
 
         if (meta.hasShoppingSpecifics()) {
             setPriceTrackingNotificationUiEnabled(true);
             setPriceTrackingIconForEnabledState(false);
-            mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_VISIBLE, true);
-            mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TITLE,
-                    mContext.getResources().getString(R.string.enable_price_tracking_menu_item));
-            mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLE_LISTENER,
-                    this::handleNotificationSwitchToggle);
+            if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
+                mPropertyModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_VISIBLE, true);
 
-            if (fromExplicitTrackUi) {
-                mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLED, true);
+                mPropertyModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED,
+                        fromExplicitTrackUi);
+                mPropertyModel.set(
+                        ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_LISTENER,
+                        this::handleNotificationSwitchToggle);
+                PowerBookmarkMetrics.reportBookmarkSaveFlowPriceTrackingState(
+                        PriceTrackingState.PRICE_TRACKING_SHOWN);
+            } else {
+                mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_VISIBLE, true);
+                mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TITLE,
+                        mContext.getResources().getString(
+                                R.string.enable_price_tracking_menu_item));
+                mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLE_LISTENER,
+                        this::handleNotificationSwitchToggle);
+
+                if (fromExplicitTrackUi) {
+                    mPropertyModel.set(
+                            BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLED, true);
+                }
+                PowerBookmarkMetrics.reportBookmarkSaveFlowPriceTrackingState(
+                        PriceTrackingState.PRICE_TRACKING_SHOWN);
             }
-            PowerBookmarkMetrics.reportBookmarkSaveFlowPriceTrackingState(
-                    PriceTrackingState.PRICE_TRACKING_SHOWN);
+        }
+    }
+
+    void bindImage(BookmarkItem item, @Nullable PowerBookmarkMeta meta) {
+        Callback<Drawable> callback = drawable -> {
+            mPropertyModel.set(ImprovedBookmarkSaveFlowProperties.BOOKMARK_ROW_ICON, drawable);
+        };
+
+        if (meta != null && meta.hasShoppingSpecifics()) {
+            mBookmarkImageFetcher.fetchImageUrlWithFallbacks(
+                    new GURL(meta.getLeadImage().getUrl()), item, callback);
+        } else {
+            mBookmarkImageFetcher.fetchImageForBookmarkWithFaviconFallback(item, callback);
         }
     }
 
@@ -169,25 +224,31 @@
             PriceDropNotificationManagerFactory.create().createNotificationChannel();
         }
         setPriceTrackingIconForEnabledState(toggled);
-        PriceTrackingUtils.setPriceTrackingStateForBookmark(Profile.getLastUsedRegularProfile(),
-                mBookmarkId.getId(), toggled, mSubscriptionsManagerCallback, mIsNewBookmark);
+        PriceTrackingUtils.setPriceTrackingStateForBookmark(mProfile, mBookmarkId.getId(), toggled,
+                mSubscriptionsManagerCallback, mIsNewBookmark);
         PowerBookmarkMetrics.reportBookmarkSaveFlowPriceTrackingState(toggled
                         ? PriceTrackingState.PRICE_TRACKING_ENABLED
                         : PriceTrackingState.PRICE_TRACKING_DISABLED);
     }
 
     void setPriceTrackingNotificationUiEnabled(boolean enabled) {
-        mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_UI_ENABLED, enabled);
-        mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_SUBTITLE,
-                mContext.getResources().getString(enabled
-                                ? R.string.price_tracking_save_flow_notification_switch_subtitle
-                                : R.string.price_tracking_save_flow_notification_switch_subtitle_error));
+        if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
+            mPropertyModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_ENABLED, enabled);
+        } else {
+            mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_UI_ENABLED, enabled);
+            mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_SUBTITLE,
+                    mContext.getResources().getString(enabled
+                                    ? R.string.price_tracking_save_flow_notification_switch_subtitle
+                                    : R.string.price_tracking_save_flow_notification_switch_subtitle_error));
+        }
     }
 
     void setPriceTrackingIconForEnabledState(boolean enabled) {
-        mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_START_ICON_RES,
-                enabled ? R.drawable.price_tracking_enabled_filled
-                        : R.drawable.price_tracking_disabled);
+        if (!BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
+            mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_START_ICON_RES,
+                    enabled ? R.drawable.price_tracking_enabled_filled
+                            : R.drawable.price_tracking_disabled);
+        }
     }
 
     void destroy() {
@@ -196,23 +257,30 @@
             mShoppingService.removeSubscriptionsObserver(this);
         }
 
-        mBookmarkModel = null;
-        mPropertyModel = null;
         mBookmarkId = null;
 
         if (mCallbackController != null) {
             mCallbackController.destroy();
-            mCallbackController = null;
         }
     }
 
     @VisibleForTesting
     void setPriceTrackingToggleVisualsOnly(boolean enabled) {
-        mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLE_LISTENER, null);
-        mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLED, enabled);
-        setPriceTrackingIconForEnabledState(enabled);
-        mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLE_LISTENER,
-                this::handleNotificationSwitchToggle);
+        if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
+            mPropertyModel.set(
+                    ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_LISTENER, null);
+            mPropertyModel.set(
+                    ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED, enabled);
+            mPropertyModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_LISTENER,
+                    this::handleNotificationSwitchToggle);
+        } else {
+            mPropertyModel.set(
+                    BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLE_LISTENER, null);
+            mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLED, enabled);
+            setPriceTrackingIconForEnabledState(enabled);
+            mPropertyModel.set(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLE_LISTENER,
+                    this::handleNotificationSwitchToggle);
+        }
     }
 
     void setSubscriptionForTesting(CommerceSubscription subscription) {
@@ -228,10 +296,13 @@
             mCloseRunnable.run();
             return;
         }
-        bindBookmarkProperties(mBookmarkId, mPowerBookmarkMeta, mWasBookmarkMoved);
+
+        BookmarkItem item = mBookmarkModel.getBookmarkById(mBookmarkId);
+        bindBookmarkProperties(item, mPowerBookmarkMeta, mWasBookmarkMoved);
     }
 
     // SubscriptionsObserver implementation
+
     @Override
     public void onSubscribe(CommerceSubscription subscription, boolean succeeded) {
         if (!succeeded || !subscription.equals(mSubscription)) return;
@@ -243,4 +314,44 @@
         if (!succeeded || !subscription.equals(mSubscription)) return;
         setPriceTrackingToggleVisualsOnly(false);
     }
+
+    // Private functions
+
+    private String getFolderDisplayTextRaw(boolean wasBookmarkMoved) {
+        @StringRes
+        int stringRes;
+        if (wasBookmarkMoved) {
+            stringRes = R.string.bookmark_page_moved_location;
+        } else {
+            stringRes = R.string.bookmark_page_saved_location;
+        }
+
+        return mContext.getString(stringRes);
+    }
+
+    private String getFolderDisplayText(boolean wasBookmarkMoved) {
+        @StringRes
+        int stringRes;
+        if (wasBookmarkMoved) {
+            stringRes = R.string.bookmark_page_moved_location;
+        } else {
+            stringRes = R.string.bookmark_page_saved_location;
+        }
+
+        return mContext.getString(stringRes, mFolderName);
+    }
+
+    private void onEditClicked(View v) {
+        RecordUserAction.record("MobileBookmark.SaveFlow.EditBookmark");
+        BookmarkUtils.startEditActivity(mContext, mBookmarkId);
+        mCloseRunnable.run();
+    }
+
+    private void onFolderSelectClicked(View v) {
+        RecordUserAction.record("MobileBookmark.SaveFlow.EditFolder");
+        BookmarkUtils.startFolderSelectActivity(mContext, mBookmarkId);
+        TrackerFactory.getTrackerForProfile(mProfile).notifyEvent(
+                EventConstants.SHOPPING_LIST_SAVE_FLOW_FOLDER_TAP);
+        mCloseRunnable.run();
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java
index c7558a8..37ab32d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java
@@ -41,7 +41,7 @@
     public static final WritableObjectPropertyKey<CharSequence> TITLE_TEXT =
             new WritableObjectPropertyKey<>();
 
-    public static final PropertyKey[] ALL_PROPERTIES = {EDIT_ONCLICK_LISTENER, FOLDER_SELECT_ICON,
+    public static final PropertyKey[] ALL_KEYS = {EDIT_ONCLICK_LISTENER, FOLDER_SELECT_ICON,
             FOLDER_SELECT_ICON_ENABLED, FOLDER_SELECT_ONCLICK_LISTENER, NOTIFICATION_SWITCH_VISIBLE,
             NOTIFICATION_SWITCH_START_ICON_RES, NOTIFICATION_SWITCH_TITLE,
             NOTIFICATION_SWITCH_SUBTITLE, NOTIFICATION_SWITCH_TOGGLED,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java
index 997ce5d2..82d4175 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java
@@ -21,14 +21,11 @@
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor.ViewBinder;
-import org.chromium.ui.widget.ViewLookupCachingFrameLayout;
 
 /** ViewBinder for the bookmarks save flow. */
-public class BookmarkSaveFlowViewBinder
-        implements ViewBinder<PropertyModel, ViewLookupCachingFrameLayout, PropertyKey> {
+public class BookmarkSaveFlowViewBinder implements ViewBinder<PropertyModel, View, PropertyKey> {
     @Override
-    public void bind(
-            PropertyModel model, ViewLookupCachingFrameLayout view, PropertyKey propertyKey) {
+    public void bind(PropertyModel model, View view, PropertyKey propertyKey) {
         if (propertyKey == BookmarkSaveFlowProperties.EDIT_ONCLICK_LISTENER) {
             view.findViewById(R.id.bookmark_edit)
                     .setOnClickListener(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowProperties.java
new file mode 100644
index 0000000..df2fc52
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowProperties.java
@@ -0,0 +1,63 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.CompoundButton;
+
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
+import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
+
+/** Hosts the properties for the improved bookmarks save flow. */
+public class ImprovedBookmarkSaveFlowProperties {
+    /** Encapsulates the display text for folders. */
+    static class FolderText {
+        private final String mFolderDisplayText;
+        private final int mFolderTitleStartIndex;
+        private final int mFolderTitleEndIndex;
+
+        FolderText(String folderDisplayText, int folderTitleStartIndex, int folderTitleLength) {
+            mFolderDisplayText = folderDisplayText;
+            mFolderTitleStartIndex = folderTitleStartIndex;
+            mFolderTitleEndIndex = mFolderTitleStartIndex + folderTitleLength;
+        }
+
+        String getDisplayText() {
+            return mFolderDisplayText;
+        }
+
+        int getFolderTitleStartIndex() {
+            return mFolderTitleStartIndex;
+        }
+
+        int getFolderTitleEndIndex() {
+            return mFolderTitleEndIndex;
+        }
+    }
+
+    public static final WritableObjectPropertyKey<View.OnClickListener>
+            BOOKMARK_ROW_CLICK_LISTENER = new WritableObjectPropertyKey<>();
+    public static final WritableObjectPropertyKey<Drawable> BOOKMARK_ROW_ICON =
+            new WritableObjectPropertyKey<>();
+    public static final WritableObjectPropertyKey<FolderText> FOLDER_TEXT =
+            new WritableObjectPropertyKey<>();
+    public static final WritableBooleanPropertyKey PRICE_TRACKING_VISIBLE =
+            new WritableBooleanPropertyKey();
+    public static final WritableBooleanPropertyKey PRICE_TRACKING_ENABLED =
+            new WritableBooleanPropertyKey();
+    public static final WritableBooleanPropertyKey PRICE_TRACKING_SWITCH_CHECKED =
+            new WritableBooleanPropertyKey();
+    public static final WritableObjectPropertyKey<CompoundButton.OnCheckedChangeListener>
+            PRICE_TRACKING_SWITCH_LISTENER = new WritableObjectPropertyKey<>();
+
+    private static final PropertyKey[] NEW_KEYS = {BOOKMARK_ROW_CLICK_LISTENER, BOOKMARK_ROW_ICON,
+            FOLDER_TEXT, PRICE_TRACKING_VISIBLE, PRICE_TRACKING_ENABLED,
+            PRICE_TRACKING_SWITCH_CHECKED, PRICE_TRACKING_SWITCH_LISTENER};
+    public static final PropertyKey[] ALL_KEYS =
+            PropertyModel.concatKeys(BookmarkSaveFlowProperties.ALL_KEYS, NEW_KEYS);
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowView.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowView.java
new file mode 100644
index 0000000..4968d1da
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowView.java
@@ -0,0 +1,89 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.style.ForegroundColorSpan;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.ImprovedBookmarkSaveFlowProperties.FolderText;
+import org.chromium.components.browser_ui.styles.SemanticColorUtils;
+
+/** Controls the bookmarks save-flow view. */
+public class ImprovedBookmarkSaveFlowView extends FrameLayout {
+    private View mBookmarkContainer;
+    private ImageView mBookmarkImageView;
+    private TextView mBookmarkSubtitleView;
+    private View mPriceTrackingContainer;
+    private CompoundButton mPriceTrackingSwitch;
+
+    /** Constructor for inflating from XML. */
+    public ImprovedBookmarkSaveFlowView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        mBookmarkContainer = findViewById(R.id.bookmark_container);
+        mBookmarkImageView = findViewById(R.id.bookmark_image);
+        mBookmarkSubtitleView = findViewById(R.id.bookmark_subtitle);
+        mPriceTrackingContainer = findViewById(R.id.price_tracking_container);
+        mPriceTrackingSwitch = findViewById(R.id.price_tracking_switch);
+
+        mBookmarkContainer.setBackgroundResource(
+                R.drawable.improved_bookmark_save_flow_single_pane_background);
+    }
+
+    void setBookmarkRowClickListener(View.OnClickListener listener) {
+        mBookmarkContainer.setOnClickListener(listener);
+    }
+
+    void setBookmarkDrawable(Drawable drawable) {
+        mBookmarkImageView.setImageDrawable(drawable);
+    }
+
+    void setFolderText(FolderText folderText) {
+        SpannableString ss = new SpannableString(folderText.getDisplayText());
+        ForegroundColorSpan fcs = new ForegroundColorSpan(
+                SemanticColorUtils.getDefaultTextColorAccent1(getContext()));
+        ss.setSpan(fcs, folderText.getFolderTitleStartIndex(), folderText.getFolderTitleEndIndex(),
+                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        // mBookmarkSubtitleView.setMovementMethod(LinkMovementMethod.getInstance());
+        mBookmarkSubtitleView.setText(ss);
+    }
+
+    void setPriceTrackingUiVisible(boolean visible) {
+        mPriceTrackingContainer.setVisibility(visible ? View.VISIBLE : View.GONE);
+        if (visible) {
+            mBookmarkContainer.setBackgroundResource(
+                    R.drawable.improved_bookmark_save_flow_multi_pane_top_background);
+            mPriceTrackingContainer.setBackgroundResource(
+                    R.drawable.improved_bookmark_save_flow_multi_pane_bottom_background);
+        }
+    }
+
+    void setPriceTrackingUiEnabled(boolean enabled) {
+        mPriceTrackingContainer.setEnabled(enabled);
+    }
+
+    void setPriceTrackingSwitchChecked(boolean checked) {
+        mPriceTrackingSwitch.setChecked(checked);
+    }
+
+    void setPriceTrackingSwitchToggleListener(CompoundButton.OnCheckedChangeListener listener) {
+        mPriceTrackingSwitch.setOnCheckedChangeListener(listener);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowViewBinder.java
new file mode 100644
index 0000000..61c8257
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowViewBinder.java
@@ -0,0 +1,41 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.view.View;
+
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/** ViewBinder for the improved bookmarks save flow. */
+class ImprovedBookmarkSaveFlowViewBinder {
+    static void bind(PropertyModel model, View view, PropertyKey propertyKey) {
+        ImprovedBookmarkSaveFlowView improvedSaveFlow = (ImprovedBookmarkSaveFlowView) view;
+        if (propertyKey == ImprovedBookmarkSaveFlowProperties.BOOKMARK_ROW_CLICK_LISTENER) {
+            improvedSaveFlow.setBookmarkRowClickListener(
+                    model.get(ImprovedBookmarkSaveFlowProperties.BOOKMARK_ROW_CLICK_LISTENER));
+        } else if (propertyKey == ImprovedBookmarkSaveFlowProperties.BOOKMARK_ROW_ICON) {
+            improvedSaveFlow.setBookmarkDrawable(
+                    model.get(ImprovedBookmarkSaveFlowProperties.BOOKMARK_ROW_ICON));
+        } else if (propertyKey == ImprovedBookmarkSaveFlowProperties.FOLDER_TEXT) {
+            improvedSaveFlow.setFolderText(
+                    model.get(ImprovedBookmarkSaveFlowProperties.FOLDER_TEXT));
+        } else if (propertyKey == ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_VISIBLE) {
+            improvedSaveFlow.setPriceTrackingUiVisible(
+                    model.get(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_VISIBLE));
+        } else if (propertyKey == ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_ENABLED) {
+            improvedSaveFlow.setPriceTrackingUiEnabled(
+                    model.get(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_ENABLED));
+        } else if (propertyKey
+                == ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED) {
+            improvedSaveFlow.setPriceTrackingSwitchChecked(
+                    model.get(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED));
+        } else if (propertyKey
+                == ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_LISTENER) {
+            improvedSaveFlow.setPriceTrackingSwitchToggleListener(
+                    model.get(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_LISTENER));
+        }
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
index e50df9b..64bf0b9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -1707,14 +1707,20 @@
         }
     }
 
+    private boolean isNewTabButtonAnchorDisabled() {
+        return !ChromeFeatureList.sTabStripRedesign.isEnabled()
+                || TabUiFeatureUtilities.isTabStripNtbAnchorDisabled()
+                || TabUiFeatureUtilities.isTabStripButtonStyleDisabled();
+    }
+
+    // @Todo (crbugs.com/1448590) Update NTB and incognito position for button style disabled param.
     private CompositorAnimator updateNewTabButtonState(boolean animate) {
         // 1. The NTB is faded out upon entering reorder mode and hidden when the model is empty.
         boolean isEmpty = mStripTabs.length == 0;
         mNewTabButton.setVisible(!isEmpty);
         if (mInReorderMode || isEmpty) return null;
 
-        if (!ChromeFeatureList.sTabStripRedesign.isEnabled()
-                || TabUiFeatureUtilities.isTabStripNtbAnchorDisabled()) {
+        if (isNewTabButtonAnchorDisabled()) {
             // 2. Get offset from strip stacker.
             float offset = mStripStacker.computeNewTabButtonOffset(mStripTabs, mTabOverlapWidth,
                     mLeftMargin, mRightMargin, mWidth, mNewTabButtonWidth,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
index b66a6229..991bc226c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
@@ -13,6 +13,7 @@
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.content.res.AppCompatResources;
 
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.Supplier;
@@ -272,12 +273,6 @@
                 createDetachedModelSelectorButton(context, selectorClickHandler);
             }
 
-            // Model selector button icon color
-            int iconDefaultColor =
-                    context.getResources().getColor(R.color.model_selector_button_icon_color);
-            int iconIncognitoColor =
-                    context.getResources().getColor(R.color.default_icon_color_secondary_light);
-
             // Model selector button background color.
             // Default bg color is surface inverse.
             int backgroundDefaultColor =
@@ -294,9 +289,21 @@
                     ? context.getResources().getColor(defaultBgColorDarkElev1)
                     : context.getResources().getColor(defaultBgColorDarkElev2);
 
+            // Model selector button icon color
+            // @Todo(zheliooo crbugs.com/1447285) may need to update color using GM3 and update MSB
+            // icon per UX suggestion. Temporarily set MSB color match NTB color in normal mode
+            int iconDefaultColor = TabUiFeatureUtilities.isTabStripButtonStyleDisabled()
+                    ? AppCompatResources
+                              .getColorStateList(context, R.color.default_icon_color_tint_list)
+                              .getDefaultColor()
+                    : context.getResources().getColor(R.color.model_selector_button_icon_color);
+            int iconIncognitoColor =
+                    context.getResources().getColor(R.color.default_icon_color_secondary_light);
+
             ((TintedCompositorButton) mModelSelectorButton)
                     .setTint(iconDefaultColor, iconDefaultColor, iconIncognitoColor,
                             iconIncognitoColor);
+
             ((TintedCompositorButton) mModelSelectorButton)
                     .setBackgroundTint(backgroundDefaultColor, backgroundDefaultColor,
                             backgroundIncognitoColor, backgroundIncognitoColor);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
index 81eabffb..db2aa31 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
@@ -19,6 +19,7 @@
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer;
 import org.chromium.chrome.browser.layouts.scene_layer.SceneOverlayLayer;
+import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
 import org.chromium.ui.base.LocalizationUtils;
 import org.chromium.ui.resources.ResourceManager;
 
@@ -44,8 +45,9 @@
     @Override
     protected void initializeNative() {
         if (mNativePtr == 0) {
-            mNativePtr = TabStripSceneLayerJni.get().init(
-                    TabStripSceneLayer.this, ChromeFeatureList.sTabStripRedesign.isEnabled());
+            mNativePtr = TabStripSceneLayerJni.get().init(TabStripSceneLayer.this,
+                    ChromeFeatureList.sTabStripRedesign.isEnabled(),
+                    TabUiFeatureUtilities.isTabStripButtonStyleDisabled());
         }
         // Set flag for testing
         if (!sTestFlag) {
@@ -177,7 +179,8 @@
 
     @NativeMethods
     public interface Natives {
-        long init(TabStripSceneLayer caller, boolean isTabStripRedesignEnabled);
+        long init(TabStripSceneLayer caller, boolean isTabStripRedesignEnabled,
+                boolean isTsrButtonStyleDisabled);
         void beginBuildingFrame(
                 long nativeTabStripSceneLayer, TabStripSceneLayer caller, boolean visible);
         void finishBuildingFrame(long nativeTabStripSceneLayer, TabStripSceneLayer caller);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index 640617a9..6afdb35 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -459,8 +459,8 @@
     public boolean onItemSelected(int itemId) {
         if (itemId == R.id.contextmenu_open_in_new_tab) {
             recordContextMenuSelection(ContextMenuUma.Action.OPEN_IN_NEW_TAB);
-            mItemDelegate.onOpenInNewTab(
-                    mParams.getUrl(), mParams.getReferrer(), /*navigateToTab=*/false);
+            mItemDelegate.onOpenInNewTab(mParams.getUrl(), mParams.getReferrer(),
+                    /*navigateToTab=*/false, mParams.getImpression());
         } else if (itemId == R.id.contextmenu_open_in_new_tab_in_group) {
             recordContextMenuSelection(ContextMenuUma.Action.OPEN_IN_NEW_TAB_IN_GROUP);
             mItemDelegate.onOpenInNewTabInGroup(mParams.getUrl(), mParams.getReferrer());
@@ -617,7 +617,7 @@
         } else if (itemId == R.id.contextmenu_learn_more) {
             recordContextMenuSelection(ContextMenuUma.Action.LEARN_MORE);
             mItemDelegate.onOpenInNewTab(new GURL(LinkToTextHelper.SHARED_HIGHLIGHTING_SUPPORT_URL),
-                    mParams.getReferrer(), /*navigateToTab=*/true);
+                    mParams.getReferrer(), /*navigateToTab=*/true, /*attributionSrcToken*/ null);
         } else {
             assert false;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
index 501380a..4930d6b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -115,13 +115,6 @@
             "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_POSITION";
 
     /**
-     * Extra that defines the behavior of the opening animation of the side sheet.
-     * It is set to {@link #ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE} by default.
-     */
-    public static final String EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR =
-            "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR";
-
-    /**
      * Extra used to keep the caller alive. Its value is an Intent.
      */
     public static final String EXTRA_KEEP_ALIVE = "android.support.customtabs.extra.KEEP_ALIVE";
@@ -1024,9 +1017,6 @@
         if (IntentUtils.safeHasExtra(intent, EXTRA_ACTIVITY_SIDE_SHEET_POSITION)) {
             featureUsage.log(CustomTabsFeature.EXTRA_ACTIVITY_SIDE_SHEET_POSITION);
         }
-        if (IntentUtils.safeHasExtra(intent, EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR)) {
-            featureUsage.log(CustomTabsFeature.EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR);
-        }
     }
 
     @Override
@@ -1408,12 +1398,7 @@
 
     @Override
     public int getSideSheetSlideInBehavior() {
-        @ActivitySideSheetSlideInBehavior
-        int slideInBehavior = IntentUtils.safeGetIntExtra(mIntent,
-                EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR, ACTIVITY_SIDE_SHEET_SLIDE_IN_DEFAULT);
-        return slideInBehavior == ACTIVITY_SIDE_SHEET_SLIDE_IN_DEFAULT
-                ? ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE
-                : slideInBehavior;
+        return ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE;
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java
index f89b137..5fbf7215 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java
@@ -9,6 +9,7 @@
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.DONE_RUNNABLE;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_FIELDS;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_TITLE;
+import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.SHOW_REQUIRED_INDICATOR;
 
 import android.app.ProgressDialog;
 import android.os.Handler;
@@ -279,6 +280,7 @@
 
         mEditorModel = new PropertyModel.Builder(ALL_KEYS)
                                .with(EDITOR_TITLE, editTitle)
+                               .with(SHOW_REQUIRED_INDICATOR, true)
                                .with(EDITOR_FIELDS, new ArrayList())
                                .with(DONE_RUNNABLE, onDone)
                                .with(CANCEL_RUNNABLE, onCancel)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ContactEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ContactEditor.java
index 8e801dc..b109fec2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ContactEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ContactEditor.java
@@ -9,6 +9,7 @@
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.DONE_RUNNABLE;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_FIELDS;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_TITLE;
+import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.SHOW_REQUIRED_INDICATOR;
 
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
@@ -279,6 +280,7 @@
 
         PropertyModel editorModel = new PropertyModel.Builder(ALL_KEYS)
                                             .with(EDITOR_TITLE, editorTitle)
+                                            .with(SHOW_REQUIRED_INDICATOR, true)
                                             .with(EDITOR_FIELDS, editorFields)
                                             .with(DONE_RUNNABLE, onDone)
                                             .with(CANCEL_RUNNABLE, onCancel)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
index 889e51f9..37c43a2e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -12,6 +12,7 @@
 import android.provider.Browser;
 import android.provider.ContactsContract;
 
+import androidx.annotation.Nullable;
 import androidx.browser.customtabs.CustomTabsIntent;
 
 import org.chromium.base.ContextUtils;
@@ -39,6 +40,7 @@
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.components.embedder_support.util.UrlUtilities;
 import org.chromium.components.feature_engagement.EventConstants;
+import org.chromium.content_public.browser.Impression;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.common.Referrer;
@@ -200,11 +202,13 @@
     }
 
     @Override
-    public void onOpenInNewTab(GURL url, Referrer referrer, boolean navigateToTab) {
+    public void onOpenInNewTab(
+            GURL url, Referrer referrer, boolean navigateToTab, @Nullable Impression impression) {
         RecordUserAction.record("MobileNewTabOpened");
         RecordUserAction.record("LinkOpenedInNewTab");
         LoadUrlParams loadUrlParams = new LoadUrlParams(url.getSpec());
         loadUrlParams.setReferrer(referrer);
+        loadUrlParams.setImpression(impression);
         mTabModelSelector.openNewTab(loadUrlParams,
                 navigateToTab ? TabLaunchType.FROM_LONGPRESS_FOREGROUND
                               : TabLaunchType.FROM_LONGPRESS_BACKGROUND,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webshare/ShareServiceImplementationFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/webshare/ShareServiceImplementationFactory.java
index 29f565c..aca64b77 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webshare/ShareServiceImplementationFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webshare/ShareServiceImplementationFactory.java
@@ -6,6 +6,7 @@
 
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.share.ChromeShareExtras;
+import org.chromium.chrome.browser.share.ChromeShareExtras.DetailedContentType;
 import org.chromium.chrome.browser.share.ShareDelegate;
 import org.chromium.chrome.browser.share.ShareDelegate.ShareOrigin;
 import org.chromium.chrome.browser.share.ShareDelegateSupplier;
@@ -44,8 +45,11 @@
 
             @Override
             public void share(ShareParams params) {
-                getShareDelegate().share(
-                        params, new ChromeShareExtras.Builder().build(), ShareOrigin.WEBSHARE_API);
+                getShareDelegate().share(params,
+                        new ChromeShareExtras.Builder()
+                                .setDetailedContentType(DetailedContentType.WEB_SHARE)
+                                .build(),
+                        ShareOrigin.WEBSHARE_API);
             }
 
             /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java
index 5aced62..c7bc226 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java
@@ -80,17 +80,12 @@
     public JniMocker mJniMocker = new JniMocker();
 
     @Mock
-    ShoppingService mShoppingService;
-
+    private ShoppingService mShoppingService;
     @Mock
-    PriceTrackingUtils.Natives mMockPriceTrackingUtilsJni;
-
+    private PriceTrackingUtils.Natives mMockPriceTrackingUtilsJni;
     @Mock
     private UserEducationHelper mUserEducationHelper;
 
-    @Mock
-    private Profile mProfile;
-
     private BookmarkSaveFlowCoordinator mBookmarkSaveFlowCoordinator;
     private BottomSheetController mBottomSheetController;
     private BottomSheetTestSupport mBottomSheetTestSupport;
@@ -101,6 +96,8 @@
         mActivityTestRule.startMainActivityOnBlankPage();
         ChromeActivityTestRule.waitForActivityNativeInitializationComplete(
                 mActivityTestRule.getActivity());
+
+        // Setup price-tracking.
         mJniMocker.mock(PriceTrackingUtilsJni.TEST_HOOKS, mMockPriceTrackingUtilsJni);
 
         TestThreadUtils.runOnUiThreadBlocking(() -> {
@@ -108,9 +105,10 @@
             mBottomSheetController =
                     cta.getRootUiCoordinatorForTesting().getBottomSheetController();
             mBottomSheetTestSupport = new BottomSheetTestSupport(mBottomSheetController);
-            mBookmarkSaveFlowCoordinator = new BookmarkSaveFlowCoordinator(
-                    cta, mBottomSheetController, mShoppingService, mUserEducationHelper, mProfile);
             mBookmarkModel = mActivityTestRule.getActivity().getBookmarkModelForTesting();
+            mBookmarkSaveFlowCoordinator =
+                    new BookmarkSaveFlowCoordinator(cta, mBottomSheetController, mShoppingService,
+                            mUserEducationHelper, Profile.getLastUsedRegularProfile());
         });
 
         loadBookmarkModel();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowRenderTest.java
new file mode 100644
index 0000000..279ce8af
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowRenderTest.java
@@ -0,0 +1,173 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import androidx.test.filters.MediumTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import org.chromium.base.test.BaseActivityTestRule;
+import org.chromium.base.test.params.ParameterAnnotations;
+import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
+import org.chromium.base.test.params.ParameterSet;
+import org.chromium.base.test.params.ParameterizedRunner;
+import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref;
+import org.chromium.chrome.browser.bookmarks.ImprovedBookmarkSaveFlowProperties.FolderText;
+import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
+import org.chromium.ui.test.util.BlankUiTestActivity;
+import org.chromium.ui.test.util.DisableAnimationsTestRule;
+import org.chromium.ui.test.util.NightModeTestUtils;
+import org.chromium.ui.test.util.NightModeTestUtils.NightModeParams;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Render tests for the improved bookmark row.
+ */
+@RunWith(ParameterizedRunner.class)
+@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
+@Batch(Batch.PER_CLASS)
+public class ImprovedBookmarkSaveFlowRenderTest {
+    @ClassParameter
+    private static List<ParameterSet> sClassParams = new NightModeParams().getParameters();
+
+    @Rule
+    public final DisableAnimationsTestRule mDisableAnimationsRule = new DisableAnimationsTestRule();
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule
+    public BaseActivityTestRule<BlankUiTestActivity> mActivityTestRule =
+            new BaseActivityTestRule<>(BlankUiTestActivity.class);
+    @Rule
+    public ChromeRenderTestRule mRenderTestRule =
+            ChromeRenderTestRule.Builder.withPublicCorpus()
+                    .setBugComponent(ChromeRenderTestRule.Component.UI_BROWSER_BOOKMARKS)
+                    .build();
+
+    private Bitmap mBitmap;
+    private ImprovedBookmarkSaveFlowView mView;
+    private LinearLayout mContentView;
+    private PropertyModel mModel;
+
+    public ImprovedBookmarkSaveFlowRenderTest(boolean nightModeEnabled) {
+        // Sets a fake background color to make the screenshots easier to compare with bare eyes.
+        NightModeTestUtils.setUpNightModeForBlankUiTestActivity(nightModeEnabled);
+        mRenderTestRule.setNightModeEnabled(nightModeEnabled);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.launchActivity(null);
+        mActivityTestRule.getActivity().setTheme(R.style.Theme_BrowserUI_DayNight);
+
+        int bitmapSize = mActivityTestRule.getActivity().getResources().getDimensionPixelSize(
+                R.dimen.improved_bookmark_save_flow_image_size);
+        mBitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
+        mBitmap.eraseColor(Color.GREEN);
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mContentView = new LinearLayout(mActivityTestRule.getActivity());
+            mContentView.setBackgroundColor(Color.WHITE);
+
+            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            mActivityTestRule.getActivity().setContentView(mContentView, params);
+
+            LayoutInflater.from(mActivityTestRule.getActivity())
+                    .inflate(R.layout.improved_bookmark_save_flow, /*root=*/mContentView);
+
+            mView = mContentView.findViewById(R.id.improved_bookmark_save_flow);
+            mModel = new PropertyModel.Builder(ImprovedBookmarkSaveFlowProperties.ALL_KEYS)
+                             .with(ImprovedBookmarkSaveFlowProperties.BOOKMARK_ROW_ICON,
+                                     new BitmapDrawable(
+                                             mActivityTestRule.getActivity().getResources(),
+                                             mBitmap))
+                             .with(ImprovedBookmarkSaveFlowProperties.FOLDER_TEXT,
+                                     new FolderText("in test folder", 3, 11))
+                             .with(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_VISIBLE, false)
+                             .build();
+
+            PropertyModelChangeProcessor.create(
+                    mModel, mView, ImprovedBookmarkSaveFlowViewBinder::bind);
+        });
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    public void testImage() throws IOException {
+        mRenderTestRule.render(mContentView, "image");
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    public void testFavicon() throws IOException {
+        int bitmapSize = BookmarkUtils.getFaviconDisplaySize(
+                mActivityTestRule.getActivity().getResources(), BookmarkRowDisplayPref.VISUAL);
+        Bitmap bitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
+        bitmap.eraseColor(Color.GREEN);
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mModel.set(ImprovedBookmarkSaveFlowProperties.BOOKMARK_ROW_ICON,
+                    new BitmapDrawable(mActivityTestRule.getActivity().getResources(), bitmap));
+        });
+        mRenderTestRule.render(mContentView, "favicon");
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    public void testPriceTracking() throws IOException {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_VISIBLE, true);
+            mModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED, true);
+        });
+        mRenderTestRule.render(mContentView, "price_tracking");
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    public void testPriceTracking_switchUnchecked() throws IOException {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_VISIBLE, true);
+            mModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED, false);
+        });
+        mRenderTestRule.render(mContentView, "price_tracking_switch_unchecked");
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    public void testPriceTracking_visibleNotEnabled() throws IOException {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_VISIBLE, true);
+            mModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED, true);
+            mModel.set(ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_ENABLED, false);
+        });
+        mRenderTestRule.render(mContentView, "price_tracking_visible_not_enabled");
+    }
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
index 52d59624..256f2a96 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -182,7 +182,7 @@
         FirstRunStatus.setFirstRunFlowComplete(false);
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL),
                 new GURL(LINK_URL), LINK_TEXT, GURL.emptyGURL(), GURL.emptyGURL(), "", null, false,
-                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         int[] expected = {R.id.contextmenu_copy_link_address, R.id.contextmenu_copy_link_text};
 
@@ -225,7 +225,7 @@
     public void testHttpLinkWithPreviewTabEnabled() {
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL),
                 new GURL(LINK_URL), LINK_TEXT, GURL.emptyGURL(), GURL.emptyGURL(), "", null, false,
-                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         FirstRunStatus.setFirstRunFlowComplete(true);
 
@@ -260,7 +260,7 @@
         GURL mailto = new GURL("mailto:fake@email.com");
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL), mailto, "MAIL!",
                 GURL.emptyGURL(), new GURL(PAGE_URL), "", null, false, 0, 0,
-                MenuSourceType.MENU_SOURCE_TOUCH, false);
+                MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         int[] expected = {R.id.contextmenu_copy};
 
@@ -299,7 +299,7 @@
         GURL tel = new GURL("tel:0048221234567");
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL), tel, "PHONE!",
                 GURL.emptyGURL(), new GURL(PAGE_URL), "", null, false, 0, 0,
-                MenuSourceType.MENU_SOURCE_TOUCH, false);
+                MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         int[] expected = {R.id.contextmenu_copy};
 
@@ -342,7 +342,7 @@
         GURL url = new GURL(sourceUrl.getSpec() + "I_love_mouse_video.avi");
         ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.VIDEO,
                 new GURL(PAGE_URL), url, "VIDEO!", GURL.emptyGURL(), sourceUrl, "", null, true, 0,
-                0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+                0, MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         int[] expectedTab1 = {R.id.contextmenu_copy_link_address, R.id.contextmenu_copy_link_text};
 
@@ -388,7 +388,8 @@
         FirstRunStatus.setFirstRunFlowComplete(false);
         ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE,
                 new GURL(PAGE_URL), GURL.emptyGURL(), "", GURL.emptyGURL(), new GURL(IMAGE_SRC_URL),
-                IMAGE_TITLE_TEXT, null, true, 0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+                IMAGE_TITLE_TEXT, null, true, 0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false,
+                /*impression=*/null);
 
         int[] expected = null;
         checkMenuOptions(expected);
@@ -427,7 +428,7 @@
         ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE,
                 new GURL(PAGE_URL), new GURL(LINK_URL), LINK_TEXT, GURL.emptyGURL(),
                 new GURL(IMAGE_SRC_URL), IMAGE_TITLE_TEXT, null, true, 0, 0,
-                MenuSourceType.MENU_SOURCE_TOUCH, false);
+                MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         int[] expected = {R.id.contextmenu_copy_link_address};
 
@@ -477,7 +478,7 @@
 
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL),
                 new GURL(LINK_URL), LINK_TEXT, GURL.emptyGURL(), GURL.emptyGURL(), "", null, false,
-                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         // HTTP scheme should include read later context menu item.
         initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params);
@@ -505,7 +506,7 @@
         // Non-http scheme should not include read later context menu item.
         params = new ContextMenuParams(0, 0, new GURL("chrome://flags"), new GURL(LINK_URL),
                 LINK_TEXT, GURL.emptyGURL(), GURL.emptyGURL(), "", null, false, 0, 0,
-                MenuSourceType.MENU_SOURCE_TOUCH, false);
+                MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
         initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params);
         int[] expected4 = {R.id.contextmenu_open_in_new_tab_in_group,
                 R.id.contextmenu_open_in_new_tab, R.id.contextmenu_open_in_incognito_tab,
@@ -522,7 +523,7 @@
 
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL),
                 new GURL(LINK_URL), LINK_TEXT, GURL.emptyGURL(), GURL.emptyGURL(), "", null, false,
-                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         when(mItemDelegate.isIncognito()).thenReturn(true);
         initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params);
@@ -541,7 +542,7 @@
 
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL),
                 new GURL(LINK_URL), LINK_TEXT, GURL.emptyGURL(), GURL.emptyGURL(), "", null, false,
-                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         when(mItemDelegate.isOpenInOtherWindowSupported()).thenReturn(true);
         initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params);
@@ -562,7 +563,7 @@
 
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL),
                 new GURL(LINK_URL), LINK_TEXT, GURL.emptyGURL(), GURL.emptyGURL(), "", null, false,
-                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+                0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
 
         when(mItemDelegate.canEnterMultiWindowMode()).thenReturn(true);
         initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params);
@@ -581,9 +582,10 @@
     @UiThreadTest
     public void testGetLensIntentParams() {
         when(mItemDelegate.isIncognito()).thenReturn(true);
-        ContextMenuParams params = new ContextMenuParams(0, 0, new GURL(PAGE_URL),
-                new GURL(LINK_URL), LINK_TEXT, GURL.emptyGURL(), new GURL(IMAGE_SRC_URL),
-                IMAGE_TITLE_TEXT, null, false, 0, 0, MenuSourceType.MENU_SOURCE_TOUCH, false);
+        ContextMenuParams params =
+                new ContextMenuParams(0, 0, new GURL(PAGE_URL), new GURL(LINK_URL), LINK_TEXT,
+                        GURL.emptyGURL(), new GURL(IMAGE_SRC_URL), IMAGE_TITLE_TEXT, null, false, 0,
+                        0, MenuSourceType.MENU_SOURCE_TOUCH, false, /*impression=*/null);
         initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params);
 
         LensIntentParams lensIntentParams = mPopulator.getLensIntentParams(
@@ -613,7 +615,8 @@
                 /*unfilteredLinkUrl=*/GURL.emptyGURL(), /*srcUrl=*/GURL.emptyGURL(),
                 /*titleText=*/"", /*referrer=*/null, /*canSaveMedia=*/false,
                 /*triggeringTouchXDp=*/0, /*triggeringTouchXDp=*/0,
-                MenuSourceType.MENU_SOURCE_TOUCH, /*openedFromHighlight=*/true);
+                MenuSourceType.MENU_SOURCE_TOUCH, /*openedFromHighlight=*/true,
+                /*impression=*/null);
 
         // In normal mode, there should be three options: share, remove and learn more.
         int[] normal_expected = {R.id.contextmenu_share_highlight,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
index 4c0da2b..e87abff 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -905,7 +905,8 @@
                 ContextMenuHelper.createForTesting(0, tab.getWebContents());
         ContextMenuParams params = new ContextMenuParams(0, 0, new GURL("http://example.com/"),
                 GURL.emptyGURL(), "", GURL.emptyGURL(), GURL.emptyGURL(), "", null, false, 0, 0,
-                MenuSourceType.MENU_SOURCE_TOUCH, /*getOpenedFromHighlight*/ true);
+                MenuSourceType.MENU_SOURCE_TOUCH, /*getOpenedFromHighlight=*/true,
+                /*impression=*/null);
         ContextMenuPopulatorFactory populatorFactory = new ChromeContextMenuPopulatorFactory(
                 mItemDelegate,
                 ()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuUtilsTest.java
index 722da0d..51eb0f3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuUtilsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuUtilsTest.java
@@ -35,7 +35,7 @@
         ContextMenuParams params = new ContextMenuParams(0,
                 org.chromium.blink_public.common.ContextMenuDataMediaType.IMAGE, GURL.emptyGURL(),
                 GURL.emptyGURL(), sLinkText, GURL.emptyGURL(), new GURL(sSrcUrl), sTitleText, null,
-                false, 0, 0, 0, false);
+                false, 0, 0, 0, false, /*impression=*/null);
 
         assertEquals(sTitleText, ContextMenuUtils.getTitle(params));
     }
@@ -45,7 +45,7 @@
     public void getTitle_noTitleTextHasLinkText() {
         ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE,
                 GURL.emptyGURL(), GURL.emptyGURL(), sLinkText, GURL.emptyGURL(), new GURL(sSrcUrl),
-                "", null, false, 0, 0, 0, false);
+                "", null, false, 0, 0, 0, false, /*impression=*/null);
 
         assertEquals(sLinkText, ContextMenuUtils.getTitle(params));
     }
@@ -55,7 +55,7 @@
     public void getTitle_noTitleTextOrLinkText() {
         ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE,
                 GURL.emptyGURL(), GURL.emptyGURL(), "", GURL.emptyGURL(), new GURL(sSrcUrl), "",
-                null, false, 0, 0, 0, false);
+                null, false, 0, 0, 0, false, /*impression=*/null);
 
         assertEquals(URLUtil.guessFileName(sSrcUrl, null, null), ContextMenuUtils.getTitle(params));
     }
@@ -65,7 +65,7 @@
     public void getTitle_noShareParams() {
         ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.NONE,
                 GURL.emptyGURL(), GURL.emptyGURL(), "", GURL.emptyGURL(), GURL.emptyGURL(), "",
-                null, false, 0, 0, 0, false);
+                null, false, 0, 0, 0, false, /*impression=*/null);
 
         assertEquals("", ContextMenuUtils.getTitle(params));
     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java
index b4ac952..3e5c9cc 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java
@@ -25,6 +25,7 @@
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.DONE_RUNNABLE;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_FIELDS;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.FOOTER_MESSAGE;
+import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.SHOW_REQUIRED_INDICATOR;
 
 import android.app.Activity;
 
@@ -260,11 +261,12 @@
         Assert.assertEquals(hasLengthCounter, field.hasLengthCounter());
     }
 
-    private static void checkUiStringsHaveExpectedValues(PropertyModel editorModel,
+    private static void checkModelHasExpectedValues(PropertyModel editorModel,
             String expectedDeleteTitle, String expectedDeleteText,
             @Nullable String expectedSourceNotice) {
         Assert.assertNotNull(editorModel);
 
+        Assert.assertFalse(editorModel.get(SHOW_REQUIRED_INDICATOR));
         Assert.assertEquals(expectedDeleteTitle, editorModel.get(DELETE_CONFIRMATION_TITLE));
         Assert.assertEquals(expectedDeleteText, editorModel.get(DELETE_CONFIRMATION_TEXT));
         Assert.assertEquals(expectedSourceNotice, editorModel.get(FOOTER_MESSAGE));
@@ -365,7 +367,7 @@
                 mActivity.getString(R.string.autofill_delete_local_address_source_notice);
         final String sourceNotice = null;
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -389,7 +391,7 @@
                         .getString(R.string.autofill_address_will_be_saved_in_account_source_notice)
                         .replace("$1", USER_EMAIL);
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -409,7 +411,7 @@
                 mActivity.getString(R.string.autofill_delete_local_address_source_notice);
         final String sourceNotice = null;
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -433,7 +435,7 @@
                 mActivity.getString(R.string.autofill_delete_sync_address_source_notice);
         final String sourceNotice = null;
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -453,7 +455,7 @@
                 mActivity.getString(R.string.autofill_delete_local_address_source_notice);
         final String sourceNotice = null;
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -477,7 +479,7 @@
                 mActivity.getString(R.string.autofill_delete_sync_address_source_notice);
         final String sourceNotice = null;
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -502,7 +504,7 @@
                         .getString(R.string.autofill_address_will_be_saved_in_account_source_notice)
                         .replace("$1", USER_EMAIL);
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -530,7 +532,7 @@
                         .getString(R.string.autofill_address_will_be_saved_in_account_source_notice)
                         .replace("$1", USER_EMAIL);
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -554,7 +556,7 @@
                         .getString(R.string.autofill_address_will_be_saved_in_account_source_notice)
                         .replace("$1", USER_EMAIL);
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
@@ -578,7 +580,7 @@
                         .getString(R.string.autofill_address_already_saved_in_account_source_notice)
                         .replace("$1", USER_EMAIL);
 
-        checkUiStringsHaveExpectedValues(
+        checkModelHasExpectedValues(
                 mPropertyModelCapture.getValue(), deleteTitle, deleteText, sourceNotice);
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcherTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcherTest.java
index b847e9c..db854e8 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcherTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcherTest.java
@@ -9,6 +9,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -96,6 +97,8 @@
     private ArgumentCaptor<Drawable> mDrawableCaptor;
     @Captor
     private ArgumentCaptor<Pair<Drawable, Drawable>> mFolderDrawablesCaptor;
+    @Captor
+    private ArgumentCaptor<Callback<GURL>> mGURLCallbackCaptor;
 
     private final BookmarkId mFolderId = new BookmarkId(/*id=*/1, BookmarkType.NORMAL);
     private final BookmarkId mBookmarkId1 = new BookmarkId(/*id=*/2, BookmarkType.NORMAL);
@@ -208,7 +211,6 @@
         mBookmarkImageFetcher.fetchImageForBookmarkWithFaviconFallback(
                 mBookmarkItem1, mDrawableCallback);
         verify(mDrawableCallback).onResult(mDrawableCaptor.capture());
-        // There shouldn't be any interaction with large icon bridge since an image was found.
         verify(mLargeIconBridge).getLargeIconForUrl(any(), anyInt(), any());
 
         assertNotNull(mDrawableCaptor.getValue());
@@ -223,4 +225,32 @@
 
         assertNotNull(mDrawableCaptor.getValue());
     }
+
+    @Test
+    public void testFetchImageUrlWithFallbacks() {
+        mBookmarkImageFetcher.fetchImageUrlWithFallbacks(
+                JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), mBookmarkItem1,
+                mDrawableCallback);
+        verify(mDrawableCallback).onResult(mDrawableCaptor.capture());
+        verify(mImageFetcher, times(1)).fetchImage(any(), any());
+        // There shouldn't be any interaction with large icon bridge since an image was found.
+        verify(mLargeIconBridge, times(0)).getLargeIconForUrl(any(), anyInt(), any());
+
+        assertNotNull(mDrawableCaptor.getValue());
+    }
+
+    @Test
+    public void testMediatorDestroyedBeforeCallback() {
+        doNothing().when(mBookmarkModel).getImageUrlForBookmark(any(), any());
+        mBookmarkImageFetcher.fetchImageForBookmarkWithFaviconFallback(
+                mBookmarkItem1, mDrawableCallback);
+
+        verify(mBookmarkModel).getImageUrlForBookmark(any(), mGURLCallbackCaptor.capture());
+        mBookmarkImageFetcher.destroy();
+
+        // Now that mBookmarkImageFetcher is destroyed, all the callbacks should have been
+        // cancelled.
+        mGURLCallbackCaptor.getValue().onResult(JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL));
+        verify(mImageFetcher, times(0)).fetchImage(any(), any());
+    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
index 69d923a..03cf139 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
@@ -428,6 +428,8 @@
         mMediator.onDestroy();
         verify(mBookmarkUiObserver).onDestroy();
         verify(mBookmarkUndoController).destroy();
+        verify(mBookmarkImageFetcher).destroy();
+        verify(mLargeIconBridge).destroy();
     }
 
     @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediatorTest.java
index 533d59c..c28ca1c 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediatorTest.java
@@ -8,16 +8,23 @@
 
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.Features;
+import org.chromium.base.test.util.Features.DisableFeatures;
+import org.chromium.base.test.util.Features.EnableFeatures;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.components.commerce.core.CommerceSubscription;
 import org.chromium.components.commerce.core.IdentifierType;
 import org.chromium.components.commerce.core.ManagementType;
@@ -30,32 +37,41 @@
 @Batch(Batch.UNIT_TESTS)
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE, shadows = {ShadowAppCompatResources.class})
+@DisableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
 public class BookmarkSaveFlowMediatorTest {
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule
+    public final Features.JUnitProcessor mProcessor = new Features.JUnitProcessor();
+
     private BookmarkSaveFlowMediator mMediator;
     private PropertyModel mPropertyModel =
-            new PropertyModel(BookmarkSaveFlowProperties.ALL_PROPERTIES);
+            new PropertyModel(ImprovedBookmarkSaveFlowProperties.ALL_KEYS);
 
     @Mock
-    Context mContext;
+    private Context mContext;
     @Mock
-    Runnable mCloseRunnable;
+    private Runnable mCloseRunnable;
     @Mock
-    BookmarkModel mModel;
+    private BookmarkModel mModel;
     @Mock
-    ShoppingService mShoppingService;
+    private ShoppingService mShoppingService;
     @Mock
-    CommerceSubscription mSubscription;
+    private CommerceSubscription mSubscription;
+    @Mock
+    private BookmarkImageFetcher mBookmarkImageFetcher;
+    @Mock
+    private Profile mProfile;
 
     @Before
     public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mMediator = new BookmarkSaveFlowMediator(
-                mModel, mPropertyModel, mContext, mCloseRunnable, mShoppingService);
+        mMediator = new BookmarkSaveFlowMediator(mModel, mPropertyModel, mContext, mCloseRunnable,
+                mShoppingService, mBookmarkImageFetcher, mProfile);
         mMediator.setSubscriptionForTesting(mSubscription);
     }
 
     @Test
-    public void subscribedInBackground() {
+    public void testSubscribedInBackground() {
         mMediator.setPriceTrackingToggleVisualsOnly(false);
         Assert.assertFalse(
                 mPropertyModel.get(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLED));
@@ -75,10 +91,26 @@
                 .unsubscribe(Mockito.any(CommerceSubscription.class), Mockito.any());
     }
 
+    @Test
+    @EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
+    public void testSubscribedInBackground_improved() {
+        mMediator.setPriceTrackingToggleVisualsOnly(false);
+        Assert.assertFalse(mPropertyModel.get(
+                ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED));
+
+        mMediator.onSubscribe(mSubscription, true);
+        Assert.assertTrue(mPropertyModel.get(
+                ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED));
+        Mockito.verify(mShoppingService, Mockito.never())
+                .subscribe(Mockito.any(CommerceSubscription.class), Mockito.any());
+        Mockito.verify(mShoppingService, Mockito.never())
+                .unsubscribe(Mockito.any(CommerceSubscription.class), Mockito.any());
+    }
+
     // Ensure the toggle logic still works when the subscription object changes but has identical
     // information.
     @Test
-    public void subscribed_DifferentObjects() {
+    public void testSubscribed_differentObjects() {
         String clusterId = "1234";
         CommerceSubscription original = new CommerceSubscription(SubscriptionType.PRICE_TRACK,
                 IdentifierType.PRODUCT_CLUSTER_ID, clusterId, ManagementType.USER_MANAGED, null);
@@ -107,7 +139,31 @@
     }
 
     @Test
-    public void unsubscribedInBackground() {
+    @EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
+    public void testSubscribed_differentObjects_improved() {
+        String clusterId = "1234";
+        CommerceSubscription original = new CommerceSubscription(SubscriptionType.PRICE_TRACK,
+                IdentifierType.PRODUCT_CLUSTER_ID, clusterId, ManagementType.USER_MANAGED, null);
+        CommerceSubscription clone = new CommerceSubscription(SubscriptionType.PRICE_TRACK,
+                IdentifierType.PRODUCT_CLUSTER_ID, clusterId, ManagementType.USER_MANAGED, null);
+
+        mMediator.setSubscriptionForTesting(original);
+
+        mMediator.setPriceTrackingToggleVisualsOnly(false);
+        Assert.assertFalse(mPropertyModel.get(
+                ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED));
+
+        mMediator.onSubscribe(clone, true);
+        Assert.assertTrue(mPropertyModel.get(
+                ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED));
+        Mockito.verify(mShoppingService, Mockito.never())
+                .subscribe(Mockito.any(CommerceSubscription.class), Mockito.any());
+        Mockito.verify(mShoppingService, Mockito.never())
+                .unsubscribe(Mockito.any(CommerceSubscription.class), Mockito.any());
+    }
+
+    @Test
+    public void testUnsubscribedInBackground() {
         mMediator.setPriceTrackingToggleVisualsOnly(true);
         Assert.assertTrue(
                 mPropertyModel.get(BookmarkSaveFlowProperties.NOTIFICATION_SWITCH_TOGGLED));
@@ -126,4 +182,20 @@
         Mockito.verify(mShoppingService, Mockito.never())
                 .unsubscribe(Mockito.any(CommerceSubscription.class), Mockito.any());
     }
+
+    @Test
+    @EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
+    public void testUnsubscribedInBackground_improved() {
+        mMediator.setPriceTrackingToggleVisualsOnly(true);
+        Assert.assertTrue(mPropertyModel.get(
+                ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED));
+
+        mMediator.onUnsubscribe(mSubscription, true);
+        Assert.assertFalse(mPropertyModel.get(
+                ImprovedBookmarkSaveFlowProperties.PRICE_TRACKING_SWITCH_CHECKED));
+        Mockito.verify(mShoppingService, Mockito.never())
+                .subscribe(Mockito.any(CommerceSubscription.class), Mockito.any());
+        Mockito.verify(mShoppingService, Mockito.never())
+                .unsubscribe(Mockito.any(CommerceSubscription.class), Mockito.any());
+    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java
index 75ca658..41da111 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java
@@ -9,6 +9,7 @@
 import android.content.Context;
 import android.view.ContextThemeWrapper;
 
+import androidx.appcompat.content.res.AppCompatResources;
 import androidx.test.core.app.ApplicationProvider;
 
 import org.junit.After;
@@ -31,13 +32,16 @@
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerHost;
 import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
 import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
+import org.chromium.chrome.browser.compositor.layouts.components.TintedCompositorButton;
 import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelperManager.TabModelStartupInfo;
 import org.chromium.chrome.browser.compositor.scene_layer.TabStripSceneLayer;
 import org.chromium.chrome.browser.compositor.scene_layer.TabStripSceneLayerJni;
+import org.chromium.chrome.browser.flags.BooleanCachedFieldTrialParameter;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial;
+import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.components.browser_ui.styles.ChromeColors;
 import org.chromium.ui.base.LocalizationUtils;
@@ -97,17 +101,11 @@
                 mLifecycleDispatcher);
     }
 
-    private void initializeFolioTest() {
-        // Since we check TSR arm and determine model selector button width inside constructor, so
-        // need to set TSR arm before initialize test.
-        TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_FOLIO.setForTesting(true);
-        initializeTest();
-    }
-
-    private void initializeDetachedTest() {
-        // Since we check TSR arm and determine model selector button width inside constructor, so
-        // need to set TSR arm before initialize test.
-        TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_DETACHED.setForTesting(true);
+    private void initializeTestWithTsrArm(BooleanCachedFieldTrialParameter param) {
+        // Since we check TSR arm and determine model selector button properties(eg. color/bg color,
+        // width, etc) inside constructor, so need to set TSR arm before initialize test each time
+        // we switch arm.
+        param.setForTesting(true);
         initializeTest();
     }
 
@@ -133,7 +131,7 @@
     @Feature("Tab Strip Redesign")
     public void testModelSelectorButtonPosition_Folio() {
         // setup
-        initializeFolioTest();
+        initializeTestWithTsrArm(TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_FOLIO);
 
         // Set model selector button position.
         mStripLayoutHelperManager.onSizeChanged(
@@ -149,7 +147,7 @@
     @Feature("Tab Strip Redesign")
     public void testModelSelectorButtonPosition_RTL_Folio() {
         // setup
-        initializeFolioTest();
+        initializeTestWithTsrArm(TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_FOLIO);
 
         // Set model selector button position.
         LocalizationUtils.setRtlForTesting(true);
@@ -165,7 +163,7 @@
     @Feature("Tab Strip Redesign")
     public void testModelSelectorButtonPosition_Detached() {
         // setup
-        initializeDetachedTest();
+        initializeTestWithTsrArm(TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_DETACHED);
 
         // Set model selector button position.
         mStripLayoutHelperManager.onSizeChanged(
@@ -181,7 +179,7 @@
     @Feature("Tab Strip Redesign")
     public void testModelSelectorButtonPosition_RTL_Detached() {
         // setup
-        initializeDetachedTest();
+        initializeTestWithTsrArm(TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_DETACHED);
 
         // Set model selector button position.
         LocalizationUtils.setRtlForTesting(true);
@@ -293,6 +291,30 @@
     }
 
     @Test
+    @Feature("Tab Strip Redesign")
+    public void testButtonIconColor() {
+        // Verify TSR button icon color.
+        assertEquals("Unexpected incognito button color.",
+                mContext.getResources().getColor(R.color.model_selector_button_icon_color),
+                ((TintedCompositorButton) mStripLayoutHelperManager.getModelSelectorButton())
+                        .getTint());
+    }
+
+    @Test
+    @Feature("Tab Strip Redesign")
+    public void testButtonIconColor_DisableButtonStyle() {
+        // setup
+        initializeTestWithTsrArm(TabUiFeatureUtilities.TAB_STRIP_REDESIGN_DISABLE_BUTTON_STYLE);
+
+        // Verify TSR button icon color after disabling button style.
+        assertEquals("Unexpected incognito button color.",
+                AppCompatResources.getColorStateList(mContext, R.color.default_icon_color_tint_list)
+                        .getDefaultColor(),
+                ((TintedCompositorButton) mStripLayoutHelperManager.getModelSelectorButton())
+                        .getTint());
+    }
+
+    @Test
     @Feature("TabStripPerformance")
     public void testSetTabModelStartupInfo() {
         // Setup
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
index 14b45b13..97836f2 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -27,10 +27,14 @@
 import android.content.res.Resources;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
+import android.view.ContextThemeWrapper;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
 import android.view.ViewGroup.MarginLayoutParams;
 
+import androidx.appcompat.content.res.AppCompatResources;
+import androidx.test.core.app.ApplicationProvider;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -94,6 +98,7 @@
     private StripLayoutHelperManager mStripLayoutHelperManager;
 
     private Activity mActivity;
+    private Context mContext;
     private TestTabModel mModel = new TestTabModel();
     private StripLayoutHelper mStripLayoutHelper;
     private boolean mIncognito;
@@ -136,6 +141,8 @@
         MockitoAnnotations.initMocks(this);
         when(mModelSelectorBtn.isVisible()).thenReturn(true);
         when(mTabGroupModelFilter.hasOtherRelatedTabs(any())).thenReturn(false);
+        mContext = new ContextThemeWrapper(
+                ApplicationProvider.getApplicationContext(), R.style.Theme_BrowserUI_DayNight);
 
         mActivity = Robolectric.setupActivity(Activity.class);
         mActivity.setTheme(org.chromium.chrome.R.style.Theme_BrowserUI);
@@ -771,6 +778,30 @@
     }
 
     @Test
+    @Feature("Tab Strip Redesign")
+    public void testNewTabButtonStyle_ButtonStyleDisabled() {
+        // Setup
+        TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_FOLIO.setForTesting(true);
+        TabUiFeatureUtilities.TAB_STRIP_REDESIGN_DISABLE_BUTTON_STYLE.setForTesting(true);
+        int tabCount = 1;
+        initializeTest(false, false, false, 0, tabCount);
+        mStripLayoutHelper.onSizeChanged(SCREEN_WIDTH, SCREEN_HEIGHT, false, TIMESTAMP);
+        mStripLayoutHelper.updateLayout(TIMESTAMP);
+
+        // Verify new tab button position.
+        // tabWidth(237) + tabOverLapWidth(28) + folioXOffset(6) = 271
+        assertEquals("New tab button position is not as expected", 271.f,
+                mStripLayoutHelper.getNewTabButton().getX(), EPSILON);
+
+        assertEquals("Unexpected incognito button color.",
+                AppCompatResources.getColorStateList(mContext, R.color.default_icon_color_tint_list)
+                        .getDefaultColor(),
+                ((org.chromium.chrome.browser.compositor.layouts.components.TintedCompositorButton)
+                                mStripLayoutHelper.getNewTabButton())
+                        .getTint());
+    }
+
+    @Test
     public void testScrollOffset_OnResume_StartOnLeft_SelectedRightmostTab() {
         // Arrange: Initialize tabs with last tab selected.
         initializeTest(false, true, false, 9, 10);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayerTest.java
index 03fb93d..642fd2ac 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayerTest.java
@@ -103,7 +103,7 @@
     private void initializeTest() {
         mTabStripSceneLayer = new TabStripSceneLayer(mContext);
         when(mTabStripSceneMock.init(
-                     mTabStripSceneLayer, ChromeFeatureList.sTabStripRedesign.isEnabled()))
+                     mTabStripSceneLayer, ChromeFeatureList.sTabStripRedesign.isEnabled(), false))
                 .thenReturn(1L);
         mModelSelectorButton = new TintedCompositorButton(
                 mContext, 36.f, 36.f, mCompositorOnClickHandler, R.drawable.ic_new_tab_button);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinatorTest.java
index 6a23298..6bbf5a0 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinatorTest.java
@@ -153,7 +153,7 @@
     public void testGetItemListWithImageLink() {
         final ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE,
                 GURL.emptyGURL(), GURL.emptyGURL(), "", GURL.emptyGURL(), GURL.emptyGURL(), "",
-                null, false, 0, 0, 0, false);
+                null, false, 0, 0, 0, false, /*impression=*/null);
         List<Pair<Integer, ModelList>> rawItems = new ArrayList<>();
         // Link items
         ModelList groupOne = new ModelList();
@@ -193,7 +193,7 @@
         // initialized. mediaType here doesn't have any effect on what we're testing.
         final ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE,
                 GURL.emptyGURL(), GURL.emptyGURL(), "", GURL.emptyGURL(), GURL.emptyGURL(), "",
-                null, false, 0, 0, 0, false);
+                null, false, 0, 0, 0, false, /*impression=*/null);
         List<Pair<Integer, ModelList>> rawItems = new ArrayList<>();
         // Link items
         ModelList groupOne = new ModelList();
@@ -219,7 +219,7 @@
     public void testGetItemListWithVideo() {
         final ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.VIDEO,
                 GURL.emptyGURL(), GURL.emptyGURL(), "", GURL.emptyGURL(), GURL.emptyGURL(), "",
-                null, false, 0, 0, 0, false);
+                null, false, 0, 0, 0, false, /*impression=*/null);
         List<Pair<Integer, ModelList>> rawItems = new ArrayList<>();
         // Video items
         ModelList groupOne = new ModelList();
@@ -404,7 +404,7 @@
             int triggeringTouchXDp, int triggeringTouchYDp) {
         final ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE,
                 GURL.emptyGURL(), GURL.emptyGURL(), "", GURL.emptyGURL(), GURL.emptyGURL(), "",
-                null, false, triggeringTouchXDp, triggeringTouchYDp, 0, false);
+                null, false, triggeringTouchXDp, triggeringTouchYDp, 0, false, /*impression=*/null);
 
         final WindowAndroid windowAndroid = Mockito.mock(WindowAndroid.class);
         doReturn(new WeakReference<Activity>(mActivity)).when(windowAndroid).getActivity();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediatorTest.java
index 54d2606..7e371a74 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediatorTest.java
@@ -82,9 +82,9 @@
         PropertyModel model =
                 new PropertyModel.Builder(ContextMenuHeaderProperties.ALL_KEYS).build();
         final GURL url = JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL);
-        final ContextMenuParams params =
-                new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE, url, GURL.emptyGURL(), "",
-                        GURL.emptyGURL(), GURL.emptyGURL(), "", null, false, 0, 0, 0, false);
+        final ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.IMAGE,
+                url, GURL.emptyGURL(), "", GURL.emptyGURL(), GURL.emptyGURL(), "", null, false, 0,
+                0, 0, false, /*impression=*/null);
         final ContextMenuHeaderMediator mediator =
                 new ContextMenuHeaderMediator(mActivity, model, params, mProfile, mNativeDelegate);
 
@@ -113,7 +113,7 @@
                 new PropertyModel.Builder(ContextMenuHeaderProperties.ALL_KEYS).build();
         final ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.VIDEO,
                 GURL.emptyGURL(), GURL.emptyGURL(), "", GURL.emptyGURL(), GURL.emptyGURL(), "",
-                null, false, 0, 0, 0, false);
+                null, false, 0, 0, 0, false, /*impression=*/null);
         final ContextMenuHeaderMediator mediator =
                 new ContextMenuHeaderMediator(mActivity, model, params, mProfile, mNativeDelegate);
 
@@ -136,7 +136,7 @@
         final GURL linkUrl = JUnitTestGURLs.getGURL(JUnitTestGURLs.URL_1);
         final ContextMenuParams params = new ContextMenuParams(0, ContextMenuDataMediaType.FILE,
                 GURL.emptyGURL(), linkUrl, JUnitTestGURLs.URL_1, GURL.emptyGURL(), GURL.emptyGURL(),
-                "", null, false, 0, 0, 0, false);
+                "", null, false, 0, 0, 0, false, /*impression=*/null);
         final ContextMenuHeaderMediator mediator =
                 new ContextMenuHeaderMediator(mActivity, model, params, mProfile, mNativeDelegate);
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
index b65f2b8..6bad75330 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
@@ -19,8 +19,6 @@
 import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.ACTIVITY_SIDE_SHEET_POSITION_DEFAULT;
 import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.ACTIVITY_SIDE_SHEET_POSITION_END;
 import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.ACTIVITY_SIDE_SHEET_POSITION_START;
-import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.ACTIVITY_SIDE_SHEET_SLIDE_IN_DEFAULT;
-import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_BOTTOM;
 import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE;
 
 import android.app.Activity;
@@ -428,31 +426,6 @@
                 new CustomTabIntentDataProvider(new Intent(), mContext, COLOR_SCHEME_LIGHT);
         assertEquals("Should return ..SLIDE_IN_FROM_SIDE for the default slide-in behavior",
                 ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE, dataProvider.getSideSheetSlideInBehavior());
-
-        // Default
-        Intent intent = new Intent().putExtra(
-                CustomTabIntentDataProvider.EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR,
-                ACTIVITY_SIDE_SHEET_SLIDE_IN_DEFAULT);
-        dataProvider = new CustomTabIntentDataProvider(intent, mContext, COLOR_SCHEME_LIGHT);
-        assertEquals("Should return ..SLIDE_IN_FROM_SIDE", ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE,
-                dataProvider.getSideSheetSlideInBehavior());
-
-        // Bottom
-        intent = new Intent().putExtra(
-                CustomTabIntentDataProvider.EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR,
-                ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_BOTTOM);
-        dataProvider = new CustomTabIntentDataProvider(intent, mContext, COLOR_SCHEME_LIGHT);
-        assertEquals("Should return ..SLIDE_IN_FROM_BOTTOM",
-                ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_BOTTOM,
-                dataProvider.getSideSheetSlideInBehavior());
-
-        // Side
-        intent = new Intent().putExtra(
-                CustomTabIntentDataProvider.EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR,
-                ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE);
-        dataProvider = new CustomTabIntentDataProvider(intent, mContext, COLOR_SCHEME_LIGHT);
-        assertEquals("Should return ..SLIDE_IN_FROM_SIDE", ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE,
-                dataProvider.getSideSheetSlideInBehavior());
     }
 
     @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/payments/AddressEditorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/payments/AddressEditorTest.java
index b2431b6..256728f3 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/payments/AddressEditorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/payments/AddressEditorTest.java
@@ -21,15 +21,12 @@
 import static org.mockito.Mockito.when;
 
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.CANCEL_RUNNABLE;
-import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.DELETE_CONFIRMATION_TEXT;
-import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.DELETE_CONFIRMATION_TITLE;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.DONE_RUNNABLE;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_FIELDS;
-import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.FOOTER_MESSAGE;
+import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.SHOW_REQUIRED_INDICATOR;
 
 import android.app.Activity;
 
-import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
 import org.junit.After;
@@ -215,16 +212,6 @@
         assertEquals(hasLengthCounter, field.hasLengthCounter());
     }
 
-    private static void checkUiStringsHaveExpectedValues(PropertyModel editorModel,
-            String expectedDeleteTitle, String expectedDeleteText,
-            @Nullable String expectedSourceNotice) {
-        assertNotNull(editorModel);
-
-        assertEquals(expectedDeleteTitle, editorModel.get(DELETE_CONFIRMATION_TITLE));
-        assertEquals(expectedDeleteText, editorModel.get(DELETE_CONFIRMATION_TEXT));
-        assertEquals(expectedSourceNotice, editorModel.get(FOOTER_MESSAGE));
-    }
-
     private void validateShownFields(PropertyModel editorModel, AutofillProfile profile) {
         assertNotNull(editorModel);
         List<EditorFieldModel> editorFields = editorModel.get(EDITOR_FIELDS);
@@ -286,6 +273,24 @@
 
     @Test
     @SmallTest
+    public void validateRequiredFieldIndicator() {
+        setUpAddressUiComponents(new ArrayList(), /*countryCode=*/"US");
+        mAddressEditor = new AddressEditor(/*saveToDisk=*/false);
+        mAddressEditor.setEditorDialog(mEditorDialog);
+        doAnswer(unused -> {
+            mAddressEditor.onSubKeysReceived(null, null);
+            return null;
+        })
+                .when(mPersonalDataManager)
+                .getRegionSubKeys(anyString(), any());
+        mAddressEditor.edit(new AutofillAddress(mActivity, sProfile), unused -> {});
+
+        assertNotNull(mPropertyModelCapture.getValue());
+        assertTrue(mPropertyModelCapture.getValue().get(SHOW_REQUIRED_INDICATOR));
+    }
+
+    @Test
+    @SmallTest
     public void validateDefaultFields() {
         setUpAddressUiComponents(new ArrayList(), /*countryCode=*/"US");
         mAddressEditor = new AddressEditor(/*saveToDisk=*/false);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/payments/ContactEditorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/payments/ContactEditorTest.java
index 80f593e..8ce5f2d 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/payments/ContactEditorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/payments/ContactEditorTest.java
@@ -15,6 +15,7 @@
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.CANCEL_RUNNABLE;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.DONE_RUNNABLE;
 import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.EDITOR_FIELDS;
+import static org.chromium.chrome.browser.autofill.prefeditor.EditorProperties.SHOW_REQUIRED_INDICATOR;
 
 import android.app.Activity;
 
@@ -99,6 +100,20 @@
 
     @Test
     @SmallTest
+    public void validateRequiredFieldIndicator() {
+        ContactEditor editor = new ContactEditor(/*requestPayerName=*/true,
+                /*requestPayerPhone=*/false,
+                /*requestPayerEmail=*/false,
+                /*saveToDisk=*/false);
+        editor.setEditorDialog(mEditorDialog);
+        editor.edit(null, unused -> {});
+
+        assertNotNull(mPropertyModelCapture.getValue());
+        assertTrue(mPropertyModelCapture.getValue().get(SHOW_REQUIRED_INDICATOR));
+    }
+
+    @Test
+    @SmallTest
     public void requestName_NewContact() {
         ContactEditor editor = new ContactEditor(/*requestPayerName=*/true,
                 /*requestPayerPhone=*/false,
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 5a9818b..8b28cac 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -134,6 +134,10 @@
     Finalizing...
   </message>
 
+  <message name="IDS_GETTING_DEVICE_READY" desc="Message that the system is getting the device ready" translateable="false">
+    Getting the device ready...
+  </message>
+
   <!-- Cellular Setup UI Strings -->
   <message name="IDS_CELLULAR_SETUP_BACK_LABEL" desc="Label for button to go to previous screen during cellular setup">
     Back
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index 5d434ad90..e33aa6f 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -827,7 +827,7 @@
       </if>
 
       <message name="IDS_VIEW_PASSWORDS" desc="Item in the app menu which shows Password Manager page">
-        Password Manager
+        P&amp;assword Manager
       </message>
 
       <!-- Chrome sign-in page -->
diff --git a/chrome/app/chromium_strings_grd/IDS_VIEW_PASSWORDS.png.sha1 b/chrome/app/chromium_strings_grd/IDS_VIEW_PASSWORDS.png.sha1
index 45eb682..bcefd0c 100644
--- a/chrome/app/chromium_strings_grd/IDS_VIEW_PASSWORDS.png.sha1
+++ b/chrome/app/chromium_strings_grd/IDS_VIEW_PASSWORDS.png.sha1
@@ -1 +1 @@
-59af7c027036dbc173f47b8040265340c49c742d
\ No newline at end of file
+364db295edba8a38570266a2ad2f31b2008e3eaa
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 1cc38373..0f37c10 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -1186,10 +1186,7 @@
           <message name="IDS_FIND_AND_EDIT_MENU" desc="The text label of the Find and edit sub menu item">
             &amp;Find and edit
           </message>
-          <message name="IDS_PASSWORD_MANAGER_SUBMENU_OPTION" desc="The text label of the password manager for the passwords and autofill submenu">
-            &amp;Google Password Manager
-          </message>
-            <message name="IDS_PAYMENT_METHOD_SUBMENU_OPTION" desc="The text label of the payment method for the passwords and autofill submenu">
+          <message name="IDS_PAYMENT_METHOD_SUBMENU_OPTION" desc="The text label of the payment method for the passwords and autofill submenu">
             &amp;Payment methods
           </message>
           <message name="IDS_SAVE_PAGE" desc="The text label of the Save Page As menu item">
@@ -1229,7 +1226,7 @@
             Copy &amp;URL
           </message>
           <message name="IDS_OPEN_IN_APP_WINDOW" desc="The text label of the menu item for moving the current tab to a standalone app window">
-            Open in <ph name="APP">$1<ex>Gmail App</ex></ph>
+            &amp;Open in <ph name="APP">$1<ex>Gmail App</ex></ph>
           </message>
           <message name="IDS_MOVE_TAB_TO_NEW_WINDOW" desc="The text label of the Move Tab to Window menu item.">
             Move tab to new window
@@ -1287,9 +1284,6 @@
           <message name="IDS_FIND_AND_EDIT_MENU" desc="In Title Case: The text label of the Find and edit sub menu item">
             &amp;Find and Edit
           </message>
-          <message name="IDS_PASSWORD_MANAGER_SUBMENU_OPTION" desc="In Title Case: The text label of the password manager for the passwords and autofill submenu">
-            &amp;Google Password Manager
-          </message>
           <message name="IDS_PAYMENT_METHOD_SUBMENU_OPTION" desc="In Title Case: The text label of the payment method for the passwords and autofill submenu">
             &amp;Payment Methods
           </message>
@@ -1330,7 +1324,7 @@
             Copy &amp;URL
           </message>
           <message name="IDS_OPEN_IN_APP_WINDOW" desc="In Title Case: The text label of the menu item for moving the current tab to a standalone app window">
-            Open in <ph name="APP">$1<ex>Gmail App</ex></ph>
+            &amp;Open in <ph name="APP">$1<ex>Gmail App</ex></ph>
           </message>
           <message name="IDS_MOVE_TAB_TO_NEW_WINDOW" desc="In Title Case: The text label of the Move Tab to New Window menu item.">
             Move Tab to New Window
@@ -1542,7 +1536,7 @@
           Performance
         </message>
         <message name="IDS_SETTINGS" desc="The text label of the Settings menu item">
-          &amp;Settings
+          Settin&amp;gs
         </message>
         <message name="IDS_OPTIONS" desc="The text label of the Options menu item">
           &amp;Options
@@ -3127,24 +3121,24 @@
       <!-- "Create application shortcuts" menu item -->
       <if expr="use_titlecase">
         <message name="IDS_ADD_TO_OS_LAUNCH_SURFACE" desc="In Title Case: Menu text for adding a bookmark app shortcut to the operating system.">
-          Create Shortcut...
+          Create &amp;Shortcut...
         </message>
       </if>
       <if expr="not use_titlecase">
         <message name="IDS_ADD_TO_OS_LAUNCH_SURFACE" desc="Menu text for adding a bookmark app shortcut to the operating system.">
-          Create shortcut...
+          Create &amp;shortcut...
         </message>
       </if>
 
       <!-- "Install web app" menu item -->
       <if expr="use_titlecase">
         <message name="IDS_INSTALL_TO_OS_LAUNCH_SURFACE" desc="In Title Case: Menu text for installing a web app to the operating system.">
-          Install <ph name="APP">$1<ex>Gmail</ex></ph>...
+          &amp;Install <ph name="APP">$1<ex>Gmail</ex></ph>...
         </message>
       </if>
       <if expr="not use_titlecase">
         <message name="IDS_INSTALL_TO_OS_LAUNCH_SURFACE" desc="Menu text for installing a web app to the operating system.">
-          Install <ph name="APP">$1<ex>Gmail</ex></ph>...
+          &amp;Install <ph name="APP">$1<ex>Gmail</ex></ph>...
         </message>
       </if>
 
@@ -5272,6 +5266,9 @@
         </message>
 
         <if expr="not use_titlecase">
+          <message name="IDS_EXTENSIONS_CONTEXT_MENU_SITE_PERMISSIONS" desc="The label in an extension's context menu for the submenu specifying the extension site permissions (sentence case).">
+            Site permissions
+          </message>
           <message name="IDS_EXTENSIONS_CONTEXT_MENU_CANT_ACCESS_PAGE" desc="The label in an extension's context menu indicating the extension cannot access the current page. (sentence case)">
             Can't read or change site's data
           </message>
@@ -5285,7 +5282,7 @@
             You previously chose to not allow any extensions on <ph name="ORIGIN">$1<ex>google.com</ex></ph>
           </message>
           <message name="IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_CLICK_V2" desc="The label in an extension's context menu to allow the extension access to the page only when the user clicks on the extension action (sentence case).">
-            When I click the extension
+            Ask on every visit
           </message>
           <message name="IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_SITE_V2" desc="The label in an extension's context menu to always allow the extension access to the current origin (sentence case).">
             Always on <ph name="ORIGIN">$1<ex>google.com</ex></ph>
@@ -5340,6 +5337,9 @@
           </message>
         </if>
         <if expr="use_titlecase">
+          <message name="IDS_EXTENSIONS_CONTEXT_MENU_SITE_PERMISSIONS" desc="The label in an extension's context menu for the submenu specifying the extension site permissions (title case).">
+            Site Permissions
+          </message>
           <message name="IDS_EXTENSIONS_CONTEXT_MENU_CANT_ACCESS_PAGE" desc="The label in an extension's context menu indicating the extension cannot access the current page. (title case)">
             Can't Read or Change Site's Data
           </message>
@@ -5353,7 +5353,7 @@
             You Previously Chose To Not Allow Any Extensions On <ph name="ORIGIN">$1<ex>google.com</ex></ph>
           </message>
           <message name="IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_CLICK_V2" desc="The label in an extension's context menu to allow the extension access to the page only when the user clicks on the extension action (title case).">
-            When I Click the Extension
+            Ask on Every Visit
           </message>
           <message name="IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_SITE_V2" desc="The label in an extension's context menu to always allow the extension access to the current origin (title case).">
             Always on <ph name="ORIGIN">$1<ex>google.com</ex></ph>
@@ -9941,12 +9941,12 @@
       <if expr="use_titlecase">
         <then>
           <message name="IDS_MENU_SEND_TAB_TO_SELF" desc="In Title Case: The label of a menu entry to share the current tab to other devices">
-            Send to Your Devices
+            Send to Your &amp;Devices
           </message>
         </then>
         <else>
           <message name="IDS_MENU_SEND_TAB_TO_SELF" desc="The label of a menu entry to share the current tab to other devices">
-            Send to your devices
+            Send to your &amp;devices
           </message>
         </else>
       </if>
@@ -10025,6 +10025,10 @@
           desc="Button text for the QR Code generator's download button.">
         Download
       </message>
+      <message name="IDS_BROWSER_SHARING_QR_CODE_DIALOG_COPY_BUTTON_LABEL"
+          desc="Button text for the QR Code generator's copy button.">
+        Copy
+      </message>
       <message name="IDS_BROWSER_SHARING_QR_CODE_DIALOG_ERROR_TOO_LONG"
           desc="Error message displayed when a URL exceeds the limit for which we can generate a QR Code.">
         Use <ph name="CHARACTER_LIMIT">$1<ex>300</ex></ph> characters or fewer
diff --git a/chrome/app/generated_resources_grd/IDS_ADD_TO_OS_LAUNCH_SURFACE.png.sha1 b/chrome/app/generated_resources_grd/IDS_ADD_TO_OS_LAUNCH_SURFACE.png.sha1
new file mode 100644
index 0000000..74aacdc6
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_ADD_TO_OS_LAUNCH_SURFACE.png.sha1
@@ -0,0 +1 @@
+e2b09a3a24a82183995e6b0ad6ebb12ec70aa77e
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_BROWSER_SHARING_QR_CODE_DIALOG_COPY_BUTTON_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_BROWSER_SHARING_QR_CODE_DIALOG_COPY_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..f951de3
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_BROWSER_SHARING_QR_CODE_DIALOG_COPY_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+8777d77fe523c99d9058312c3bb014ee2d87ec95
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_CLICK_V2.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_CLICK_V2.png.sha1
index b5254bc..c3668ae 100644
--- a/chrome/app/generated_resources_grd/IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_CLICK_V2.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_CLICK_V2.png.sha1
@@ -1 +1 @@
-4fb5e264123d559f26c85dd06c3cebdd1aac36d6
\ No newline at end of file
+653b5caac7bee71a051dd8b41507b8e5ede25b11
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSIONS_CONTEXT_MENU_SITE_PERMISSIONS.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSIONS_CONTEXT_MENU_SITE_PERMISSIONS.png.sha1
new file mode 100644
index 0000000..c3668ae
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_EXTENSIONS_CONTEXT_MENU_SITE_PERMISSIONS.png.sha1
@@ -0,0 +1 @@
+653b5caac7bee71a051dd8b41507b8e5ede25b11
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_INSTALL_TO_OS_LAUNCH_SURFACE.png.sha1 b/chrome/app/generated_resources_grd/IDS_INSTALL_TO_OS_LAUNCH_SURFACE.png.sha1
new file mode 100644
index 0000000..f17aa74
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_INSTALL_TO_OS_LAUNCH_SURFACE.png.sha1
@@ -0,0 +1 @@
+1735b97814dff80eba787840beead87616337af1
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_MENU_SEND_TAB_TO_SELF.png.sha1 b/chrome/app/generated_resources_grd/IDS_MENU_SEND_TAB_TO_SELF.png.sha1
index dff18a17..ca7d1b23 100644
--- a/chrome/app/generated_resources_grd/IDS_MENU_SEND_TAB_TO_SELF.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_MENU_SEND_TAB_TO_SELF.png.sha1
@@ -1 +1 @@
-c975b451ac27079008716cf1fad73539c42f118d
\ No newline at end of file
+18caa2f7acb46e879b01336491441f7df721fc39
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_OPEN_IN_APP_WINDOW.png.sha1 b/chrome/app/generated_resources_grd/IDS_OPEN_IN_APP_WINDOW.png.sha1
new file mode 100644
index 0000000..fa8bb9b
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_OPEN_IN_APP_WINDOW.png.sha1
@@ -0,0 +1 @@
+c389edf530bb369a787b4ae82ce2e98dae976910
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_PASSWORD_MANAGER_SUBMENU_OPTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_PASSWORD_MANAGER_SUBMENU_OPTION.png.sha1
deleted file mode 100644
index 2498321b..0000000
--- a/chrome/app/generated_resources_grd/IDS_PASSWORD_MANAGER_SUBMENU_OPTION.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-37e6256196fb921f35c48e5afcbf3ef1d7f18dce
\ No newline at end of file
diff --git a/chrome/app/gmc_strings.grdp b/chrome/app/gmc_strings.grdp
index 1559ecf2..657ec95 100644
--- a/chrome/app/gmc_strings.grdp
+++ b/chrome/app/gmc_strings.grdp
@@ -31,6 +31,15 @@
   <message name="IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED" desc="Error message shown when a OS reboot is required to install the Live Caption files.">
    Can't install speech files. Your device needs to be updated. Restart your device and try again.
   </message>
+  <message name="IDS_GLOBAL_MEDIA_CONTROLS_CAPTION_SETTINGS" desc="Label for the link to the caption settings page.">
+   Caption settings
+  </message>
+  <message name="IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_SUBTITLE" desc="Subtitle for the live translate toggle control.">
+   Automatically translates captions
+  </message>
+  <message name="IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_TARGET_LANGUAGE_ACCNAME" desc="Accessible name for the target language selection combobox.">
+   Choose the language to translate the captions to
+  </message>
   <message name="IDS_GLOBAL_MEDIA_CONTROLS_DIALOG_NAME" desc="A11y name for the Global Media Controls dialog.">
    Global Media Controls
   </message>
diff --git a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_CAPTION_SETTINGS.png.sha1 b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_CAPTION_SETTINGS.png.sha1
new file mode 100644
index 0000000..e2e02bf
--- /dev/null
+++ b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_CAPTION_SETTINGS.png.sha1
@@ -0,0 +1 @@
+3cd6875130da6b9a6de82d8af4cd786f5e9f6223
\ No newline at end of file
diff --git a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_SUBTITLE.png.sha1 b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_SUBTITLE.png.sha1
new file mode 100644
index 0000000..e2e02bf
--- /dev/null
+++ b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_SUBTITLE.png.sha1
@@ -0,0 +1 @@
+3cd6875130da6b9a6de82d8af4cd786f5e9f6223
\ No newline at end of file
diff --git a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_TARGET_LANGUAGE_ACCNAME.png.sha1 b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_TARGET_LANGUAGE_ACCNAME.png.sha1
new file mode 100644
index 0000000..e2e02bf
--- /dev/null
+++ b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_TARGET_LANGUAGE_ACCNAME.png.sha1
@@ -0,0 +1 @@
+3cd6875130da6b9a6de82d8af4cd786f5e9f6223
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index 3ff5a21..c727da1 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -865,7 +865,7 @@
       </if>
 
       <message name="IDS_VIEW_PASSWORDS" desc="Item in the app menu which shows Password Manager page">
-        Google Password Manager
+        Google P&amp;assword Manager
       </message>
 
       <!-- Chrome sign-in page -->
diff --git a/chrome/app/google_chrome_strings_grd/IDS_VIEW_PASSWORDS.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_VIEW_PASSWORDS.png.sha1
index d9d2f3d..45f9287 100644
--- a/chrome/app/google_chrome_strings_grd/IDS_VIEW_PASSWORDS.png.sha1
+++ b/chrome/app/google_chrome_strings_grd/IDS_VIEW_PASSWORDS.png.sha1
@@ -1 +1 @@
-4b968ef1738550eed74f1dee44d499af0fed7202
\ No newline at end of file
+00cbd239fc1943eff44d372bf7cce1174b2b52d5
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 9bea85b7..eaf6a7b 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -1130,6 +1130,9 @@
   <message name="IDS_SETTINGS_STICKY_KEYS_DESCRIPTION" desc="Label for checkbox which enables sticky keys, with an explanation of the term 'sticky keys'.">
     Press one key at a time for keyboard shortcuts instead of holding keys down at the same time
   </message>
+  <message name="IDS_SETTINGS_STICKY_KEYS_DISABLED_BY_CHROMEVOX_TOOLTIP" desc="Tooltip text which explains that the Sticky keys feature cannot be enabled when ChromeVox is on. Shown next to the disabled Sticky keys toggle when ChromeVox has been enabled.">
+    Sticky keys is not available when ChromeVox is on
+  </message>
   <message name="IDS_SETTINGS_CHROMEVOX_LABEL" desc="Label for checkbox which enables ChromeVox, with a description of what ChromeVox is.">
     ChromeVox
   </message>
@@ -1531,6 +1534,9 @@
   <message name="IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION_SUBTEXT" desc="In the settings tab, the subtext next to the checkbox to highlight the focused object to make it easier to see.">
     Item is highlighted when you move focus. Press tab or select an item to change focus.
   </message>
+    <message name="IDS_SETTINGS_FOCUS_HIGHLIGHT_DISABLED_BY_CHROMEVOX_TOOLTIP" desc="Tooltip text which explains that the 'Highlight the item with keyboard focus' feature cannot be enabled when ChromeVox is on. Shown next to the disabled 'Highlight the item with keyboard focus' toggle when ChromeVox has been enabled.">
+    Highlight the item with keyboard focus is not available when ChromeVox is on
+  </message>
   <message name="IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_TITLE" desc="In the settings tab, the text next to the checkbox to enable an option to hold a key and click to speak any on-screen text out loud.">
     Select-to-speak
   </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_FOCUS_HIGHLIGHT_DISABLED_BY_CHROMEVOX_TOOLTIP.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_FOCUS_HIGHLIGHT_DISABLED_BY_CHROMEVOX_TOOLTIP.png.sha1
new file mode 100644
index 0000000..40abdc2
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_FOCUS_HIGHLIGHT_DISABLED_BY_CHROMEVOX_TOOLTIP.png.sha1
@@ -0,0 +1 @@
+1c93a7f525992443cadcfc3c2a0fac934266663a
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_STICKY_KEYS_DISABLED_BY_CHROMEVOX_TOOLTIP.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_STICKY_KEYS_DISABLED_BY_CHROMEVOX_TOOLTIP.png.sha1
new file mode 100644
index 0000000..bcdaf55e
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_STICKY_KEYS_DISABLED_BY_CHROMEVOX_TOOLTIP.png.sha1
@@ -0,0 +1 @@
+edc69b67fef23b8847d2b7f58d9137cd3da98703
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 53f1571..5a69f9b 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1595,28 +1595,23 @@
 constexpr FeatureEntry::FeatureParam kOmniboxActionsInSuggestTreatment4[] = {
     {OmniboxFieldTrial::kActionsInSuggestPromoteEntitySuggestion.name, "true"},
     {OmniboxFieldTrial::kActionsInSuggestPromoteReviewsAction.name, "true"},
-    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name,
-     "without-reviews"}};
+    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name, "reviews"}};
 constexpr FeatureEntry::FeatureParam kOmniboxActionsInSuggestTreatment5[] = {
     {OmniboxFieldTrial::kActionsInSuggestPromoteEntitySuggestion.name, "true"},
     {OmniboxFieldTrial::kActionsInSuggestPromoteReviewsAction.name, "true"},
-    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name,
-     "without-calls"}};
+    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name, "call"}};
 constexpr FeatureEntry::FeatureParam kOmniboxActionsInSuggestTreatment6[] = {
     {OmniboxFieldTrial::kActionsInSuggestPromoteEntitySuggestion.name, "true"},
     {OmniboxFieldTrial::kActionsInSuggestPromoteReviewsAction.name, "true"},
-    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name,
-     "without-directions"}};
+    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name, "directions"}};
 constexpr FeatureEntry::FeatureParam kOmniboxActionsInSuggestTreatment7[] = {
     {OmniboxFieldTrial::kActionsInSuggestPromoteEntitySuggestion.name, "true"},
     {OmniboxFieldTrial::kActionsInSuggestPromoteReviewsAction.name, "false"},
-    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name,
-     "without-calls"}};
+    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name, "call"}};
 constexpr FeatureEntry::FeatureParam kOmniboxActionsInSuggestTreatment8[] = {
     {OmniboxFieldTrial::kActionsInSuggestPromoteEntitySuggestion.name, "false"},
     {OmniboxFieldTrial::kActionsInSuggestPromoteReviewsAction.name, "false"},
-    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name,
-     "without-calls"}};
+    {OmniboxFieldTrial::kActionsInSuggestRemoveActionTypes.name, "call"}};
 
 constexpr FeatureEntry::FeatureVariation kOmniboxActionsInSuggestVariants[] = {
     {"T1: Promote, Reviews, Directions, Calls",
@@ -3142,6 +3137,11 @@
 const FeatureEntry::FeatureParam kTabStripRedesignDisableNtbAnchorDetached[] = {
     {"disable_ntb_anchor", "true"},
     {"enable_detached", "true"}};
+const FeatureEntry::FeatureParam kTabStripRedesignDisableButtonStyleFolio[] = {
+    {"disable_btn_style", "true"},
+    {"enable_folio", "true"}};
+const FeatureEntry::FeatureParam kTabStripRedesignDisableButtonStyleDetached[] =
+    {{"disable_btn_style", "true"}, {"enable_detached", "true"}};
 
 const FeatureEntry::FeatureVariation kTabStripRedesignVariations[] = {
     {"Folio", kTabStripRedesignFolio, std::size(kTabStripRedesignFolio),
@@ -3151,7 +3151,12 @@
     {"Folio NTB Unanchored ", kTabStripRedesignDisableNtbAnchorFolio,
      std::size(kTabStripRedesignDisableNtbAnchorFolio), nullptr},
     {"Detached NTB Unanchored", kTabStripRedesignDisableNtbAnchorDetached,
-     std::size(kTabStripRedesignDisableNtbAnchorDetached), nullptr}};
+     std::size(kTabStripRedesignDisableNtbAnchorDetached), nullptr},
+    {"Folio Remove Button Style", kTabStripRedesignDisableButtonStyleFolio,
+     std::size(kTabStripRedesignDisableButtonStyleFolio), nullptr},
+    {"Detached Remove Button Style",
+     kTabStripRedesignDisableButtonStyleDetached,
+     std::size(kTabStripRedesignDisableButtonStyleDetached), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
 #if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
@@ -3218,34 +3223,14 @@
 };
 
 #if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
-constexpr FeatureEntry::FeatureParam kCscStagingEnvVariation[] = {
+constexpr FeatureEntry::FeatureParam kCscVariation[] = {
     {"companion-homepage-url",
      "https://lens-staging.corp.google.com/companion"},
     {"companion-image-upload-url",
      "https://lens-staging.corp.google.com/v2/upload"}};
-constexpr FeatureEntry::FeatureParam kCscClobberVariation[] = {
-    {"open-links-in-current-tab", "true"},
-};
-constexpr FeatureEntry::FeatureParam kCscNewTabVariation[] = {
-    {"open-links-in-current-tab", "false"},
-};
 
 constexpr FeatureEntry::FeatureVariation kCscVariations[] = {
-    {"with staging URL", kCscStagingEnvVariation,
-     std::size(kCscStagingEnvVariation), nullptr},
-    {"with clobber", kCscClobberVariation, std::size(kCscClobberVariation),
-     nullptr},
-    {"with new tab", kCscNewTabVariation, std::size(kCscNewTabVariation),
-     nullptr},
-};
-
-const FeatureEntry::Choice kSidePanelPinnedStateChoices[] = {
-    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
-    {"Forced Pinned", companion::switches::kForceCompanionPinnedState,
-     "pinned"},
-    {"Forced Unpinned", companion::switches::kForceCompanionPinnedState,
-     "unpinned"},
-};
+    {"with staging URL", kCscVariation, std::size(kCscVariation), nullptr}};
 #endif  // BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -4333,9 +4318,6 @@
     {"firmware-update-jelly", flag_descriptions::kFirmwareUpdateJellyName,
      flag_descriptions::kFirmwareUpdateJellyDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kFirmwareUpdateJelly)},
-    {"personalization-jelly", flag_descriptions::kPersonalizationJellyName,
-     flag_descriptions::kPersonalizationJellyDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(ash::features::kPersonalizationJelly)},
     {"screen-saver-duration", flag_descriptions::kScreenSaverDurationName,
      flag_descriptions::kScreenSaverDurationDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kScreenSaverDuration)},
@@ -7233,10 +7215,6 @@
      flag_descriptions::kArcWindowPredictorDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(full_restore::features::kArcWindowPredictor)},
 
-    {"full-restore-for-lacros", flag_descriptions::kFullRestoreForLacrosName,
-     flag_descriptions::kFullRestoreForLacrosDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(full_restore::features::kFullRestoreForLacros)},
-
     {"use-fake-device-for-media-stream",
      flag_descriptions::kUseFakeDeviceForMediaStreamName,
      flag_descriptions::kUseFakeDeviceForMediaStreamDescription, kOsCrOS,
@@ -8530,11 +8508,6 @@
     {"raw-audio-capture", flag_descriptions::kRawAudioCaptureName,
      flag_descriptions::kRawAudioCaptureDescription, kOsWin,
      FEATURE_VALUE_TYPE(media::kWasapiRawAudioCapture)},
-
-    {"fake-audio-capture-timestamps",
-     flag_descriptions::kFakeAudioCaptureTimestamps,
-     flag_descriptions::kFakeAudioCaptureTimestampsDescription, kOsWin,
-     FEATURE_VALUE_TYPE(media::kUseFakeAudioCaptureTimestamps)},
 #endif  // BUILDFLAG(IS_WIN)
 
     {"enable-managed-configuration-web-api",
@@ -8848,10 +8821,6 @@
                                     kCscVariations,
                                     "CSC")},
 
-    {"csc-pinned-state", flag_descriptions::kCscPinnedName,
-     flag_descriptions::kCscPinnedDescription, kOsDesktop,
-     MULTI_VALUE_TYPE(kSidePanelPinnedStateChoices)},
-
     {"enable-lens-region-search-static-page",
      flag_descriptions::kLensRegionSearchStaticPageName,
      flag_descriptions::kLensRegionSearchStaticPageDescription, kOsDesktop,
@@ -8876,14 +8845,6 @@
                                     kLensPingVariations,
                                     "EnableLensPing")},
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-    {"enable-log-controller-for-diagnostics-app",
-     flag_descriptions::kEnableLogControllerForDiagnosticsAppName,
-     flag_descriptions::kEnableLogControllerForDiagnosticsAppDescription,
-     kOsCrOS,
-     FEATURE_VALUE_TYPE(ash::features::kEnableLogControllerForDiagnosticsApp)},
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 #if BUILDFLAG(IS_ANDROID)
     {"biometric-reauth-password-filling",
      flag_descriptions::kBiometricReauthForPasswordFillingName,
@@ -10012,12 +9973,6 @@
          policy::features::kSafeSitesFilterBehaviorPolicyAndroid)},
 #endif
 
-    {"cmd-decoder-always-get-size-from-source-texture",
-     flag_descriptions::kCmdDecoderAlwaysGetSizeFromSourceTextureName,
-     flag_descriptions::kCmdDecoderAlwaysGetSizeFromSourceTextureDescription,
-     kOsAll,
-     FEATURE_VALUE_TYPE(features::kCmdDecoderAlwaysGetSizeFromSourceTexture)},
-
 #if BUILDFLAG(IS_WIN)
     {"cloud-ap-auth", flag_descriptions::kCloudApAuthName,
      flag_descriptions::kCloudApAuthDescription, kOsWin,
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
index 6156673..d075161 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
@@ -25,7 +25,8 @@
 
 TabStripSceneLayer::TabStripSceneLayer(JNIEnv* env,
                                        const JavaRef<jobject>& jobj,
-                                       jboolean is_tab_strip_redesign_enabled)
+                                       jboolean is_tab_strip_redesign_enabled,
+                                       jboolean is_tsr_btn_style_disabled)
     : SceneLayer(env, jobj),
       tab_strip_layer_(cc::slim::SolidColorLayer::Create()),
       scrollable_strip_layer_(cc::slim::Layer::Create()),
@@ -36,6 +37,7 @@
       model_selector_button_(cc::slim::UIResourceLayer::Create()),
       model_selector_button_background_(cc::slim::UIResourceLayer::Create()),
       is_tab_strip_redesign_enabled_(is_tab_strip_redesign_enabled),
+      is_tsr_btn_style_disabled_(is_tsr_btn_style_disabled),
       write_index_(0),
       content_tree_(nullptr) {
   new_tab_button_->SetIsDrawable(true);
@@ -160,16 +162,23 @@
     float background_top_offset = (button_background_resource->size().height() -
                                    button_resource->size().height()) /
                                   2;
-    new_tab_button_background_->SetUIResourceId(
-        button_background_resource->ui_resource()->id());
-    new_tab_button_background_->SetPosition(gfx::PointF(x, y));
 
-    new_tab_button_background_->SetBounds(button_background_resource->size());
-    new_tab_button_background_->SetHideLayerAndSubtree(!visible);
-    new_tab_button_background_->SetOpacity(button_alpha);
-    new_tab_button_->SetPosition(
-        gfx::PointF(background_left_offset, background_top_offset));
-    new_tab_button_background_->AddChild(new_tab_button_);
+    // Do not show button bg if btn style disabled.
+    if (is_tsr_btn_style_disabled_) {
+      new_tab_button_->SetPosition(
+          gfx::PointF(x + background_left_offset, y + background_top_offset));
+    } else {
+      new_tab_button_background_->SetUIResourceId(
+          button_background_resource->ui_resource()->id());
+      new_tab_button_background_->SetPosition(gfx::PointF(x, y));
+
+      new_tab_button_background_->SetBounds(button_background_resource->size());
+      new_tab_button_background_->SetHideLayerAndSubtree(!visible);
+      new_tab_button_background_->SetOpacity(button_alpha);
+      new_tab_button_->SetPosition(
+          gfx::PointF(background_left_offset, background_top_offset));
+      new_tab_button_background_->AddChild(new_tab_button_);
+    }
   } else {
     // The touch target for the new tab button is skewed towards the end of the
     // strip. This ensures that the view itself is correctly aligned without
@@ -246,14 +255,20 @@
                                  button_resource->size().height()) /
                                 2;
 
-  model_selector_button_background_->SetPosition(gfx::PointF(x, y));
+  // Do not show button bg if btn style disabled.
+  if (is_tsr_btn_style_disabled_) {
+    model_selector_button_->SetPosition(
+        gfx::PointF(x + background_left_offset, y + background_top_offset));
+  } else {
+    model_selector_button_background_->SetPosition(gfx::PointF(x, y));
 
-  model_selector_button_background_->SetBounds(
-      button_background_resource->size());
-  model_selector_button_background_->SetHideLayerAndSubtree(!visible);
-  model_selector_button_background_->SetOpacity(button_alpha);
-  model_selector_button_->SetPosition(
-      gfx::PointF(background_left_offset, background_top_offset));
+    model_selector_button_background_->SetBounds(
+        button_background_resource->size());
+    model_selector_button_background_->SetHideLayerAndSubtree(!visible);
+    model_selector_button_background_->SetOpacity(button_alpha);
+    model_selector_button_->SetPosition(
+        gfx::PointF(background_left_offset, background_top_offset));
+  }
   model_selector_button_->SetBounds(button_resource->size());
   model_selector_button_->SetHideLayerAndSubtree(!visible);
   model_selector_button_->SetOpacity(button_alpha);
@@ -422,13 +437,13 @@
   return SceneLayer::GetBackgroundColor();
 }
 
-static jlong JNI_TabStripSceneLayer_Init(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& jobj,
-    jboolean is_tab_strip_redesign_enabled) {
+static jlong JNI_TabStripSceneLayer_Init(JNIEnv* env,
+                                         const JavaParamRef<jobject>& jobj,
+                                         jboolean is_tab_strip_redesign_enabled,
+                                         jboolean is_tsr_btn_style_disabled) {
   // This will automatically bind to the Java object and pass ownership there.
-  TabStripSceneLayer* scene_layer =
-      new TabStripSceneLayer(env, jobj, is_tab_strip_redesign_enabled);
+  TabStripSceneLayer* scene_layer = new TabStripSceneLayer(
+      env, jobj, is_tab_strip_redesign_enabled, is_tsr_btn_style_disabled);
   return reinterpret_cast<intptr_t>(scene_layer);
 }
 
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
index 5157225f..c83bafe 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
@@ -31,7 +31,8 @@
  public:
   TabStripSceneLayer(JNIEnv* env,
                      const base::android::JavaRef<jobject>& jobj,
-                     jboolean is_tab_strip_redesign_enabled);
+                     jboolean is_tab_strip_redesign_enabled,
+                     jboolean is_tsr_btn_style_disabled);
 
   TabStripSceneLayer(const TabStripSceneLayer&) = delete;
   TabStripSceneLayer& operator=(const TabStripSceneLayer&) = delete;
@@ -169,6 +170,7 @@
   scoped_refptr<cc::slim::UIResourceLayer> model_selector_button_background_;
 
   const bool is_tab_strip_redesign_enabled_ = false;
+  const bool is_tsr_btn_style_disabled_ = false;
 
   unsigned write_index_;
   TabHandleLayerList tab_handle_layers_;
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
index 3e450dc..797282e5 100644
--- a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
+++ b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
@@ -78,7 +78,6 @@
     private static final String SHARED_PREF_CLOSE_ICON = "CloseIcon";
     private static final String SHARED_PREF_CLOSE_POSITION = "ClosePosition";
     private static final String SHARED_PREF_SIDE_SHEET_POSITION = "SideSheetPosition";
-    private static final String SHARED_PREF_SIDE_SHEET_ANIMATION = "SideSheetAnimation";
     private static final String SHARED_PREF_COLOR = "Color";
     private static final String SHARED_PREF_DECORATION = "Decoration";
     private static final String SHARED_PREF_HEIGHT = "Height";
@@ -134,7 +133,6 @@
     private MaterialButtonToggleGroup mDecorationType;
     private MaterialButtonToggleGroup mThemeButton;
     private MaterialButtonToggleGroup mSideSheetPositionToggle;
-    private MaterialButtonToggleGroup mSideSheetAnimationToggle;
     private TextView mToolbarCornerRadiusLabel;
     private SeekBar mToolbarCornerRadiusSlider;
     private CheckBox mBottomToolbarCheckbox;
@@ -173,13 +171,6 @@
     public static final String EXTRA_ACTIVITY_SIDE_SHEEET_DECORATION_TYPE =
             "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_DECORATION_TYPE";
 
-    public static final int ACTIVITY_SIDE_SHEET_SLIDE_IN_DEFAULT = 0;
-    public static final int ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_BOTTOM = 1;
-    public static final int ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE = 2;
-
-    public static final String EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR =
-            "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR";
-
     public static final int ACTIVITY_SIDE_SHEET_ROUNDED_CORNERS_DEFAULT = 0;
     public static final int ACTIVITY_SIDE_SHEET_ROUNDED_CORNERS_NONE = 1;
     public static final int ACTIVITY_SIDE_SHEET_ROUNDED_CORNERS_TOP = 2;
@@ -471,13 +462,6 @@
                 ? R.id.side_sheet_start_button
                 : R.id.side_sheet_end_button;
         mSideSheetPositionToggle.check(sideSheetPositionType);
-        mSideSheetAnimationToggle = findViewById(R.id.side_sheet_animation_toggle);
-        int sideSheetAnimationType = mSharedPref.getInt(SHARED_PREF_SIDE_SHEET_ANIMATION,
-                                             ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE)
-                        == ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE
-                ? R.id.side_sheet_side_button
-                : R.id.side_sheet_bottom_button;
-        mSideSheetAnimationToggle.check(sideSheetAnimationType);
 
         mDecorationType = findViewById(R.id.decoration_type_toggle);
         if (mSharedPref.getInt(SHARED_PREF_DECORATION, ACTIVITY_SIDE_SHEET_DECORATION_TYPE_SHADOW)
@@ -816,10 +800,6 @@
                 mSideSheetPositionToggle.getCheckedButtonId() == R.id.side_sheet_end_button
                 ? ACTIVITY_SIDE_SHEET_POSITION_END
                 : ACTIVITY_SIDE_SHEET_POSITION_START;
-        int sideSheetAnimation =
-                mSideSheetAnimationToggle.getCheckedButtonId() == R.id.side_sheet_side_button
-                ? ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE
-                : ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_BOTTOM;
         int decorationType = ACTIVITY_SIDE_SHEET_DECORATION_TYPE_SHADOW;
         if (mDecorationType.getCheckedButtonId() == R.id.decoration_type_divider_button) {
             decorationType = ACTIVITY_SIDE_SHEET_DECORATION_TYPE_DIVIDER;
@@ -873,8 +853,6 @@
             }
             customTabsIntent.intent.putExtra(EXTRA_ACTIVITY_SIDE_SHEET_POSITION, sideSheetPosition);
             customTabsIntent.intent.putExtra(
-                    EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR, sideSheetAnimation);
-            customTabsIntent.intent.putExtra(
                     EXTRA_ACTIVITY_SIDE_SHEEET_DECORATION_TYPE, decorationType);
         } else {
             editor.putString(
@@ -915,7 +893,6 @@
         editor.putInt(SHARED_PREF_BOTTOM_TOOLBAR, toolbarCheck);
         editor.putInt(SHARED_PREF_CLOSE_POSITION, closeButtonPosition);
         editor.putInt(SHARED_PREF_SIDE_SHEET_POSITION, sideSheetPosition);
-        editor.putInt(SHARED_PREF_SIDE_SHEET_ANIMATION, sideSheetAnimation);
         editor.putInt(SHARED_PREF_HEIGHT_RESIZABLE,
                 mPcctHeightResizableCheckbox.isChecked() ? CHECKED : UNCHECKED);
         editor.putInt(SHARED_PREF_SIDE_SHEET_MAX_BUTTON,
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml b/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml
index 534f102..a5645e4 100644
--- a/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml
+++ b/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml
@@ -348,44 +348,6 @@
             </com.google.android.material.button.MaterialButtonToggleGroup>
         </LinearLayout>
 
-        <!-- Side sheet animation -->
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_marginStart="3dp"
-            android:layout_marginBottom="16dp">
-            <TextView
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical|start"
-                android:text="@string/side_sheet_animation_text"
-                android:layout_marginEnd="16dp"
-                style="?attr/textAppearanceLabelLarge" />
-            <com.google.android.material.button.MaterialButtonToggleGroup
-                android:id="@+id/side_sheet_animation_toggle"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:layout_weight="1"
-                android:gravity="center_horizontal"
-                app:singleSelection="true"
-                app:selectionRequired="true">
-                <Button
-                    android:id="@+id/side_sheet_side_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="@string/side_sheet_animation_side_text"
-                    style="?attr/materialButtonOutlinedStyle" />
-                <Button
-                    android:id="@+id/side_sheet_bottom_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="@string/side_sheet_animation_bottom_text"
-                    style="?attr/materialButtonOutlinedStyle" />
-            </com.google.android.material.button.MaterialButtonToggleGroup>
-        </LinearLayout>
-
         <!-- Decoration type -->
         <LinearLayout
             android:layout_width="match_parent"
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml b/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml
index ca17a71..66061bd 100644
--- a/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml
+++ b/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml
@@ -28,9 +28,6 @@
     <string name="side_sheet_position_text">Side Sheet Position</string>
     <string name="side_sheet_start_text">Start</string>
     <string name="side_sheet_end_text">Default/End</string>
-    <string name="side_sheet_animation_text">Side Sheet Animation</string>
-    <string name="side_sheet_animation_side_text">Default/Side</string>
-    <string name="side_sheet_animation_bottom_text">Bottom</string>
     <string name="show_title_text">Show Title</string>
     <string name="toolbar_corner_radius_text">PCCT corner radius</string>
     <string name="toolbar_corner_radius_slider_label_desc">Toolbar corner radius</string>
diff --git a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc
index 53e9a0e..3510e2c7 100644
--- a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc
+++ b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc
@@ -30,11 +30,11 @@
 constexpr char kAppDeduplicationFolderPath[] =
     "app_deduplication_service/deduplication_data/";
 
-// Converts PackageId strings to EntryIds when the source is Website.
-absl::optional<apps::deduplication::EntryId> GetEntryIdForWebsite(
+// Converts PackageId strings to Entrys when the source is Website.
+absl::optional<apps::deduplication::Entry> GetEntryForWebsite(
     const std::string& id) {
   size_t separator = id.find_first_of(':');
-  apps::deduplication::EntryId entry_id;
+  apps::deduplication::Entry entry;
 
   if (separator == std::string::npos || separator == id.size() - 1) {
     LOG(ERROR) << "Source is an unsupported type.";
@@ -46,12 +46,12 @@
   GURL entry_url = GURL(app_id);
 
   if (entry_url.is_valid() && app_type == "website") {
-    entry_id = apps::deduplication::EntryId(entry_url);
+    entry = apps::deduplication::Entry(entry_url);
   } else {
     LOG(ERROR) << "Source is an unsupported type.";
     return absl::nullopt;
   }
-  return entry_id;
+  return entry;
 }
 }  // namespace
 
@@ -109,10 +109,11 @@
 }
 
 std::vector<Entry> AppDeduplicationService::GetDuplicates(
-    const EntryId& entry_id) {
+    const Entry& entry_query) {
   std::vector<Entry> entries;
 
-  absl::optional<uint32_t> duplication_index = FindDuplicationIndex(entry_id);
+  absl::optional<uint32_t> duplication_index =
+      FindDuplicationIndex(entry_query);
   if (!duplication_index.has_value()) {
     return entries;
   }
@@ -122,7 +123,7 @@
   }
 
   for (const auto& entry : group->second.entries) {
-    auto status_it = entry_status_.find(entry.entry_id);
+    auto status_it = entry_status_.find(entry);
     if (status_it == entry_status_.end()) {
       continue;
     }
@@ -134,17 +135,15 @@
   return entries;
 }
 
-bool AppDeduplicationService::AreDuplicates(const EntryId& entry_id_1,
-                                            const EntryId& entry_id_2) {
+bool AppDeduplicationService::AreDuplicates(const Entry& entry_1,
+                                            const Entry& entry_2) {
   // TODO(b/238394602): Add interface with more than 2 entry ids.
-  absl::optional<uint32_t> duplication_index_1 =
-      FindDuplicationIndex(entry_id_1);
+  absl::optional<uint32_t> duplication_index_1 = FindDuplicationIndex(entry_1);
   if (!duplication_index_1.has_value()) {
     return false;
   }
 
-  absl::optional<uint32_t> duplication_index_2 =
-      FindDuplicationIndex(entry_id_2);
+  absl::optional<uint32_t> duplication_index_2 = FindDuplicationIndex(entry_2);
   if (!duplication_index_2.has_value()) {
     return false;
   }
@@ -165,17 +164,17 @@
     for (auto const& app : group.app()) {
       const std::string& app_id = app.app_id_for_platform();
       const std::string& source = app.source_name();
-      EntryId entry_id;
+      Entry entry;
       // TODO(b/238394602): Add more data type when real data is ready.
       // TODO(b/238394602): Add server data verification.
       if (source == "arc") {
-        entry_id = EntryId(app_id, AppType::kArc);
+        entry = Entry(app_id, AppType::kArc);
       } else if (source == "web") {
-        entry_id = EntryId(app_id, AppType::kWeb);
+        entry = Entry(app_id, AppType::kWeb);
       } else if (source == "website") {
         GURL entry_url = GURL(app_id);
         if (entry_url.is_valid()) {
-          entry_id = EntryId(GURL(app_id));
+          entry = Entry(GURL(app_id));
         } else {
           continue;
         }
@@ -183,12 +182,11 @@
         continue;
       }
 
-      entry_to_group_map_[entry_id] = index;
+      entry_to_group_map_[entry] = index;
       // Initialize entry status.
-      entry_status_[entry_id] = entry_id.entry_type == EntryType::kApp
-                                    ? EntryStatus::kNotInstalledApp
-                                    : EntryStatus::kNonApp;
-      Entry entry(std::move(entry_id));
+      entry_status_[entry] = entry.entry_type == EntryType::kApp
+                                 ? EntryStatus::kNotInstalledApp
+                                 : EntryStatus::kNonApp;
       duplicate_group.entries.push_back(std::move(entry));
     }
     duplication_map_[index] = std::move(duplicate_group);
@@ -213,8 +211,8 @@
 
 void AppDeduplicationService::UpdateInstallationStatus(
     const apps::AppUpdate& update) {
-  EntryId entry_id(update.PublisherId(), update.AppType());
-  auto it = entry_status_.find(entry_id);
+  Entry entry(update.PublisherId(), update.AppType());
+  auto it = entry_status_.find(entry);
 
   if (it == entry_status_.end()) {
     return;
@@ -226,10 +224,10 @@
 }
 
 absl::optional<uint32_t> AppDeduplicationService::FindDuplicationIndex(
-    const EntryId& entry_id) {
+    const Entry& entry) {
   // TODO(b/238394602): Add logic to handle url entry id and web apps.
   // Check if there is an exact match of the entry id.
-  auto it = entry_to_group_map_.find(entry_id);
+  auto it = entry_to_group_map_.find(entry);
 
   if (it != entry_to_group_map_.end()) {
     return it->second;
@@ -237,13 +235,13 @@
 
   // For website, check if the url is in the scope of the recorded url in the
   // deduplication database. Here we assume all the websites has it's own entry.
-  GURL entry_url = GURL(entry_id.id);
-  if (entry_id.entry_type == EntryType::kWebPage && entry_url.is_valid()) {
-    for (const auto& [recorded_entry_id, group_id] : entry_to_group_map_) {
-      if (recorded_entry_id.entry_type != EntryType::kWebPage) {
+  GURL entry_url = GURL(entry.id);
+  if (entry.entry_type == EntryType::kWebPage && entry_url.is_valid()) {
+    for (const auto& [recorded_entry, group_id] : entry_to_group_map_) {
+      if (recorded_entry.entry_type != EntryType::kWebPage) {
         continue;
       }
-      GURL recorded_entry_url = GURL(recorded_entry_id.id);
+      GURL recorded_entry_url = GURL(recorded_entry.id);
       if (!recorded_entry_url.is_valid()) {
         continue;
       }
@@ -346,13 +344,13 @@
     for (auto const& id : group.package_id()) {
       absl::optional<PackageId> package_id = PackageId::FromString(id);
       std::string app_id;
-      EntryId entry_id;
+      Entry entry;
       if (!package_id.has_value()) {
-        absl::optional<EntryId> web_id = GetEntryIdForWebsite(id);
+        absl::optional<Entry> web_id = GetEntryForWebsite(id);
         if (!web_id.has_value()) {
           continue;
         }
-        entry_id = web_id.value();
+        entry = web_id.value();
       } else {
         AppType source = package_id.value().app_type();
         app_id = package_id.value().identifier();
@@ -360,15 +358,14 @@
           LOG(ERROR) << "Source is an unsupported type.";
           NOTREACHED();
         }
-        entry_id = EntryId(app_id, source);
+        entry = Entry(app_id, source);
       }
 
-      entry_to_group_map_[entry_id] = index;
+      entry_to_group_map_[entry] = index;
       // Initialize entry status.
-      entry_status_[entry_id] = entry_id.entry_type == EntryType::kApp
-                                    ? EntryStatus::kNotInstalledApp
-                                    : EntryStatus::kNonApp;
-      Entry entry(std::move(entry_id));
+      entry_status_[entry] = entry.entry_type == EntryType::kApp
+                                 ? EntryStatus::kNotInstalledApp
+                                 : EntryStatus::kNonApp;
       duplicate_group.entries.push_back(std::move(entry));
     }
     if (!duplicate_group.entries.empty()) {
diff --git a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.h b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.h
index cb68fe2..b3131c3 100644
--- a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.h
+++ b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.h
@@ -44,8 +44,8 @@
   // This function returns true if the Deduplication Service has been
   // properly initialised, ensuring the correctness of method responses.
   bool IsServiceOn();
-  std::vector<Entry> GetDuplicates(const EntryId& entry_id);
-  bool AreDuplicates(const EntryId& entry_id_1, const EntryId& entry_id_2);
+  std::vector<Entry> GetDuplicates(const Entry& entry);
+  bool AreDuplicates(const Entry& entry_1, const Entry& entry_2);
 
   // Registers prefs used for the App Deduplication Service.
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
@@ -102,7 +102,7 @@
   // Returns the map key of the duplicate group in the duplication map if a
   // group is found, and return nullptr if the entry id doesn't belong to
   // and duplicate group.
-  absl::optional<uint32_t> FindDuplicationIndex(const EntryId& entry_id);
+  absl::optional<uint32_t> FindDuplicationIndex(const Entry& entry);
 
   // Calls server connector to make a request to the Fondue server to retrieve
   // duplicate app group data.
@@ -134,8 +134,8 @@
   }
 
   std::map<uint32_t, DuplicateGroup> duplication_map_;
-  std::map<EntryId, uint32_t> entry_to_group_map_;
-  std::map<EntryId, EntryStatus> entry_status_;
+  std::map<Entry, uint32_t> entry_to_group_map_;
+  std::map<Entry, EntryStatus> entry_status_;
   raw_ptr<Profile, ExperimentalAsh> profile_;
 
   base::ScopedObservation<AppProvisioningDataManager,
diff --git a/chrome/browser/apps/app_deduplication_service/app_deduplication_service_unittest.cc b/chrome/browser/apps/app_deduplication_service/app_deduplication_service_unittest.cc
index 25ab08e8..22eb09b 100644
--- a/chrome/browser/apps/app_deduplication_service/app_deduplication_service_unittest.cc
+++ b/chrome/browser/apps/app_deduplication_service/app_deduplication_service_unittest.cc
@@ -137,41 +137,41 @@
 
   uint32_t skype_test_index = 1;
   std::string skype_arc_app_id = "com.skype.raider";
-  auto it = service->entry_to_group_map_.find(
-      EntryId(skype_arc_app_id, AppType::kArc));
+  auto it =
+      service->entry_to_group_map_.find(Entry(skype_arc_app_id, AppType::kArc));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(skype_test_index, it->second);
 
   std::string skype_web_app_id = "https://web.skype.com/";
-  it = service->entry_to_group_map_.find(
-      EntryId(skype_web_app_id, AppType::kWeb));
+  it =
+      service->entry_to_group_map_.find(Entry(skype_web_app_id, AppType::kWeb));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(skype_test_index, it->second);
 
   auto map_it = service->duplication_map_.find(skype_test_index);
   ASSERT_FALSE(map_it == service->duplication_map_.end());
   EXPECT_THAT(map_it->second.entries,
-              ElementsAre(Entry(EntryId(skype_arc_app_id, AppType::kArc)),
-                          Entry(EntryId(skype_web_app_id, AppType::kWeb))));
+              ElementsAre(Entry(skype_arc_app_id, AppType::kArc),
+                          Entry(skype_web_app_id, AppType::kWeb)));
 
   uint32_t whatsapp_test_index = 2;
   std::string whatsapp_arc_app_id = "com.whatsapp";
   it = service->entry_to_group_map_.find(
-      EntryId(whatsapp_arc_app_id, AppType::kArc));
+      Entry(whatsapp_arc_app_id, AppType::kArc));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(whatsapp_test_index, it->second);
 
   std::string whatsapp_web_app_id = "https://web.whatsapp.com/";
   it = service->entry_to_group_map_.find(
-      EntryId(whatsapp_web_app_id, AppType::kWeb));
+      Entry(whatsapp_web_app_id, AppType::kWeb));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(whatsapp_test_index, it->second);
 
   map_it = service->duplication_map_.find(whatsapp_test_index);
   ASSERT_FALSE(map_it == service->duplication_map_.end());
   EXPECT_THAT(map_it->second.entries,
-              ElementsAre(Entry(EntryId(whatsapp_arc_app_id, AppType::kArc)),
-                          Entry(EntryId(whatsapp_web_app_id, AppType::kWeb))));
+              ElementsAre(Entry(whatsapp_arc_app_id, AppType::kArc),
+                          Entry(whatsapp_web_app_id, AppType::kWeb)));
 }
 
 // Test that if all apps in the duplicated group are installed, the full list
@@ -206,47 +206,36 @@
 
   service->OnDuplicatedGroupListUpdated(duplicated_group_list.value());
 
-  EntryId skype_arc_entry_id(skype_arc_app_id, apps::AppType::kArc);
-  EntryId skype_web_entry_id(skype_web_app_id, apps::AppType::kWeb);
-  EntryId whatsapp_arc_entry_id(whatsapp_arc_app_id, apps::AppType::kArc);
-  EntryId whatsapp_web_entry_id(whatsapp_web_app_id, apps::AppType::kWeb);
+  Entry skype_arc_entry(skype_arc_app_id, apps::AppType::kArc);
+  Entry skype_web_entry(skype_web_app_id, apps::AppType::kWeb);
+  Entry whatsapp_arc_entry(whatsapp_arc_app_id, apps::AppType::kArc);
+  Entry whatsapp_web_entry(whatsapp_web_app_id, apps::AppType::kWeb);
 
+  EXPECT_THAT(service->GetDuplicates(skype_arc_entry),
+              ElementsAre(Entry(skype_arc_entry), Entry(skype_web_entry)));
+  EXPECT_THAT(service->GetDuplicates(skype_web_entry),
+              ElementsAre(Entry(skype_arc_entry), Entry(skype_web_entry)));
   EXPECT_THAT(
-      service->GetDuplicates(skype_arc_entry_id),
-      ElementsAre(Entry(skype_arc_entry_id), Entry(skype_web_entry_id)));
+      service->GetDuplicates(whatsapp_web_entry),
+      ElementsAre(Entry(whatsapp_arc_entry), Entry(whatsapp_web_entry)));
   EXPECT_THAT(
-      service->GetDuplicates(skype_web_entry_id),
-      ElementsAre(Entry(skype_arc_entry_id), Entry(skype_web_entry_id)));
-  EXPECT_THAT(
-      service->GetDuplicates(whatsapp_web_entry_id),
-      ElementsAre(Entry(whatsapp_arc_entry_id), Entry(whatsapp_web_entry_id)));
-  EXPECT_THAT(
-      service->GetDuplicates(whatsapp_arc_entry_id),
-      ElementsAre(Entry(whatsapp_arc_entry_id), Entry(whatsapp_web_entry_id)));
+      service->GetDuplicates(whatsapp_arc_entry),
+      ElementsAre(Entry(whatsapp_arc_entry), Entry(whatsapp_web_entry)));
 
-  EXPECT_TRUE(service->AreDuplicates(skype_arc_entry_id, skype_web_entry_id));
-  EXPECT_TRUE(
-      service->AreDuplicates(whatsapp_arc_entry_id, whatsapp_web_entry_id));
+  EXPECT_TRUE(service->AreDuplicates(skype_arc_entry, skype_web_entry));
+  EXPECT_TRUE(service->AreDuplicates(whatsapp_arc_entry, whatsapp_web_entry));
 
-  EXPECT_FALSE(
-      service->AreDuplicates(skype_arc_entry_id, whatsapp_arc_entry_id));
-  EXPECT_FALSE(
-      service->AreDuplicates(skype_arc_entry_id, whatsapp_web_entry_id));
-  EXPECT_FALSE(
-      service->AreDuplicates(skype_web_entry_id, whatsapp_arc_entry_id));
-  EXPECT_FALSE(
-      service->AreDuplicates(skype_web_entry_id, whatsapp_web_entry_id));
+  EXPECT_FALSE(service->AreDuplicates(skype_arc_entry, whatsapp_arc_entry));
+  EXPECT_FALSE(service->AreDuplicates(skype_arc_entry, whatsapp_web_entry));
+  EXPECT_FALSE(service->AreDuplicates(skype_web_entry, whatsapp_arc_entry));
+  EXPECT_FALSE(service->AreDuplicates(skype_web_entry, whatsapp_web_entry));
 
-  EntryId not_duplicate_app_id("not_duplicate_app_id", apps::AppType::kWeb);
-  EXPECT_TRUE(service->GetDuplicates(not_duplicate_app_id).empty());
-  EXPECT_FALSE(
-      service->AreDuplicates(not_duplicate_app_id, skype_arc_entry_id));
-  EXPECT_FALSE(
-      service->AreDuplicates(not_duplicate_app_id, skype_web_entry_id));
-  EXPECT_FALSE(
-      service->AreDuplicates(not_duplicate_app_id, whatsapp_arc_entry_id));
-  EXPECT_FALSE(
-      service->AreDuplicates(not_duplicate_app_id, whatsapp_web_entry_id));
+  Entry not_duplicate_app("not_duplicate_app_id", apps::AppType::kWeb);
+  EXPECT_TRUE(service->GetDuplicates(not_duplicate_app).empty());
+  EXPECT_FALSE(service->AreDuplicates(not_duplicate_app, skype_arc_entry));
+  EXPECT_FALSE(service->AreDuplicates(not_duplicate_app, skype_web_entry));
+  EXPECT_FALSE(service->AreDuplicates(not_duplicate_app, whatsapp_arc_entry));
+  EXPECT_FALSE(service->AreDuplicates(not_duplicate_app, whatsapp_web_entry));
 }
 
 TEST_F(AppDeduplicationServiceTest, Installation) {
@@ -270,29 +259,29 @@
   std::string whatsapp_arc_app_id = "com.whatsapp";
   std::string whatsapp_web_app_id = "https://web.whatsapp.com/";
 
-  EntryId skype_arc_entry_id(skype_arc_app_id, apps::AppType::kArc);
-  EntryId skype_web_entry_id(skype_web_app_id, apps::AppType::kWeb);
-  EntryId whatsapp_arc_entry_id(whatsapp_arc_app_id, apps::AppType::kArc);
-  EntryId whatsapp_web_entry_id(whatsapp_web_app_id, apps::AppType::kWeb);
+  Entry skype_arc_entry(skype_arc_app_id, apps::AppType::kArc);
+  Entry skype_web_entry(skype_web_app_id, apps::AppType::kWeb);
+  Entry whatsapp_arc_entry(whatsapp_arc_app_id, apps::AppType::kArc);
+  Entry whatsapp_web_entry(whatsapp_web_app_id, apps::AppType::kWeb);
 
   // If nothing is installed, should only return phonehub app.
-  EXPECT_THAT(service->GetDuplicates(skype_arc_entry_id), ElementsAre());
-  EXPECT_THAT(service->GetDuplicates(whatsapp_web_entry_id), ElementsAre());
+  EXPECT_THAT(service->GetDuplicates(skype_arc_entry), ElementsAre());
+  EXPECT_THAT(service->GetDuplicates(whatsapp_web_entry), ElementsAre());
 
   UpdateAppReadiness(proxy, "app1", skype_arc_app_id, apps::AppType::kArc,
                      Readiness::kReady);
-  EXPECT_THAT(service->GetDuplicates(skype_web_entry_id),
-              ElementsAre(Entry(skype_arc_entry_id)));
+  EXPECT_THAT(service->GetDuplicates(skype_web_entry),
+              ElementsAre(Entry(skype_arc_entry)));
 
   UpdateAppReadiness(proxy, "app2", whatsapp_web_app_id, apps::AppType::kWeb,
                      Readiness::kReady);
-  EXPECT_THAT(service->GetDuplicates(whatsapp_arc_entry_id),
-              ElementsAre(Entry(whatsapp_web_entry_id)));
+  EXPECT_THAT(service->GetDuplicates(whatsapp_arc_entry),
+              ElementsAre(Entry(whatsapp_web_entry)));
 
   // Uninstall the app removes it from duplicates.
   UpdateAppReadiness(proxy, "app1", skype_arc_app_id, apps::AppType::kArc,
                      Readiness::kUninstalledByUser);
-  EXPECT_THAT(service->GetDuplicates(skype_arc_entry_id), ElementsAre());
+  EXPECT_THAT(service->GetDuplicates(skype_arc_entry), ElementsAre());
 }
 
 TEST_F(AppDeduplicationServiceTest, Websites) {
@@ -318,35 +307,34 @@
   std::string keep_web_app_id = "https://keep.google.com/?usp=installed_webapp";
   GURL wrong_scheme_website = GURL("http://www.google.com/");
 
-  EntryId keep_website_entry_id(keep_website);
-  EntryId keep_website_with_path_entry_id(keep_website_with_path);
-  EntryId keep_arc_entry_id(keep_arc_app_id, apps::AppType::kArc);
-  EntryId keep_web_entry_id(keep_web_app_id, apps::AppType::kWeb);
-  EntryId not_keep_website_entry_id(not_keep_website);
-  EntryId wrong_scheme_website_entry_id(wrong_scheme_website);
+  Entry keep_website_entry(keep_website);
+  Entry keep_website_with_path_entry(keep_website_with_path);
+  Entry keep_arc_entry(keep_arc_app_id, apps::AppType::kArc);
+  Entry keep_web_entry(keep_web_app_id, apps::AppType::kWeb);
+  Entry not_keep_website_entry(not_keep_website);
+  Entry wrong_scheme_website_entry(wrong_scheme_website);
 
   UpdateAppReadiness(proxy, "app1", keep_arc_app_id, apps::AppType::kArc,
                      Readiness::kReady);
   UpdateAppReadiness(proxy, "app2", keep_web_app_id, apps::AppType::kWeb,
                      Readiness::kReady);
 
-  EXPECT_THAT(service->GetDuplicates(keep_website_entry_id),
-              ElementsAre(Entry(keep_arc_entry_id), Entry(keep_web_entry_id),
-                          Entry(keep_website_entry_id)));
-  EXPECT_THAT(service->GetDuplicates(keep_website_with_path_entry_id),
-              ElementsAre(Entry(keep_arc_entry_id), Entry(keep_web_entry_id),
-                          Entry(keep_website_entry_id)));
-  EXPECT_THAT(service->GetDuplicates(not_keep_website_entry_id),
+  EXPECT_THAT(service->GetDuplicates(keep_website_entry),
+              ElementsAre(Entry(keep_arc_entry), Entry(keep_web_entry),
+                          Entry(keep_website_entry)));
+  EXPECT_THAT(service->GetDuplicates(keep_website_with_path_entry),
+              ElementsAre(Entry(keep_arc_entry), Entry(keep_web_entry),
+                          Entry(keep_website_entry)));
+  EXPECT_THAT(service->GetDuplicates(not_keep_website_entry),
               testing::IsEmpty());
-  EXPECT_THAT(service->GetDuplicates(wrong_scheme_website_entry_id),
+  EXPECT_THAT(service->GetDuplicates(wrong_scheme_website_entry),
               testing::IsEmpty());
 
-  EXPECT_TRUE(service->AreDuplicates(keep_website_with_path_entry_id,
-                                     keep_arc_entry_id));
+  EXPECT_TRUE(
+      service->AreDuplicates(keep_website_with_path_entry, keep_arc_entry));
+  EXPECT_FALSE(service->AreDuplicates(not_keep_website_entry, keep_web_entry));
   EXPECT_FALSE(
-      service->AreDuplicates(not_keep_website_entry_id, keep_web_entry_id));
-  EXPECT_FALSE(
-      service->AreDuplicates(wrong_scheme_website_entry_id, keep_web_entry_id));
+      service->AreDuplicates(wrong_scheme_website_entry, keep_web_entry));
 }
 
 // Test updating duplication data from app provisioning data manager.
@@ -378,18 +366,16 @@
   apps::AppProvisioningDataManager::Get()->PopulateFromDynamicUpdate(
       component_files, install_dir);
 
-  EntryId skype_arc_entry_id(skype_arc_app_id, apps::AppType::kArc);
-  EntryId skype_web_entry_id(skype_web_app_id, apps::AppType::kWeb);
+  Entry skype_arc_entry(skype_arc_app_id, apps::AppType::kArc);
+  Entry skype_web_entry(skype_web_app_id, apps::AppType::kWeb);
 
-  EXPECT_THAT(
-      service->GetDuplicates(skype_arc_entry_id),
-      ElementsAre(Entry(skype_arc_entry_id), Entry(skype_web_entry_id)));
-  EXPECT_TRUE(service->AreDuplicates(skype_arc_entry_id, skype_web_entry_id));
+  EXPECT_THAT(service->GetDuplicates(skype_arc_entry),
+              ElementsAre(Entry(skype_arc_entry), Entry(skype_web_entry)));
+  EXPECT_TRUE(service->AreDuplicates(skype_arc_entry, skype_web_entry));
 
-  EntryId not_duplicate_app_id("not_duplicate_app_id", apps::AppType::kWeb);
-  EXPECT_TRUE(service->GetDuplicates(not_duplicate_app_id).empty());
-  EXPECT_FALSE(
-      service->AreDuplicates(not_duplicate_app_id, skype_web_entry_id));
+  Entry not_duplicate_app("not_duplicate_app_id", apps::AppType::kWeb);
+  EXPECT_TRUE(service->GetDuplicates(not_duplicate_app).empty());
+  EXPECT_FALSE(service->AreDuplicates(not_duplicate_app, skype_web_entry));
 }
 
 class AppDeduplicationServiceAlmanacTest : public testing::Test {
@@ -463,51 +449,50 @@
 
   std::string skype_android_app_id = "com.skype.raider";
   auto it = service->entry_to_group_map_.find(
-      EntryId(skype_android_app_id, AppType::kArc));
+      Entry(skype_android_app_id, AppType::kArc));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(skype_test_index, it->second);
 
   std::string skype_web_id = "https://web.skype.com/";
-  it = service->entry_to_group_map_.find(EntryId(skype_web_id, AppType::kWeb));
+  it = service->entry_to_group_map_.find(Entry(skype_web_id, AppType::kWeb));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(skype_test_index, it->second);
 
-  it = service->entry_to_group_map_.find(EntryId(GURL(skype_web_id)));
+  it = service->entry_to_group_map_.find(Entry(GURL(skype_web_id)));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(skype_test_index, it->second);
 
   auto map_it = service->duplication_map_.find(skype_test_index);
   ASSERT_FALSE(map_it == service->duplication_map_.end());
   EXPECT_THAT(map_it->second.entries,
-              ElementsAre(Entry(EntryId(skype_android_app_id, AppType::kArc)),
-                          Entry(EntryId(skype_web_id, AppType::kWeb)),
-                          Entry(EntryId(GURL(skype_web_id)))));
+              ElementsAre(Entry(skype_android_app_id, AppType::kArc),
+                          Entry(skype_web_id, AppType::kWeb),
+                          Entry(GURL(skype_web_id))));
 
   uint32_t duo_test_index = 2;
 
   std::string duo_android_app_id = "com.google.duo";
   it = service->entry_to_group_map_.find(
-      EntryId(duo_android_app_id, AppType::kArc));
+      Entry(duo_android_app_id, AppType::kArc));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(duo_test_index, it->second);
 
   std::string duo_web_app_id = "https://duo.google.com/?lfhs=2";
-  it =
-      service->entry_to_group_map_.find(EntryId(duo_web_app_id, AppType::kWeb));
+  it = service->entry_to_group_map_.find(Entry(duo_web_app_id, AppType::kWeb));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(duo_test_index, it->second);
 
   std::string duo_website_app_id = "https://duo.google.com/?lfhs=2";
-  it = service->entry_to_group_map_.find(EntryId(GURL(duo_website_app_id)));
+  it = service->entry_to_group_map_.find(Entry(GURL(duo_website_app_id)));
   ASSERT_NE(it, service->entry_to_group_map_.end());
   EXPECT_EQ(duo_test_index, it->second);
 
   map_it = service->duplication_map_.find(duo_test_index);
   ASSERT_FALSE(map_it == service->duplication_map_.end());
   EXPECT_THAT(map_it->second.entries,
-              ElementsAre(Entry(EntryId(duo_android_app_id, AppType::kArc)),
-                          Entry(EntryId(duo_web_app_id, AppType::kWeb)),
-                          Entry(EntryId(GURL(duo_website_app_id)))));
+              ElementsAre(Entry(duo_android_app_id, AppType::kArc),
+                          Entry(duo_web_app_id, AppType::kWeb),
+                          Entry(GURL(duo_website_app_id))));
 }
 
 TEST_F(AppDeduplicationServiceAlmanacTest,
@@ -627,9 +612,9 @@
 
   EXPECT_TRUE(service->IsServiceOn());
 
-  EntryId viber_arc_entry_id(viber_arc_app_id, apps::AppType::kArc);
+  Entry viber_arc_entry(viber_arc_app_id, apps::AppType::kArc);
 
-  EXPECT_TRUE(service->GetDuplicates(viber_arc_entry_id).empty());
+  EXPECT_TRUE(service->GetDuplicates(viber_arc_entry).empty());
 }
 
 TEST_F(AppDeduplicationServiceAlmanacTest, InvalidServiceNoDuplicates) {
diff --git a/chrome/browser/apps/app_deduplication_service/entry_types.cc b/chrome/browser/apps/app_deduplication_service/entry_types.cc
index 2bdadb7b..8efd8a9 100644
--- a/chrome/browser/apps/app_deduplication_service/entry_types.cc
+++ b/chrome/browser/apps/app_deduplication_service/entry_types.cc
@@ -10,17 +10,17 @@
 
 namespace apps::deduplication {
 
-EntryId::EntryId(std::string app_id, AppType app_type)
+Entry::Entry(std::string app_id, AppType app_type)
     : entry_type(EntryType::kApp), id(std::move(app_id)), app_type(app_type) {}
-EntryId::EntryId(const GURL& url)
+Entry::Entry(const GURL& url)
     : entry_type(EntryType::kWebPage), id(url.spec()) {}
 
-bool EntryId::operator==(const EntryId& other) const {
+bool Entry::operator==(const Entry& other) const {
   return entry_type == other.entry_type && id == other.id &&
          (entry_type != EntryType::kApp || app_type == other.app_type);
 }
 
-bool EntryId::operator<(const EntryId& other) const {
+bool Entry::operator<(const Entry& other) const {
   if (entry_type != other.entry_type)
     return entry_type < other.entry_type;
 
@@ -30,25 +30,15 @@
   return id < other.id;
 }
 
-Entry::Entry(EntryId entry_id) : entry_id(std::move(entry_id)) {}
-
-bool Entry::operator==(const Entry& other) const {
-  return entry_id == other.entry_id;
-}
-
-bool Entry::operator<(const Entry& other) const {
-  return entry_id < other.entry_id;
-}
-
-std::ostream& operator<<(std::ostream& out, const EntryId& entry_id) {
+std::ostream& operator<<(std::ostream& out, const Entry& entry) {
   out << "EntryType: "
-      << static_cast<std::underlying_type<EntryType>::type>(entry_id.entry_type)
+      << static_cast<std::underlying_type<EntryType>::type>(entry.entry_type)
       << std::endl;
-  out << "Id: " << entry_id.id << std::endl;
-  if (entry_id.app_type.has_value()) {
+  out << "Id: " << entry.id << std::endl;
+  if (entry.app_type.has_value()) {
     out << "AppType: "
         << static_cast<std::underlying_type<AppType>::type>(
-               entry_id.app_type.value())
+               entry.app_type.value())
         << std::endl;
   }
   return out;
diff --git a/chrome/browser/apps/app_deduplication_service/entry_types.h b/chrome/browser/apps/app_deduplication_service/entry_types.h
index d3f4910..8d3d8e5 100644
--- a/chrome/browser/apps/app_deduplication_service/entry_types.h
+++ b/chrome/browser/apps/app_deduplication_service/entry_types.h
@@ -14,27 +14,26 @@
 
 namespace apps::deduplication {
 
-enum class EntryType {
-  kApp,
-  kWebPage,
-  kPhoneHubApp,
-};
+enum class EntryType { kApp, kWebPage };
 
-struct EntryId {
-  EntryId() = default;
+// Deduplication entry, each entry represents an app or a web page that could be
+// identified as duplicates with each other.
+struct Entry {
+  Entry() = default;
+
   // Constructor for apps.
-  EntryId(std::string app_id, AppType app_type);
+  Entry(std::string app_id, AppType app_type);
 
   // Constructor for web pages.
-  explicit EntryId(const GURL& url);
+  explicit Entry(const GURL& url);
 
-  EntryId(const EntryId&) = default;
-  EntryId& operator=(const EntryId&) = default;
-  EntryId(EntryId&&) = default;
-  EntryId& operator=(EntryId&&) = default;
+  Entry(const Entry&) = default;
+  Entry& operator=(const Entry&) = default;
+  Entry(Entry&&) = default;
+  Entry& operator=(Entry&&) = default;
 
-  bool operator==(const EntryId& other) const;
-  bool operator<(const EntryId& other) const;
+  bool operator==(const Entry& other) const;
+  bool operator<(const Entry& other) const;
 
   EntryType entry_type;
 
@@ -46,24 +45,7 @@
 };
 
 // For logging and debugging purposes.
-std::ostream& operator<<(std::ostream& out, const EntryId& entry_id);
-
-// Deduplication entry, each entry represents an app or a web page that could be
-// identified as duplicates with each other.
-struct Entry {
-  explicit Entry(EntryId entry_id);
-
-  Entry(const Entry&) = default;
-  Entry& operator=(const Entry&) = default;
-  Entry(Entry&&) = default;
-  Entry& operator=(Entry&&) = default;
-
-  bool operator==(const Entry& other) const;
-  bool operator<(const Entry& other) const;
-
-  // Unique identifier for deduplication entry.
-  EntryId entry_id;
-};
+std::ostream& operator<<(std::ostream& out, const Entry& entry);
 
 }  // namespace apps::deduplication
 
diff --git a/chrome/browser/apps/app_preload_service/BUILD.gn b/chrome/browser/apps/app_preload_service/BUILD.gn
index c35cf775..7fcf491 100644
--- a/chrome/browser/apps/app_preload_service/BUILD.gn
+++ b/chrome/browser/apps/app_preload_service/BUILD.gn
@@ -27,10 +27,12 @@
     "//chrome/browser/apps/almanac_api_client/proto",
     "//chrome/browser/apps/app_preload_service/proto",
     "//chrome/browser/apps/app_service",
+    "//chrome/browser/ash/crosapi",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/web_applications",
     "//chrome/common:channel_info",
     "//chrome/common:chrome_features",
+    "//chromeos/crosapi/mojom",
     "//components/keyed_service/core",
     "//components/pref_registry",
     "//components/prefs",
@@ -80,6 +82,7 @@
   sources = [
     "app_preload_service_browsertest.cc",
     "web_app_preload_installer_browsertest.cc",
+    "web_app_preload_installer_lacros_browsertest.cc",
   ]
 
   defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
@@ -90,10 +93,12 @@
     "//base",
     "//chrome/browser/apps/app_preload_service/proto",
     "//chrome/browser/apps/app_service",
+    "//chrome/browser/ash/crosapi",
     "//chrome/browser/ui",
     "//chrome/browser/web_applications",
     "//chrome/browser/web_applications:web_applications_test_support",
     "//chrome/common:chrome_features",
+    "//chrome/test:test_support",
     "//chrome/test:test_support_ui",
     "//components/services/app_service/public/cpp:app_types",
     "//components/services/app_service/public/cpp:app_update",
diff --git a/chrome/browser/apps/app_preload_service/web_app_preload_installer.cc b/chrome/browser/apps/app_preload_service/web_app_preload_installer.cc
index 55f0e92..a7732be 100644
--- a/chrome/browser/apps/app_preload_service/web_app_preload_installer.cc
+++ b/chrome/browser/apps/app_preload_service/web_app_preload_installer.cc
@@ -7,12 +7,16 @@
 #include <memory>
 
 #include "base/metrics/histogram_functions.h"
+#include "chrome/browser/ash/crosapi/crosapi_ash.h"
+#include "chrome/browser/ash/crosapi/crosapi_manager.h"
+#include "chrome/browser/ash/crosapi/web_app_service_ash.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/commands/install_preloaded_verified_app_command.h"
 #include "chrome/browser/web_applications/web_app_command_manager.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
+#include "chromeos/crosapi/mojom/web_app_types.mojom.h"
 #include "components/webapps/browser/install_result_code.h"
 #include "net/base/net_errors.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
@@ -78,22 +82,26 @@
     const PreloadAppDefinition& app,
     WebAppPreloadInstalledCallback callback) {
   DCHECK_EQ(app.GetPlatform(), AppType::kWeb);
-
   if (web_app::IsWebAppsCrosapiEnabled()) {
-    // Installation in Lacros is not implemented yet. Report the installation as
-    // successful to prevent useless retries.
-    // TODO(b/267667215): Support web app installation for Lacros web apps.
-    std::move(callback).Run(/*success=*/true);
-    return;
+    if (crosapi::CrosapiManager::Get()
+            ->crosapi_ash()
+            ->web_app_service_ash()
+            ->GetWebAppProviderBridge() != nullptr) {
+      InstallAppImpl(app, std::move(callback));
+    } else {
+      // Report a successful installation to prevent useless retries.
+      // TODO(melzhang): Support waiting for Lacros to start up before
+      // performing installation.
+      std::move(callback).Run(/*success=*/true);
+    }
+  } else {
+    auto* provider = web_app::WebAppProvider::GetForWebApps(profile_);
+    DCHECK(provider);
+    provider->on_registry_ready().Post(
+        FROM_HERE, base::BindOnce(&WebAppPreloadInstaller::InstallAppImpl,
+                                  weak_ptr_factory_.GetWeakPtr(), app,
+                                  std::move(callback)));
   }
-
-  auto* provider = web_app::WebAppProvider::GetForWebApps(profile_);
-  DCHECK(provider);
-
-  provider->on_registry_ready().Post(
-      FROM_HERE,
-      base::BindOnce(&WebAppPreloadInstaller::InstallAppImpl,
-                     weak_ptr_factory_.GetWeakPtr(), app, std::move(callback)));
 }
 
 std::string WebAppPreloadInstaller::GetAppId(
@@ -159,17 +167,43 @@
 
   auto* provider = web_app::WebAppProvider::GetForWebApps(profile_);
 
+  // TODO(b/284053861) Move allowlist into InstallPreloadedVerifiedAppCommand.
   base::flat_set<std::string> host_allowlist = {
       "meltingpot.googleusercontent.com"};
 
-  provider->command_manager().ScheduleCommand(
-      std::make_unique<web_app::InstallPreloadedVerifiedAppCommand>(
-          webapps::WebappInstallSource::PRELOADED_OEM,
-          /*document_url=*/GURL(app.GetWebAppManifestId()).GetWithEmptyPath(),
-          /*manifest_url=*/app.GetWebAppOriginalManifestUrl(),
-          std::move(*response), GetAppId(app), std::move(host_allowlist),
-          base::BindOnce(&WebAppPreloadInstaller::OnAppInstalled,
-                         weak_ptr_factory_.GetWeakPtr(), std::move(callback))));
+  if (web_app::IsWebAppsCrosapiEnabled()) {
+    crosapi::mojom::WebAppProviderBridge* web_app_provider_bridge =
+        crosapi::CrosapiManager::Get()
+            ->crosapi_ash()
+            ->web_app_service_ash()
+            ->GetWebAppProviderBridge();
+    if (!web_app_provider_bridge) {
+      std::move(callback).Run(/*success=*/false);
+      return;
+    }
+    auto web_app_install_info = crosapi::mojom::PreloadWebAppInstallInfo::New();
+    web_app_install_info->document_url =
+        GURL(app.GetWebAppManifestId()).GetWithEmptyPath();
+    web_app_install_info->manifest_url = app.GetWebAppOriginalManifestUrl();
+    web_app_install_info->expected_app_id = GetAppId(app);
+    web_app_install_info->manifest = std::move(*response);
+
+    web_app_provider_bridge->InstallPreloadWebApp(
+        std::move(web_app_install_info),
+        base::BindOnce(&WebAppPreloadInstaller::OnAppInstalled,
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+    return;
+  } else {
+    provider->command_manager().ScheduleCommand(
+        std::make_unique<web_app::InstallPreloadedVerifiedAppCommand>(
+            webapps::WebappInstallSource::PRELOADED_OEM,
+            /*document_url=*/GURL(app.GetWebAppManifestId()).GetWithEmptyPath(),
+            /*manifest_url=*/app.GetWebAppOriginalManifestUrl(),
+            std::move(*response), GetAppId(app), std::move(host_allowlist),
+            base::BindOnce(&WebAppPreloadInstaller::OnAppInstalled,
+                           weak_ptr_factory_.GetWeakPtr(),
+                           std::move(callback))));
+  }
 }
 
 void WebAppPreloadInstaller::OnAppInstalled(
diff --git a/chrome/browser/apps/app_preload_service/web_app_preload_installer_lacros_browsertest.cc b/chrome/browser/apps/app_preload_service/web_app_preload_installer_lacros_browsertest.cc
new file mode 100644
index 0000000..f7c67fd
--- /dev/null
+++ b/chrome/browser/apps/app_preload_service/web_app_preload_installer_lacros_browsertest.cc
@@ -0,0 +1,148 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/functional/bind.h"
+#include "base/test/test_future.h"
+#include "chrome/browser/apps/app_preload_service/web_app_preload_installer.h"
+#include "chrome/browser/apps/app_service/app_service_proxy.h"
+#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
+#include "chrome/browser/ash/crosapi/browser_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_helpers.h"
+#include "chrome/test/base/chromeos/ash_browser_test_starter.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/services/app_service/public/cpp/app_registry_cache.h"
+#include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/app_update.h"
+#include "components/webapps/browser/install_result_code.h"
+#include "content/public/test/browser_test.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace apps {
+
+class WebAppPreloadInstallerLacrosBrowserTest : public InProcessBrowserTest {
+ public:
+  void SetUpInProcessBrowserTestFixture() override {
+    if (ash_starter_.HasLacrosArgument()) {
+      ASSERT_TRUE(ash_starter_.PrepareEnvironmentForLacros());
+    }
+  }
+
+  void SetUpOnMainThread() override {
+    InProcessBrowserTest::SetUpOnMainThread();
+    if (ash_starter_.HasLacrosArgument()) {
+      ash_starter_.StartLacros(this);
+    }
+
+    https_server_.RegisterRequestHandler(base::BindRepeating(
+        &WebAppPreloadInstallerLacrosBrowserTest::HandleRequest,
+        base::Unretained(this)));
+    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
+
+    ASSERT_TRUE(https_server_.Start());
+  }
+
+  std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
+      const net::test_server::HttpRequest& request) {
+    if (request.relative_url != "/manifest.json" || manifest_.empty()) {
+      return nullptr;
+    }
+
+    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
+    response->set_code(net::HTTP_OK);
+    response->set_content_type("application/json");
+    response->set_content(manifest_);
+    return response;
+  }
+
+  std::string AddIconToManifest(const std::string& manifest_template) {
+    GURL icon_url = https_server()->GetURL("/web_apps/blue-192.png");
+    constexpr char kIconsBlock[] = R"([{
+        "src": "$1",
+        "sizes": "192x192",
+        "type": "image/png"
+      }])";
+    std::string icon_value = base::ReplaceStringPlaceholders(
+        kIconsBlock, {icon_url.spec()}, nullptr);
+    return base::ReplaceStringPlaceholders(manifest_template, {icon_value},
+                                           nullptr);
+  }
+
+  void SetManifestResponse(std::string manifest) { manifest_ = manifest; }
+
+  Profile* profile() { return browser()->profile(); }
+
+  net::EmbeddedTestServer* https_server() { return &https_server_; }
+
+  AppRegistryCache& app_registry_cache() {
+    auto* proxy = AppServiceProxyFactory::GetForProfile(browser()->profile());
+    return proxy->AppRegistryCache();
+  }
+
+ protected:
+  test::AshBrowserTestStarter ash_starter_;
+
+ private:
+  net::EmbeddedTestServer https_server_;
+  std::string manifest_;
+};
+
+IN_PROC_BROWSER_TEST_F(WebAppPreloadInstallerLacrosBrowserTest, InstallOemApp) {
+  if (!ash_starter_.HasLacrosArgument()) {
+    return;
+  }
+  // Assert Lacros is running.
+  ASSERT_TRUE(crosapi::BrowserManager::Get()->IsRunning());
+
+  proto::AppPreloadListResponse_App app;
+  app.set_name("Example App");
+  app.set_package_id("web:https://www.example.com/index.html");
+  app.set_install_reason(proto::AppPreloadListResponse::INSTALL_REASON_OEM);
+
+  auto* web_extras = app.mutable_web_extras();
+  web_extras->set_original_manifest_url(
+      "https://www.example.com/manifest.json");
+  web_extras->set_manifest_url(https_server()->GetURL("/manifest.json").spec());
+
+  constexpr char kManifestTemplate[] = R"({
+    "name": "Example App",
+    "start_url": "/index.html",
+    "scope": "/",
+    "icons": $1
+  })";
+
+  SetManifestResponse(AddIconToManifest(kManifestTemplate));
+
+  base::HistogramTester histograms;
+  base::test::TestFuture<bool> result;
+
+  // Install the app.
+  WebAppPreloadInstaller installer(profile());
+
+  installer.InstallApp(PreloadAppDefinition(app), result.GetCallback());
+  ASSERT_TRUE(result.Get());
+
+  // Check the app is installed in app_registry_cache.
+  auto app_id = web_app::GenerateAppId(
+      absl::nullopt, GURL("https://www.example.com/index.html"));
+  bool found =
+      app_registry_cache().ForOneApp(app_id, [](const AppUpdate& update) {
+        EXPECT_EQ(update.Name(), "Example App");
+        EXPECT_EQ(update.InstallReason(), InstallReason::kOem);
+      });
+  ASSERT_TRUE(found);
+
+  histograms.ExpectBucketCount("AppPreloadService.WebAppInstall.InstallResult",
+                               WebAppPreloadResult::kSuccess, 1);
+  histograms.ExpectBucketCount(
+      "AppPreloadService.WebAppInstall.CommandResultCode",
+      webapps::InstallResultCode::kSuccessNewInstall, 1);
+}
+
+}  // namespace apps
diff --git a/chrome/browser/apps/app_service/BUILD.gn b/chrome/browser/apps/app_service/BUILD.gn
index 9591a931..e9c6f30 100644
--- a/chrome/browser/apps/app_service/BUILD.gn
+++ b/chrome/browser/apps/app_service/BUILD.gn
@@ -164,6 +164,8 @@
       "promise_apps/promise_app.h",
       "promise_apps/promise_app_almanac_connector.cc",
       "promise_apps/promise_app_almanac_connector.h",
+      "promise_apps/promise_app_icon_cache.cc",
+      "promise_apps/promise_app_icon_cache.h",
       "promise_apps/promise_app_registry_cache.cc",
       "promise_apps/promise_app_registry_cache.h",
       "promise_apps/promise_app_service.cc",
@@ -246,6 +248,7 @@
       "//components/arc/common",
       "//components/arc/common:arc_intent_helper_constants",
       "//components/exo",
+      "//components/image_fetcher/core",
       "//components/metrics/structured:structured_events",
       "//components/resources:components_resources",
       "//components/services/app_service/public/cpp:crosapi_utils",
diff --git a/chrome/browser/apps/app_service/intent_util.cc b/chrome/browser/apps/app_service/intent_util.cc
index f28acee..a08bf47 100644
--- a/chrome/browser/apps/app_service/intent_util.cc
+++ b/chrome/browser/apps/app_service/intent_util.cc
@@ -48,6 +48,7 @@
 #include "ash/components/arc/mojom/intent_helper.mojom-shared.h"
 #include "ash/components/arc/mojom/intent_helper.mojom.h"
 #include "chrome/browser/ash/app_list/arc/intent.h"
+#include "chrome/browser/ash/fusebox/fusebox_server.h"
 #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
 #include "components/arc/intent_helper/intent_constants.h"
 #include "components/arc/intent_helper/intent_filter.h"
@@ -734,10 +735,16 @@
       } else if (file->url.SchemeIsFileSystem()) {
         auto file_system_url = apps::GetFileSystemURL(profile, file->url);
         if (file_system_url.is_valid()) {
-          auto crosapi_file = crosapi::mojom::IntentFile::New();
-          crosapi_file->file_path = file_system_url.path();
-          crosapi_file->mime_type = file->mime_type;
-          crosapi_files.push_back(std::move(crosapi_file));
+          base::FilePath path =
+              file_system_url.TypeImpliesPathIsReal()
+                  ? file_system_url.path()
+                  : fusebox::Server::SubstituteFuseboxFilePath(file_system_url);
+          if (!path.empty()) {
+            auto crosapi_file = crosapi::mojom::IntentFile::New();
+            crosapi_file->file_path = std::move(path);
+            crosapi_file->mime_type = file->mime_type;
+            crosapi_files.push_back(std::move(crosapi_file));
+          }
         }
       }
     }
diff --git a/chrome/browser/apps/app_service/intent_util_unittest.cc b/chrome/browser/apps/app_service/intent_util_unittest.cc
index 0b42ebd..b8e94c7 100644
--- a/chrome/browser/apps/app_service/intent_util_unittest.cc
+++ b/chrome/browser/apps/app_service/intent_util_unittest.cc
@@ -43,6 +43,8 @@
 #include "ash/components/arc/mojom/intent_helper.mojom.h"
 #include "base/strings/strcat.h"
 #include "chrome/browser/ash/file_manager/app_id.h"
+#include "chrome/browser/ash/file_manager/path_util.h"
+#include "chrome/browser/ash/fusebox/fusebox_server.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "content/public/test/browser_task_environment.h"
@@ -728,16 +730,27 @@
         TestingBrowserProcess::GetGlobal());
     ASSERT_TRUE(profile_manager_->SetUp());
     profile_ = profile_manager_->CreateTestingProfile("testing_profile");
+
+    // kFileSystemTypeLocal versus kFileSystemTypeArcContent means that the
+    // second one needs to go through Fusebox, as its
+    // FileSystemURL::TypeImpliesPathIsReal() returns false.
     ASSERT_TRUE(
         storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
-            mount_name_, storage::FileSystemType::kFileSystemTypeLocal,
-            storage::FileSystemMountOption(), base::FilePath(fs_root_)));
+            mount_name_local_, storage::FileSystemType::kFileSystemTypeLocal,
+            storage::FileSystemMountOption(), base::FilePath(fs_root_local_)));
+    ASSERT_TRUE(
+        storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
+            mount_name_arc_, storage::kFileSystemTypeArcContent,
+            storage::FileSystemMountOption(), base::FilePath(fs_root_arc_)));
   }
 
   void TearDown() override {
     ASSERT_TRUE(
         storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
-            mount_name_));
+            mount_name_arc_));
+    ASSERT_TRUE(
+        storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
+            mount_name_local_));
     profile_manager_->DeleteAllTestingProfiles();
     profile_ = nullptr;
     profile_manager_.reset();
@@ -758,8 +771,10 @@
   }
 
  protected:
-  const std::string mount_name_ = "TestMountName";
-  const std::string fs_root_ = "/path/to/test/filesystemroot";
+  const std::string mount_name_arc_ = "TestMountNameArc";
+  const std::string mount_name_local_ = "TestMountNameLocal";
+  const std::string fs_root_arc_ = "/fake/android/content/path";
+  const std::string fs_root_local_ = "/path/to/test/filesystemroot";
 
  private:
   content::BrowserTaskEnvironment task_environment_;
@@ -767,13 +782,42 @@
   raw_ptr<TestingProfile, ExperimentalAsh> profile_;
 };
 
-TEST_F(IntentUtilsFileTest, ConvertFileSystemScheme) {
+class IntentUtilsFileSystemSchemeTest
+    : public IntentUtilsFileTest,
+      public ::testing::WithParamInterface<storage::FileSystemType> {};
+
+TEST_P(IntentUtilsFileSystemSchemeTest, ConvertFileSystemScheme) {
+  constexpr char fusebox_subdir[] = "my_subdir";
+  constexpr bool read_only = false;
+  fusebox::Server fusebox_server(nullptr);
+  fusebox_server.RegisterFSURLPrefix(
+      fusebox_subdir,
+      base::StrCat({url::kFileSystemScheme, ":",
+                    GetFileManagerOrigin().Serialize(), storage::kExternalDir,
+                    "/", mount_name_arc_}),
+      read_only);
+
+  base::FilePath in_path;
+  base::FilePath out_path;
+  switch (GetParam()) {
+    case storage::kFileSystemTypeLocal:
+      in_path = base::FilePath(storage::kExternalDir).Append(mount_name_local_);
+      out_path = base::FilePath(fs_root_local_);
+      break;
+    case storage::kFileSystemTypeArcContent:
+      in_path = base::FilePath(storage::kExternalDir).Append(mount_name_arc_);
+      out_path = base::FilePath(file_manager::util::kFuseBoxMediaPath)
+                     .Append(fusebox_subdir);
+      break;
+    default:
+      NOTREACHED();
+  }
+
   auto app_service_intent = std::make_unique<apps::Intent>("action");
   app_service_intent->mime_type = "*/*";
-  const std::string path = "Documents/foo.txt";
+  const std::string relative_path = "Documents/foo.txt";
   const std::string mime_type = "text/plain";
-  auto url =
-      ToGURL(base::FilePath(storage::kExternalDir).Append(mount_name_), path);
+  auto url = ToGURL(in_path, relative_path);
   EXPECT_TRUE(url.SchemeIsFileSystem());
   app_service_intent->files = std::vector<apps::IntentFilePtr>{};
   auto file = std::make_unique<apps::IntentFile>(url);
@@ -786,10 +830,16 @@
   ASSERT_TRUE(crosapi_intent->files.has_value());
   ASSERT_EQ(crosapi_intent->files.value().size(), 1U);
   EXPECT_EQ(crosapi_intent->files.value()[0]->file_path,
-            base::FilePath(fs_root_).Append(base::FilePath(path)));
+            out_path.Append(base::FilePath(relative_path)));
   EXPECT_EQ(crosapi_intent->files.value()[0]->mime_type, mime_type);
 }
 
+INSTANTIATE_TEST_SUITE_P(
+    IntentUtilsFileSystemScheme,
+    IntentUtilsFileSystemSchemeTest,
+    testing::ValuesIn({storage::kFileSystemTypeLocal,
+                       storage::kFileSystemTypeArcContent}));
+
 TEST_F(IntentUtilsFileTest, ConvertFileScheme) {
   auto app_service_intent = std::make_unique<apps::Intent>("action");
   app_service_intent->mime_type = "*/*";
@@ -814,7 +864,7 @@
 TEST_F(IntentUtilsFileTest, CrosapiIntentToAppService) {
   const std::string path = "Documents/foo.txt";
   std::vector<base::FilePath> file_paths;
-  file_paths.push_back(base::FilePath(fs_root_).Append(path));
+  file_paths.push_back(base::FilePath(fs_root_local_).Append(path));
   auto crosapi_intent =
       apps_util::CreateCrosapiIntentForViewFiles(std::move(file_paths));
 
@@ -826,6 +876,7 @@
   ASSERT_EQ(crosapi_intent->files.value().size(), 1U);
   EXPECT_EQ(
       app_service_intent->files[0]->url,
-      ToGURL(base::FilePath(storage::kExternalDir).Append(mount_name_), path));
+      ToGURL(base::FilePath(storage::kExternalDir).Append(mount_name_local_),
+             path));
 }
 #endif
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app.cc b/chrome/browser/apps/app_service/promise_apps/promise_app.cc
index eeb768d3..7c03d17 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app.cc
@@ -17,6 +17,9 @@
     : package_id(package_id) {}
 PromiseApp::~PromiseApp() = default;
 
+PromiseAppIcon::PromiseAppIcon() = default;
+PromiseAppIcon::~PromiseAppIcon() = default;
+
 PromiseAppPtr PromiseApp::Clone() const {
   auto promise_app = std::make_unique<PromiseApp>(package_id);
   if (name.has_value()) {
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app.h b/chrome/browser/apps/app_service/promise_apps/promise_app.h
index 059541e..a2b171a 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app.h
@@ -48,6 +48,20 @@
 
 using PromiseAppPtr = std::unique_ptr<PromiseApp>;
 
+class PromiseAppIcon {
+ public:
+  PromiseAppIcon();
+  ~PromiseAppIcon();
+  PromiseAppIcon(const PromiseAppIcon&) = delete;
+  PromiseAppIcon& operator=(const PromiseAppIcon&) = delete;
+
+  gfx::ImageSkia icon;
+  absl::optional<int> width_in_pixels;
+  bool is_masking_allowed;
+};
+
+using PromiseAppIconPtr = std::unique_ptr<PromiseAppIcon>;
+
 }  // namespace apps
 
 #endif  // CHROME_BROWSER_APPS_APP_SERVICE_PROMISE_APPS_PROMISE_APP_H_
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.cc
new file mode 100644
index 0000000..f1135e4d
--- /dev/null
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.cc
@@ -0,0 +1,50 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h"
+#include <vector>
+
+#include "base/logging.h"
+#include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
+#include "components/services/app_service/public/cpp/icon_types.h"
+#include "ui/gfx/image/image.h"
+
+namespace apps {
+
+PromiseAppIconCache::PromiseAppIconCache() = default;
+PromiseAppIconCache::~PromiseAppIconCache() = default;
+
+void PromiseAppIconCache::SaveIcon(const PackageId& package_id,
+                                   std::unique_ptr<PromiseAppIcon> icon) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (icon == nullptr) {
+    LOG(ERROR) << "PromiseAppIconCache cannot save nullptr icon.";
+    return;
+  }
+  if (icon_cache_.contains(package_id)) {
+    icon_cache_[package_id].push_back(std::move(icon));
+  } else {
+    std::vector<PromiseAppIconPtr> icons;
+    icons.push_back(std::move(icon));
+    icon_cache_.insert(std::make_pair(package_id, std::move(icons)));
+  }
+}
+
+bool PromiseAppIconCache::DoesPackageIdHaveIcons(const PackageId& package_id) {
+  return icon_cache_.contains(package_id);
+}
+
+std::vector<PromiseAppIcon*> PromiseAppIconCache::GetIconsForTesting(
+    const PackageId& package_id) {
+  std::vector<PromiseAppIcon*> icons;
+  if (!icon_cache_.contains(package_id)) {
+    return icons;
+  }
+  for (PromiseAppIconPtr& icon : icon_cache_[package_id]) {
+    icons.push_back(icon.get());
+  }
+  return icons;
+}
+
+}  // namespace apps
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h
new file mode 100644
index 0000000..938db54
--- /dev/null
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h
@@ -0,0 +1,45 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_APPS_APP_SERVICE_PROMISE_APPS_PROMISE_APP_ICON_CACHE_H_
+#define CHROME_BROWSER_APPS_APP_SERVICE_PROMISE_APPS_PROMISE_APP_ICON_CACHE_H_
+
+#include <map>
+
+#include "chrome/browser/apps/app_service/package_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace apps {
+
+class PromiseAppIcon;
+
+// Stores promise app icons. Each promise app may have several icons of
+// different sizes.
+class PromiseAppIconCache {
+ public:
+  PromiseAppIconCache();
+  ~PromiseAppIconCache();
+
+  // Save an icon into the cache against a package ID. If there is already an
+  // icon for this package ID, append it to the list of existing icons.
+  void SaveIcon(const PackageId& package_id,
+                std::unique_ptr<PromiseAppIcon> icon);
+
+  // Checks whether there is at least one icon for a package ID.
+  bool DoesPackageIdHaveIcons(const PackageId& package_id);
+
+  // For testing only. Retrieves pointers to all the registered icons for a
+  // package ID.
+  std::vector<PromiseAppIcon*> GetIconsForTesting(const PackageId& package_id);
+
+ private:
+  std::map<PackageId, std::vector<std::unique_ptr<PromiseAppIcon>>> icon_cache_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+};
+
+}  // namespace apps
+
+#endif  // CHROME_BROWSER_APPS_APP_SERVICE_PROMISE_APPS_PROMISE_APP_ICON_CACHE_H_
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache_unittest.cc
new file mode 100644
index 0000000..7cf523dc5
--- /dev/null
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache_unittest.cc
@@ -0,0 +1,73 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h"
+
+#include "chrome/browser/apps/app_service/package_id.h"
+#include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace apps {
+
+const PackageId kTestPackageId(AppType::kArc, "test.package.name");
+
+class PromiseAppIconCacheTest : public testing::Test {
+ public:
+  void SetUp() override { cache_ = std::make_unique<PromiseAppIconCache>(); }
+
+  PromiseAppIconCache* icon_cache() { return cache_.get(); }
+
+ private:
+  std::unique_ptr<PromiseAppIconCache> cache_;
+};
+
+TEST_F(PromiseAppIconCacheTest, SaveIcon) {
+  PromiseAppIconPtr icon = std::make_unique<PromiseAppIcon>();
+  icon->icon = gfx::ImageSkia();
+  icon->is_masking_allowed = true;
+  icon->width_in_pixels = 50;
+
+  EXPECT_FALSE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
+
+  icon_cache()->SaveIcon(kTestPackageId, std::move(icon));
+  EXPECT_TRUE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
+  std::vector<PromiseAppIcon*> icons_saved =
+      icon_cache()->GetIconsForTesting(kTestPackageId);
+  EXPECT_EQ(icons_saved.size(), 1u);
+  EXPECT_EQ(icons_saved[0]->is_masking_allowed, true);
+  EXPECT_EQ(icons_saved[0]->width_in_pixels, 50);
+}
+
+TEST_F(PromiseAppIconCacheTest, SaveMultipleIcons) {
+  PromiseAppIconPtr icon_small = std::make_unique<PromiseAppIcon>();
+  icon_small->icon = gfx::ImageSkia();
+  icon_small->is_masking_allowed = true;
+  icon_small->width_in_pixels = 512;
+
+  PromiseAppIconPtr icon_large = std::make_unique<PromiseAppIcon>();
+  icon_large->icon = gfx::ImageSkia();
+  icon_large->is_masking_allowed = false;
+  icon_large->width_in_pixels = 1024;
+
+  EXPECT_FALSE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
+
+  icon_cache()->SaveIcon(kTestPackageId, std::move(icon_small));
+  EXPECT_TRUE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
+  EXPECT_EQ(icon_cache()->GetIconsForTesting(kTestPackageId).size(), 1u);
+
+  icon_cache()->SaveIcon(kTestPackageId, std::move(icon_large));
+
+  // We should have 2 icons for the same package ID.
+  std::vector<PromiseAppIcon*> icons_saved =
+      icon_cache()->GetIconsForTesting(kTestPackageId);
+  EXPECT_EQ(icons_saved.size(), 2u);
+  EXPECT_EQ(icons_saved[0]->is_masking_allowed, true);
+  EXPECT_EQ(icons_saved[0]->width_in_pixels, 512);
+  EXPECT_EQ(icons_saved[1]->is_masking_allowed, false);
+  EXPECT_EQ(icons_saved[1]->width_in_pixels, 1024);
+}
+
+}  // namespace apps
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc
index 6753824a..d6221539 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc
@@ -10,10 +10,46 @@
 
 namespace apps {
 
+PromiseAppRegistryCache::Observer::Observer(PromiseAppRegistryCache* cache) {
+  Observer::Observe(cache);
+}
+
+PromiseAppRegistryCache::Observer::Observer() = default;
+
+PromiseAppRegistryCache::Observer::~Observer() {
+  if (cache_) {
+    cache_->RemoveObserver(this);
+  }
+}
+
+void PromiseAppRegistryCache::Observer::Observe(
+    PromiseAppRegistryCache* cache) {
+  if (cache == cache_) {
+    // Early exit to avoid infinite loops if we're in the middle of a callback.
+    return;
+  }
+  if (cache_) {
+    cache_->RemoveObserver(this);
+  }
+  cache_ = cache;
+  if (cache_) {
+    cache_->AddObserver(this);
+  }
+}
+
 PromiseAppRegistryCache::PromiseAppRegistryCache() = default;
 
 PromiseAppRegistryCache::~PromiseAppRegistryCache() = default;
 
+void PromiseAppRegistryCache::AddObserver(Observer* observer) {
+  DCHECK(observer);
+  observers_.AddObserver(observer);
+}
+
+void PromiseAppRegistryCache::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 void PromiseAppRegistryCache::OnPromiseApp(PromiseAppPtr delta) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
@@ -26,17 +62,17 @@
   // Retrieve the current promise app state.
   apps::PromiseApp* state = FindPromiseApp(delta->package_id);
 
-  // Update the existing promise app if it exists.
   if (state) {
+    // Update the existing promise app if it exists.
     PromiseAppUpdate::Merge(state, delta.get());
-    update_in_progress_ = false;
-    return;
+  } else {
+    // Add the promise app instance to the cache if it isn't registered yet.
+    promise_app_map_[delta->package_id] = delta->Clone();
   }
 
-  // Add the promise app instance to the cache if it isn't registered yet.
-  promise_app_map_[delta->package_id] = delta->Clone();
-
-  // TODO(b/261907495): Notify observers.
+  for (auto& observer : observers_) {
+    observer.OnPromiseAppUpdate(PromiseAppUpdate(state, delta.get()));
+  }
 
   update_in_progress_ = false;
 }
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h
index a2e54d3..4c9a1071 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h
@@ -7,12 +7,15 @@
 #include <map>
 #include <memory>
 
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
 #include "base/sequence_checker.h"
 #include "chrome/browser/apps/app_service/package_id.h"
 
 namespace apps {
 
 struct PromiseApp;
+class PromiseAppUpdate;
 using PromiseAppPtr = std::unique_ptr<PromiseApp>;
 using PromiseAppCacheMap = std::map<PackageId, PromiseAppPtr>;
 
@@ -20,6 +23,41 @@
 // system.
 class PromiseAppRegistryCache {
  public:
+  class Observer : public base::CheckedObserver {
+   public:
+    Observer(const Observer&) = delete;
+    Observer& operator=(const Observer&) = delete;
+
+    // The apps::PromiseAppUpdate argument shouldn't be accessed after
+    // OnPromiseAppUpdate returns.
+    virtual void OnPromiseAppUpdate(const PromiseAppUpdate& update) {}
+
+    // Called when the PromiseAppRegistryCache object (the thing that this
+    // observer observes) will be destroyed. In response, the observer, |this|,
+    // should call "cache->RemoveObserver(this)", whether directly or indirectly
+    // (e.g. via base::ScopedObservation::Remove or via Observe(nullptr)).
+    virtual void OnPromiseAppRegistryCacheWillBeDestroyed(
+        PromiseAppRegistryCache* cache) = 0;
+
+   protected:
+    // Use this constructor when the observer |this| is tied to a single
+    // PromiseAppRegistryCache for its entire lifetime, or until the observee
+    // (the PromiseAppRegistryCache) is destroyed, whichever comes first.
+    explicit Observer(PromiseAppRegistryCache* cache);
+
+    // Use this constructor when the observer |this| wants to observe a
+    // PromiseAppRegistryCache for part of its lifetime. It can then call
+    // Observe() to start and stop observing.
+    Observer();
+
+    ~Observer() override;
+
+    void Observe(PromiseAppRegistryCache* cache);
+
+   private:
+    raw_ptr<PromiseAppRegistryCache> cache_ = nullptr;
+  };
+
   PromiseAppRegistryCache();
 
   PromiseAppRegistryCache(const PromiseAppRegistryCache&) = delete;
@@ -47,6 +85,9 @@
   // not store the pointer as the promise app may be destroyed at any time.
   const PromiseApp* GetPromiseAppForTesting(const PackageId& package_id) const;
 
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
  private:
   // Retrieve the registered promise app with the specified package_id. Returns
   // nullptr if the promise app does not exist.
@@ -54,6 +95,8 @@
 
   apps::PromiseAppCacheMap promise_app_map_;
 
+  base::ObserverList<Observer> observers_;
+
   // Flag to check whether an update to a promise app is already in progress. We
   // shouldn't have more than one concurrent update to a package_id, e.g. if
   // OnPromiseApp notifies observers and triggers them to call OnPromiseApp
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_service.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_service.cc
index 2acb7824..42bb258 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_service.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_service.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_service.h"
 
+#include <memory>
+
+#include "base/check.h"
 #include "base/logging.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/apps/app_service/package_id.h"
@@ -11,13 +14,65 @@
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h"
+#include "chrome/browser/image_fetcher/image_decoder_impl.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/image_fetcher/core/image_fetcher_impl.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/gfx/image/image.h"
+#include "url/gurl.h"
+
+namespace {
+const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+    net::DefineNetworkTrafficAnnotation("promise_app_service_download_icon",
+                                        R"(
+    semantics {
+      sender: "Promise App Service"
+      description:
+        "Queries a Google server to fetch the icon of an app that is being "
+        "installed or is pending installation on the device."
+      trigger:
+        "A request can be sent when an app starts installing or is pending "
+        "installation."
+      destination: GOOGLE_OWNED_SERVICE
+      internal {
+        contacts {
+          email: "chromeos-apps-foundation-team@google.com"
+        }
+      }
+      user_data {
+        type: SENSITIVE_URL
+      }
+      data: "URL of the image to be fetched."
+      last_reviewed: "2023-05-16"
+    }
+    policy {
+      cookies_allowed: NO
+      setting:
+        "This request is enabled by app sync without passphrase. You can"
+        "disable this request in the 'Sync and Google services' section"
+        "in Settings by either: 1. Going into the 'Manage What You Sync'"
+        "settings page and turning off Apps sync; OR 2. In the 'Encryption"
+        "Options' settings page, select the option to use a sync passphrase."
+      policy_exception_justification:
+        "This feature is required to deliver core user experiences and "
+        "cannot be disabled by policy."
+    }
+  )");
+
+}  // namespace
 
 namespace apps {
 PromiseAppService::PromiseAppService(Profile* profile)
     : promise_app_registry_cache_(
           std::make_unique<apps::PromiseAppRegistryCache>()),
       promise_app_almanac_connector_(
-          std::make_unique<PromiseAppAlmanacConnector>(profile)) {}
+          std::make_unique<PromiseAppAlmanacConnector>(profile)),
+      promise_app_icon_cache_(std::make_unique<apps::PromiseAppIconCache>()),
+      image_fetcher_(std::make_unique<image_fetcher::ImageFetcherImpl>(
+          std::make_unique<ImageDecoderImpl>(),
+          profile->GetURLLoaderFactory())) {}
 
 PromiseAppService::~PromiseAppService() = default;
 
@@ -25,7 +80,13 @@
   return promise_app_registry_cache_.get();
 }
 
+PromiseAppIconCache* PromiseAppService::PromiseAppIconCache() {
+  return promise_app_icon_cache_.get();
+}
+
 void PromiseAppService::OnPromiseApp(PromiseAppPtr delta) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   const PackageId package_id = delta->package_id;
   bool is_existing_registration =
       promise_app_registry_cache_->HasPromiseApp(package_id);
@@ -52,9 +113,16 @@
   skip_almanac_for_testing_ = skip_almanac;
 }
 
+void PromiseAppService::SetImageFetcherForTesting(
+    std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher) {
+  image_fetcher_ = std::move(image_fetcher);
+}
+
 void PromiseAppService::OnGetPromiseAppInfoCompleted(
     const PackageId& package_id,
     absl::optional<PromiseAppWrapper> promise_app_info) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   if (!promise_app_info.has_value()) {
     LOG(ERROR) << "Request for app details from the Almanac Promise App API "
                   "failed for package "
@@ -91,7 +159,70 @@
   PromiseAppPtr promise_app =
       std::make_unique<PromiseApp>(promise_app_info->GetPackageId().value());
   promise_app->name = promise_app_info->GetName().value();
-  promise_app->should_show = true;
   OnPromiseApp(std::move(promise_app));
+
+  pending_download_count_[package_id] = promise_app_info->GetIcons().size();
+
+  for (auto icon : promise_app_info->GetIcons()) {
+    PromiseAppIconPtr promise_app_icon = std::make_unique<PromiseAppIcon>();
+    promise_app_icon->width_in_pixels = icon.GetWidthInPixels();
+    promise_app_icon->is_masking_allowed = icon.IsMaskingAllowed();
+
+    image_fetcher_->FetchImage(
+        icon.GetUrl(),
+        base::BindOnce(&PromiseAppService::OnIconDownloaded,
+                       weak_ptr_factory_.GetWeakPtr(), package_id,
+                       std::move(promise_app_icon)),
+        image_fetcher::ImageFetcherParams(kTrafficAnnotation,
+                                          "Promise App Service Icon Fetcher"));
+  }
+}
+
+void PromiseAppService::OnIconDownloaded(
+    const PackageId& package_id,
+    PromiseAppIconPtr promise_app_icon,
+    const gfx::Image& image,
+    const image_fetcher::RequestMetadata& metadata) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  // If we weren't expecting an icon to be downloaded for this package ID, don't
+  // process the result.
+  if (!pending_download_count_.contains(package_id)) {
+    LOG(ERROR) << "Will not save icon for unexpected package ID: "
+               << package_id.ToString();
+    return;
+  }
+  if (pending_download_count_[package_id] == 0) {
+    LOG(ERROR) << "Will not save icon for unexpected package ID: "
+               << package_id.ToString();
+    pending_download_count_.erase(package_id);
+    return;
+  }
+
+  // Save valid icons to the icon cache.
+  if (!image.IsEmpty()) {
+    promise_app_icon->icon = image.AsImageSkia();
+    promise_app_icon_cache_->SaveIcon(package_id, std::move(promise_app_icon));
+  }
+
+  // If there are still icons to be downloaded, we should wait for those
+  // downloads to finish before updating the promise app. Otherwise, stop
+  // tracking pending downloads for this package ID.
+  pending_download_count_[package_id] -= 1;
+  if (pending_download_count_[package_id] > 0) {
+    return;
+  }
+  pending_download_count_.erase(package_id);
+
+  // If there are no successfully downloaded icons, we don't want to update or
+  // show the promise icon at all.
+  if (!promise_app_icon_cache_->DoesPackageIdHaveIcons(package_id)) {
+    return;
+  }
+
+  // Update the promise app so it can show to the user.
+  PromiseAppPtr promise_app = std::make_unique<PromiseApp>(package_id);
+  promise_app->should_show = true;
+  promise_app_registry_cache_->OnPromiseApp(std::move(promise_app));
 }
 }  // namespace apps
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_service.h b/chrome/browser/apps/app_service/promise_apps/promise_app_service.h
index 7359769..f449f80 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_service.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_service.h
@@ -7,20 +7,42 @@
 
 #include <memory>
 
+#include "base/functional/callback_forward.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
 
+namespace gfx {
+class Image;
+}
+namespace image_fetcher {
+class ImageFetcher;
+struct RequestMetadata;
+}  // namespace image_fetcher
+
 namespace apps {
 
 struct PromiseApp;
-using PromiseAppPtr = std::unique_ptr<PromiseApp>;
+struct IconValue;
+
+class PromiseAppIcon;
+class PromiseAppIconCache;
+
 class PackageId;
 class PromiseAppAlmanacConnector;
 class PromiseAppRegistryCache;
 class PromiseAppWrapper;
 
+using PromiseAppPtr = std::unique_ptr<PromiseApp>;
+using PromiseAppIconPtr = std::unique_ptr<PromiseAppIcon>;
+using IconValuePtr = std::unique_ptr<IconValue>;
+
+using IconDownloadedCallback =
+    base::OnceCallback<void(const gfx::Image& image,
+                            const image_fetcher::RequestMetadata& metadata)>;
+
 // This service is responsible for registering and managing promise apps,
 // including retrieving any data required to populate a promise app object.
 // These promise apps will result in a "promise icon" that the user sees in the
@@ -35,6 +57,8 @@
 
   apps::PromiseAppRegistryCache* PromiseAppRegistryCache();
 
+  apps::PromiseAppIconCache* PromiseAppIconCache();
+
   // Adds or updates a promise app in the Promise App Registry Cache with the
   // fields provided in `delta`. For new promise app registrations, we send a
   // request to the Almanac API to retrieve additional promise app info.
@@ -44,12 +68,23 @@
   // care about Almanac responses.
   void SetSkipAlmanacForTesting(bool skip_almanac);
 
+  // Allows us to set a fake image fetcher for mock responses in unit tests.
+  void SetImageFetcherForTesting(
+      std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher);
+
  private:
   // Update a promise app's fields with the info retrieved from the Almanac API.
   void OnGetPromiseAppInfoCompleted(
       const PackageId& package_id,
       absl::optional<PromiseAppWrapper> promise_app_info);
 
+  // Adds an icon to the icon cache and marks the corresponding promise app
+  // as ready to show after all the icons are downloaded.
+  void OnIconDownloaded(const PackageId& package_id,
+                        PromiseAppIconPtr promise_app_icon,
+                        const gfx::Image& image,
+                        const image_fetcher::RequestMetadata& metadata);
+
   // The cache that contains all the promise apps in the system.
   std::unique_ptr<apps::PromiseAppRegistryCache> promise_app_registry_cache_;
 
@@ -57,8 +92,21 @@
   // packages being installed.
   std::unique_ptr<PromiseAppAlmanacConnector> promise_app_almanac_connector_;
 
+  // Cache that contains all promise app icons.
+  std::unique_ptr<apps::PromiseAppIconCache> promise_app_icon_cache_;
+
+  // Fetches images from a given URL.
+  std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_;
+
+  // Keeps track of how many icon downloads we are waiting on for each promise
+  // app. When all downloads are completed, we can proceed to set (or not set)
+  // the promise app as ready to show to the user.
+  std::map<PackageId, int> pending_download_count_;
+
   bool skip_almanac_for_testing_ = false;
 
+  SEQUENCE_CHECKER(sequence_checker_);
+
   base::WeakPtrFactory<PromiseAppService> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc
index 179457b..31fbe01 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc
@@ -8,11 +8,15 @@
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
+#include "chrome/browser/apps/app_service/promise_apps/promise_app_update.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h"
 #include "chrome/browser/apps/app_service/promise_apps/proto/promise_app.pb.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
+#include "components/image_fetcher/core/fake_image_decoder.h"
+#include "components/image_fetcher/core/image_fetcher.h"
+#include "components/image_fetcher/core/image_fetcher_impl.h"
 #include "content/public/test/browser_task_environment.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
@@ -23,7 +27,8 @@
 
 const PackageId kTestPackageId(AppType::kArc, "test.package.name");
 
-class PromiseAppServiceTest : public testing::Test {
+class PromiseAppServiceTest : public testing::Test,
+                              public PromiseAppRegistryCache::Observer {
  public:
   void SetUp() override {
     url_loader_factory_ = std::make_unique<network::TestURLLoaderFactory>();
@@ -37,8 +42,16 @@
         base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
             url_loader_factory_.get());
     service_ = std::make_unique<PromiseAppService>(profile_.get());
+    std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher =
+        std::make_unique<image_fetcher::ImageFetcherImpl>(
+            std::make_unique<image_fetcher::FakeImageDecoder>(),
+            profile_->GetURLLoaderFactory());
+    service_->SetImageFetcherForTesting(std::move(image_fetcher));
+    Observe(cache());
   }
 
+  ~PromiseAppServiceTest() override { Observe(nullptr); }
+
   network::TestURLLoaderFactory* url_loader_factory() {
     return url_loader_factory_.get();
   }
@@ -47,17 +60,42 @@
     return service_->PromiseAppRegistryCache();
   }
 
+  PromiseAppIconCache* icon_cache() { return service_->PromiseAppIconCache(); }
+
   PromiseAppService* service() { return service_.get(); }
 
-  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
+  void WaitForPromiseAppUpdates(int num_updates) {
+    expected_num_updates_ = num_updates;
+    current_num_updates_ = 0;
+    wait_run_loop_ = std::make_unique<base::RunLoop>();
+    wait_run_loop_->Run();
+  }
+
+  // apps::PromiseAppRegistryCache::Observer:
+  void OnPromiseAppUpdate(const PromiseAppUpdate& update) override {
+    current_num_updates_++;
+    if (wait_run_loop_ && wait_run_loop_->running() &&
+        expected_num_updates_ == current_num_updates_) {
+      wait_run_loop_->Quit();
+    }
+  }
+
+  void OnPromiseAppRegistryCacheWillBeDestroyed(
+      apps::PromiseAppRegistryCache* cache) override {}
 
  private:
   content::BrowserTaskEnvironment task_environment_;
+  std::unique_ptr<base::RunLoop> wait_run_loop_;
   std::unique_ptr<PromiseAppService> service_;
   std::unique_ptr<Profile> profile_;
   std::unique_ptr<network::TestURLLoaderFactory> url_loader_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
   ash::system::ScopedFakeStatisticsProvider fake_statistics_provider_;
+
+  // Tracks how many times we should expect OnPromiseAppUpdate to be called
+  // before proceeding with a unit test.
+  int expected_num_updates_;
+  int current_num_updates_;
 };
 
 TEST_F(PromiseAppServiceTest, OnPromiseApp_AlmanacResponseUpdatesPromiseApp) {
@@ -77,17 +115,97 @@
   // Add promise app to cache and trigger Almanac API call.
   service()->OnPromiseApp(std::make_unique<PromiseApp>(kTestPackageId));
 
-  // TODO(b/261907233): Replace with wait for PromiseAppRegistryCache observer
-  // update.
-  RunUntilIdle();
+  // Wait for the registry cache update that follows the Almanac API response.
+  WaitForPromiseAppUpdates(/*num_updates=*/1);
 
   const PromiseApp* promise_app_result =
       cache()->GetPromiseAppForTesting(kTestPackageId);
   EXPECT_TRUE(promise_app_result->name.has_value());
   EXPECT_EQ(promise_app_result->name.value(), "Name");
-  EXPECT_TRUE(promise_app_result->should_show);
-
-  // TODO(b/261910028): Add testcases for promise_app_result icons;
 }
 
+// Tests that icons can be successfully downloaded from the URLs provided by an
+// Almanac response.
+TEST_F(PromiseAppServiceTest, OnPromiseApp_IconsDownloaded) {
+  std::string url = "http://image.test/test.png";
+  std::string url_other = "http://image.test/second-test.png";
+
+  proto::PromiseAppResponse response;
+  response.set_package_id(kTestPackageId.ToString());
+  response.set_name("Name");
+  response.add_icons();
+  response.mutable_icons(0)->set_url(url);
+  response.mutable_icons(0)->set_width_in_pixels(512);
+  response.mutable_icons(0)->set_mime_type("image/png");
+  response.mutable_icons(0)->set_is_masking_allowed(true);
+  response.add_icons();
+  response.mutable_icons(1)->set_url(url_other);
+  response.mutable_icons(1)->set_width_in_pixels(1024);
+  response.mutable_icons(1)->set_mime_type("image/png");
+  response.mutable_icons(1)->set_is_masking_allowed(false);
+
+  // Set up response for Almanac endpoint.
+  url_loader_factory()->AddResponse(
+      PromiseAppAlmanacConnector::GetServerUrl().spec(),
+      response.SerializeAsString());
+
+  // Set up responses for image fetcher.
+  url_loader_factory()->AddResponse(url, "data");
+  url_loader_factory()->AddResponse(url_other, "data");
+
+  // Confirm there aren't any icons for the package yet.
+  EXPECT_FALSE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
+
+  // Add promise app to cache and trigger Almanac API and image fetcher calls.
+  service()->OnPromiseApp(std::make_unique<PromiseApp>(kTestPackageId));
+
+  // Wait for the separate registry cache updates that follow the Almanac API
+  // response and image fetcher completion.
+  WaitForPromiseAppUpdates(/*num_updates=*/2);
+
+  // Verify that there are 2 icons now saved in cache.
+  EXPECT_TRUE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
+  std::vector<PromiseAppIcon*> icons =
+      icon_cache()->GetIconsForTesting(kTestPackageId);
+  EXPECT_EQ(icons.size(), 2u);
+  EXPECT_TRUE(icons[0]->is_masking_allowed);
+  EXPECT_EQ(icons[0]->width_in_pixels, 512);
+  EXPECT_FALSE(icons[1]->is_masking_allowed);
+  EXPECT_EQ(icons[1]->width_in_pixels, 1024);
+
+  // Verify that the promise app is allowed to be visible now.
+  const PromiseApp* promise_app_result =
+      cache()->GetPromiseAppForTesting(kTestPackageId);
+  EXPECT_TRUE(promise_app_result->should_show);
+}
+
+// Tests that we can deal with broken URLs/ failed icon downloads and avoid
+// updating the icon cache.
+TEST_F(PromiseAppServiceTest, OnPromiseApp_FailedIconDownload) {
+  proto::PromiseAppResponse response;
+  response.set_package_id(kTestPackageId.ToString());
+  response.set_name("Name");
+  response.add_icons();
+  response.mutable_icons(0)->set_url("broken-url");
+  response.mutable_icons(0)->set_width_in_pixels(512);
+  response.mutable_icons(0)->set_mime_type("image/png");
+  response.mutable_icons(0)->set_is_masking_allowed(true);
+
+  // Set up response for Almanac endpoint.
+  url_loader_factory()->AddResponse(
+      PromiseAppAlmanacConnector::GetServerUrl().spec(),
+      response.SerializeAsString());
+
+  // Confirm there aren't any icons for the package yet.
+  EXPECT_FALSE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
+
+  // Add promise app to cache and trigger Almanac API call.
+  service()->OnPromiseApp(std::make_unique<PromiseApp>(kTestPackageId));
+
+  // Wait for the registry cache update that follows the Almanac API response.
+  WaitForPromiseAppUpdates(/*num_updates=*/1);
+
+  // Icon cache should still be empty.
+  EXPECT_FALSE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
+}
 }  // namespace apps
diff --git a/chrome/browser/ash/app_list/search/search_metrics_util.cc b/chrome/browser/ash/app_list/search/search_metrics_util.cc
index 5b3fca1..2693a07cf 100644
--- a/chrome/browser/ash/app_list/search/search_metrics_util.cc
+++ b/chrome/browser/ash/app_list/search/search_metrics_util.cc
@@ -36,6 +36,7 @@
     case ash::AppListShowSource::kTabletMode:
     case ash::AppListShowSource::kAssistantEntryPoint:
     case ash::AppListShowSource::kBrowser:
+    case ash::AppListShowSource::kWelcomeTour:
       return "Others";
   }
 }
diff --git a/chrome/browser/ash/app_mode/kiosk_pixel_browsertest.cc b/chrome/browser/ash/app_mode/kiosk_pixel_browsertest.cc
index a323ead..a2d0089f 100644
--- a/chrome/browser/ash/app_mode/kiosk_pixel_browsertest.cc
+++ b/chrome/browser/ash/app_mode/kiosk_pixel_browsertest.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/test/event_generator.h"
@@ -24,7 +25,7 @@
 
 bool IsPixelTestEnabled() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
-      "browser-ui-tests-verify-pixels");
+      switches::kVerifyPixels);
 }
 
 // Helper class to wait until contents finish loading, either on failure or
diff --git a/chrome/browser/ash/arc/idle_manager/arc_idle_manager.cc b/chrome/browser/ash/arc/idle_manager/arc_idle_manager.cc
index 320c0cff..200ab5e5 100644
--- a/chrome/browser/ash/arc/idle_manager/arc_idle_manager.cc
+++ b/chrome/browser/ash/arc/idle_manager/arc_idle_manager.cc
@@ -94,7 +94,7 @@
 
   auto* const power_bridge = ArcPowerBridge::GetForBrowserContext(context);
 
-  // This may be null in unit tests.
+  // This maybe null in unit tests.
   if (power_bridge)
     power_bridge->DisableAndroidIdleControl();
 
@@ -129,7 +129,7 @@
   is_connected_ = true;
 
   // Always reset the timer on connect.
-  LogScreenOffTimer(true);
+  LogScreenOffTimer(/*toggle_timer*/ true);
   // Next call to LogScreenOffTimer from ThrottleInstance will either:
   //   a) throttle=true: reset the timer again - and that's fine.
   //   b) throttle=false: log time between connect and un-throttle.
@@ -141,27 +141,27 @@
     return;
   StopObservers();
   if (should_throttle()) {
-    // May be a logout, or a systemserver crash.
+    // Maybe a logout, or a systemserver crash.
     // Either way, we stop tracking and log.
-    LogScreenOffTimer(false);
+    LogScreenOffTimer(/*toggle_timer*/ false);
   }
   is_connected_ = false;
 }
 
 void ArcIdleManager::ThrottleInstance(bool should_throttle) {
   // Note: this never happens in between StopObservers() - StartObservers();
-  LogScreenOffTimer(should_throttle);
+  LogScreenOffTimer(/*toggle_timer*/ should_throttle);
   delegate_->SetInteractiveMode(bridge_, !should_throttle);
 }
 
-void ArcIdleManager::LogScreenOffTimer(bool should_throttle) {
-  if (should_throttle) {
+void ArcIdleManager::LogScreenOffTimer(bool toggle_timer) {
+  if (toggle_timer) {
     // Start measuring now.
-    interactive_off_span_ = base::ElapsedTimer();
+    interactive_off_span_timer_ = base::ElapsedTimer();
   } else {
-    base::TimeDelta elapsed = interactive_off_span_.Elapsed();
+    base::TimeDelta elapsed = interactive_off_span_timer_.Elapsed();
     // Report time spent with screen-off, in milliseconds. Use 100 buckets,
-    // as the span of allowed values is very wide (0ms -> 8h(28,800,000ms)).
+    // as the span of allowed values is very wide (1ms -> 8h(28,800,000ms)).
     // Notice that the very first call to this function may hit this case,
     // which will cause us to log the time between start-up and the
     // transition to no-throttle (first-active), which is an appropriate
@@ -169,7 +169,7 @@
     base::UmaHistogramCustomTimes("Arc.IdleManager.ScreenOffTime",
                                   /*sample=*/elapsed,
                                   /*min=*/base::Milliseconds(1),
-                                  /*max=*/base::Hours(8), /*#buckets=*/100);
+                                  /*max=*/base::Hours(8), /*buckets=*/100);
   }
 }
 
diff --git a/chrome/browser/ash/arc/idle_manager/arc_idle_manager.h b/chrome/browser/ash/arc/idle_manager/arc_idle_manager.h
index ab7f44b..ada2f470 100644
--- a/chrome/browser/ash/arc/idle_manager/arc_idle_manager.h
+++ b/chrome/browser/ash/arc/idle_manager/arc_idle_manager.h
@@ -78,12 +78,12 @@
   bool is_connected_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
   SEQUENCE_CHECKER(sequence_checker_);
 
-  void LogScreenOffTimer(bool should_throttle);
+  void LogScreenOffTimer(bool toggle_timer);
 
   // Owned by ArcServiceManager.
   const raw_ptr<ArcBridgeService, ExperimentalAsh> bridge_;
 
-  base::ElapsedTimer interactive_off_span_;
+  base::ElapsedTimer interactive_off_span_timer_;
 };
 
 }  // namespace arc
diff --git a/chrome/browser/ash/arc/idle_manager/arc_idle_manager_unittest.cc b/chrome/browser/ash/arc/idle_manager/arc_idle_manager_unittest.cc
index cc9c101..c73707a 100644
--- a/chrome/browser/ash/arc/idle_manager/arc_idle_manager_unittest.cc
+++ b/chrome/browser/ash/arc/idle_manager/arc_idle_manager_unittest.cc
@@ -252,7 +252,7 @@
 
 // Tests that ArcIdleManager records the screen off time metric correctly.
 TEST_F(ArcIdleManagerTest, TestScreenOffTimerMetrics) {
-  // When no one blocks, it should enable idle (screen off);
+  // When no one blocks, it should enable idle (screen off).
 
   on_battery_observer()->SetActive(false);
   display_power_observer()->SetActive(false);
@@ -277,7 +277,7 @@
       "Arc.IdleManager.ScreenOffTime",
       base::ScopedMockElapsedTimersForTest::kMockElapsedTime, 1);
 
-  // Fake a disconnection (aking to crash of SystemServer)
+  // Fake a disconnection (akin to a crash of SystemServer)
   arc_idle_manager()->OnConnectionClosed();
   // we are NOT throttled, shouldn't see any change
 
@@ -285,17 +285,17 @@
       "Arc.IdleManager.ScreenOffTime",
       base::ScopedMockElapsedTimersForTest::kMockElapsedTime, 1);
 
-  // Sate change while we are not watching.
+  // State change while we are not watching.
   on_battery_observer()->SetActive(false);
 
-  // Fake system server coming back
+  // Fake systemserver coming back
   arc_idle_manager()->OnConnectionReady();
 
   histogram_tester.ExpectUniqueTimeSample(
       "Arc.IdleManager.ScreenOffTime",
       base::ScopedMockElapsedTimersForTest::kMockElapsedTime, 1);
 
-  // Again, fake a disconnection (aking to crash of SystemServer)
+  // Again, fake a disconnection (akin to a crash of SystemServer)
   arc_idle_manager()->OnConnectionClosed();
 
   // This time, we should see a counter bump, as disconnection happened
diff --git a/chrome/browser/ash/arc/session/arc_service_launcher.cc b/chrome/browser/ash/arc/session/arc_service_launcher.cc
index 386d9104..732e70f 100644
--- a/chrome/browser/ash/arc/session/arc_service_launcher.cc
+++ b/chrome/browser/ash/arc/session/arc_service_launcher.cc
@@ -12,6 +12,7 @@
 #include "ash/components/arc/arc_util.h"
 #include "ash/components/arc/audio/arc_audio_bridge.h"
 #include "ash/components/arc/camera/arc_camera_bridge.h"
+#include "ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.h"
 #include "ash/components/arc/clipboard/arc_clipboard_bridge.h"
 #include "ash/components/arc/compat_mode/arc_resize_lock_manager.h"
 #include "ash/components/arc/crash_collector/arc_crash_collector_bridge.h"
@@ -316,6 +317,7 @@
   ash::ApkWebAppService::Get(profile);
   ash::app_restore::AppRestoreArcTaskHandler::GetForProfile(profile);
   ArcInitialOptInNotifier::GetForProfile(profile);
+  ArcChromeFeatureFlagsBridge::GetForBrowserContext(profile);
 
   if (arc::IsArcVmEnabled()) {
     // ARCVM-only services.
@@ -486,6 +488,7 @@
   CertStoreService::EnsureFactoryBuilt();
   GpuArcVideoKeyedService::EnsureFactoryBuilt();
   input_overlay::ArcInputOverlayManager::EnsureFactoryBuilt();
+  ArcChromeFeatureFlagsBridge::EnsureFactoryBuilt();
 }
 
 }  // namespace arc
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
index 6c8e695b..244ec95 100644
--- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc
+++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -1400,13 +1400,11 @@
   dark_resume_controller_ = std::make_unique<system::DarkResumeController>(
       std::move(wake_lock_provider));
 
-  if (features::IsLogControllerForDiagnosticsAppEnabled()) {
-    // DiagnosticsBrowserDelegate has to be initialized after ProfilerHelper and
-    // UserManager. Initializing in PostProfileInit to ensure Profile data is
-    // available and shell has been initialized.
-    diagnostics::DiagnosticsLogController::Initialize(
-        std::make_unique<diagnostics::DiagnosticsBrowserDelegateImpl>());
-  }
+  // DiagnosticsBrowserDelegate has to be initialized after ProfilerHelper and
+  // UserManager. Initializing in PostProfileInit to ensure Profile data is
+  // available and shell has been initialized.
+  diagnostics::DiagnosticsLogController::Initialize(
+      std::make_unique<diagnostics::DiagnosticsBrowserDelegateImpl>());
 
   // Start background collection of memory pressure data for Chrome OS.
   memory_pressure_detail_ = base::MakeRefCounted<MemoryMetrics>(
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc
index eaabe1d..a8f5296 100644
--- a/chrome/browser/ash/crosapi/browser_util.cc
+++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -137,6 +137,28 @@
   return LacrosAvailability::kUserChoice;
 }
 
+// Returns appropriate LacrosAvailability.
+LacrosAvailability GetLacrosAvailability(const user_manager::User* user,
+                                         PolicyInitState policy_init_state) {
+  switch (policy_init_state) {
+    case PolicyInitState::kBeforeInit:
+      // If the value is needed before policy initialization, actually,
+      // this should be the case where ash process was restarted, and so
+      // the calculated value in the previous session should be carried
+      // via command line flag.
+      // See also LacrosAvailabilityPolicyObserver how it will be propergated.
+      return ash::standalone_browser::
+          DetermineLacrosAvailabilityFromPolicyValue(
+              user, base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+                        kLacrosAvailabilityPolicySwitch));
+
+    case PolicyInitState::kAfterInit:
+      // If policy initialization is done, the calculated value should be
+      // cached.
+      return GetCachedLacrosAvailability();
+  }
+}
+
 // Gets called from IsLacrosAllowedToBeEnabled with primary user or from
 // IsLacrosEnabledForMigration with the user that the
 // IsLacrosEnabledForMigration was passed.
@@ -391,19 +413,8 @@
     return true;
   }
 
-  LacrosAvailability lacros_availability;
-  if (policy_init_state == PolicyInitState::kBeforeInit) {
-    // Before Policy is initialized, the value won't be available.
-    // So, we'll use the value preserved in the feature flags.
-    // See also LacrosAvailabilityPolicyObserver how it will be propergated.
-    lacros_availability =
-        ash::standalone_browser::DetermineLacrosAvailabilityFromPolicyValue(
-            user, base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-                      kLacrosAvailabilityPolicySwitch));
-  } else {
-    DCHECK_EQ(policy_init_state, PolicyInitState::kAfterInit);
-    lacros_availability = GetCachedLacrosAvailability();
-  }
+  LacrosAvailability lacros_availability =
+      GetLacrosAvailability(user, policy_init_state);
 
   if (!IsLacrosAllowedToBeEnabledWithUser(user, lacros_availability))
     return false;
@@ -500,19 +511,8 @@
   if (!IsLacrosPrimaryBrowserForMigration(user, policy_init_state))
     return true;
 
-  LacrosAvailability lacros_availability;
-  if (policy_init_state == PolicyInitState::kBeforeInit) {
-    // Before Policy is initialized, the value won't be available.
-    // So, we'll use the value preserved in the feature flags.
-    // See also LacrosAvailabilityPolicyObserver how it will be propergated.
-    lacros_availability =
-        ash::standalone_browser::DetermineLacrosAvailabilityFromPolicyValue(
-            user, base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-                      kLacrosAvailabilityPolicySwitch));
-  } else {
-    DCHECK_EQ(policy_init_state, PolicyInitState::kAfterInit);
-    lacros_availability = GetCachedLacrosAvailability();
-  }
+  LacrosAvailability lacros_availability =
+      GetLacrosAvailability(user, policy_init_state);
 
   switch (lacros_availability) {
     case LacrosAvailability::kUserChoice:
@@ -589,19 +589,8 @@
     return true;
   }
 
-  LacrosAvailability lacros_availability;
-  if (policy_init_state == PolicyInitState::kBeforeInit) {
-    // Before Policy is initialized, the value won't be available.
-    // So, we'll use the value preserved in the feature flags.
-    // See also LacrosAvailabilityPolicyObserver how it will be propergated.
-    lacros_availability =
-        ash::standalone_browser::DetermineLacrosAvailabilityFromPolicyValue(
-            user, base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-                      kLacrosAvailabilityPolicySwitch));
-  } else {
-    DCHECK_EQ(policy_init_state, PolicyInitState::kAfterInit);
-    lacros_availability = GetCachedLacrosAvailability();
-  }
+  LacrosAvailability lacros_availability =
+      GetLacrosAvailability(user, policy_init_state);
 
   if (!IsLacrosPrimaryBrowserAllowedForMigration(user, lacros_availability))
     return false;
diff --git a/chrome/browser/ash/exo/chrome_data_exchange_delegate.cc b/chrome/browser/ash/exo/chrome_data_exchange_delegate.cc
index f92464c..058dfba 100644
--- a/chrome/browser/ash/exo/chrome_data_exchange_delegate.cc
+++ b/chrome/browser/ash/exo/chrome_data_exchange_delegate.cc
@@ -313,13 +313,6 @@
   std::move(callback).Run(std::move(file_urls));
 }
 
-base::FilePath SubstituteFuseboxFilePath(const storage::FileSystemURL& url) {
-  if (fusebox::Server* server = fusebox::Server::GetInstance()) {
-    return server->InverseResolveFSURL(url);
-  }
-  return base::FilePath();
-}
-
 }  // namespace
 
 std::vector<base::FilePath> TranslateVMPathsToHost(
@@ -422,10 +415,11 @@
 
   std::vector<FileInfo> list;
   for (auto& url : file_system_urls) {
-    if (!file_manager::util::IsNonNativeFileSystemType(url.type())) {
+    if (url.TypeImpliesPathIsReal()) {
       base::FilePath path = url.path();
       list.emplace_back(std::move(path), std::move(url));
-    } else if (base::FilePath path = SubstituteFuseboxFilePath(url);
+    } else if (base::FilePath path =
+                   fusebox::Server::SubstituteFuseboxFilePath(url);
                !path.empty()) {
       list.emplace_back(std::move(path), std::move(url));
     }
@@ -467,9 +461,10 @@
     if (!url.is_valid()) {
       LOG(WARNING) << "Invalid clipboard FileSystemURL: " << line;
       continue;
-    } else if (!file_manager::util::IsNonNativeFileSystemType(url.type())) {
+    } else if (url.TypeImpliesPathIsReal()) {
       file_info.emplace_back(std::move(url.path()), base::FilePath());
-    } else if (base::FilePath path = SubstituteFuseboxFilePath(url);
+    } else if (base::FilePath path =
+                   fusebox::Server::SubstituteFuseboxFilePath(url);
                !path.empty()) {
       file_info.emplace_back(std::move(path), base::FilePath());
     }
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
index 651b1cc..1253bfa 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
@@ -19,6 +19,7 @@
 #include "ash/components/arc/session/arc_service_manager.h"
 #include "ash/components/arc/system_ui/arc_system_ui_bridge.h"
 #include "ash/constants/app_types.h"
+#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
 #include "ash/public/cpp/accelerators.h"
@@ -168,6 +169,7 @@
 #include "chromeos/ash/services/assistant/public/cpp/assistant_prefs.h"
 #include "chromeos/ash/services/assistant/public/cpp/assistant_service.h"
 #include "chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/printing/printer_configuration.h"
 #include "chromeos/services/machine_learning/public/cpp/service_connection.h"
 #include "chromeos/ui/base/window_properties.h"
@@ -256,6 +258,14 @@
 
 using chromeos::PrinterClass;
 
+// Features used for testing `isFeatureEnabled`.
+BASE_FEATURE(kEnabledFeatureForTest,
+             "EnabledFeatureForTest",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+BASE_FEATURE(kDisabledFeatureForTest,
+             "DisabledFeatureForTest",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 constexpr char kCrostiniNotAvailableForCurrentUserError[] =
     "Crostini is not available for the current user";
 
@@ -6663,6 +6673,47 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// AutotestPrivateIsFeatureEnabledFunction
+//////////////////////////////////////////////////////////////////////////////
+
+AutotestPrivateIsFeatureEnabledFunction::
+    AutotestPrivateIsFeatureEnabledFunction() = default;
+
+AutotestPrivateIsFeatureEnabledFunction::
+    ~AutotestPrivateIsFeatureEnabledFunction() = default;
+
+ExtensionFunction::ResponseAction
+AutotestPrivateIsFeatureEnabledFunction::Run() {
+  absl::optional<api::autotest_private::IsFeatureEnabled::Params> params =
+      api::autotest_private::IsFeatureEnabled::Params::Create(args());
+  EXTENSION_FUNCTION_VALIDATE(params);
+
+  // base::FeatureList does not allow lookup by string name. Use an allowlist
+  // of features instead.
+  static const base::Feature* const kAllowList[] = {
+      // clang-format off
+      &ash::features::kPrivacyIndicators,
+      &ash::features::kQsRevamp,
+      &ash::features::kVideoConference,
+      &chromeos::features::kJelly,
+      &kDisabledFeatureForTest,
+      &kEnabledFeatureForTest,
+      // clang-format on
+  };
+  auto* const* it = base::ranges::find(kAllowList, params->feature_name,
+                                       &base::Feature::name);
+  if (it == std::end(kAllowList)) {
+    std::string error = base::StrCat(
+        {"feature ", params->feature_name,
+         " is not on allowlist, see "
+         "AutotestPrivateIsFeatureEnabledFunction::Run() to update the list"});
+    return RespondNow(Error(error));
+  }
+  bool enabled = base::FeatureList::IsEnabled(**it);
+  return RespondNow(WithArguments(enabled));
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // AutotestPrivateAPI
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
index fe30ba6..f618aac 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
@@ -1794,6 +1794,17 @@
   void OnRemoveVm(bool success);
 };
 
+class AutotestPrivateIsFeatureEnabledFunction : public ExtensionFunction {
+ public:
+  AutotestPrivateIsFeatureEnabledFunction();
+  DECLARE_EXTENSION_FUNCTION("autotestPrivate.isFeatureEnabled",
+                             AUTOTESTPRIVATE_ISFEATUREENABLED)
+
+ private:
+  ~AutotestPrivateIsFeatureEnabledFunction() override;
+  ResponseAction Run() override;
+};
+
 template <>
 KeyedService*
 BrowserContextKeyedAPIFactory<AutotestPrivateAPI>::BuildServiceInstanceFor(
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc
index 56adb57..406c1dd 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc
@@ -241,6 +241,10 @@
   ASSERT_TRUE(RunAutotestPrivateExtensionTest("shelf")) << message_;
 }
 
+IN_PROC_BROWSER_TEST_F(AutotestPrivateApiTest, IsFeatureEnabled) {
+  ASSERT_TRUE(RunAutotestPrivateExtensionTest("isFeatureEnabled")) << message_;
+}
+
 class AutotestPrivateHoldingSpaceApiTest
     : public AutotestPrivateApiTest,
       public ::testing::WithParamInterface<bool /* mark_time_of_first_add */> {
diff --git a/chrome/browser/ash/extensions/file_manager/system_notification_manager.cc b/chrome/browser/ash/extensions/file_manager/system_notification_manager.cc
index b2c2281..3922f4b 100644
--- a/chrome/browser/ash/extensions/file_manager/system_notification_manager.cc
+++ b/chrome/browser/ash/extensions/file_manager/system_notification_manager.cc
@@ -512,10 +512,9 @@
     absl::optional<int> button_index) {
   if (button_index.has_value()) {
     VLOG(1) << "Click on button #" << *button_index;
-    if (*button_index == 1) {
-      chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
-          profile_, chromeos::settings::mojom::kGoogleDriveSubpagePath);
-    }
+    DCHECK_EQ(*button_index, 0);
+    chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
+        profile_, chromeos::settings::mojom::kGoogleDriveSubpagePath);
   } else {
     VLOG(1) << "Click on notification";
   }
@@ -558,14 +557,9 @@
           &SystemNotificationManager::HandleBulkPinningNotificationClick,
           weak_ptr_factory_.GetWeakPtr())));
 
-  // Add buttons to the notification.
-  std::vector<ButtonInfo> buttons;
-  buttons.reserve(2);
-  ButtonInfo& dismiss_button =
-      buttons.emplace_back(GetStringUTF16(IDS_FILE_BROWSER_DISMISS_LABEL));
-  dismiss_button.type = message_center::ButtonType::DISMISS;
-  buttons.emplace_back(GetStringUTF16(IDS_FILE_BROWSER_SETTINGS_LABEL));
-  notification->set_buttons(std::move(buttons));
+  // Add button to the notification.
+  notification->set_buttons(
+      {ButtonInfo(GetStringUTF16(IDS_FILE_BROWSER_SETTINGS_LABEL))});
 
   return notification;
 }
diff --git a/chrome/browser/ash/file_manager/copy_or_move_io_task_impl.cc b/chrome/browser/ash/file_manager/copy_or_move_io_task_impl.cc
index d915008b..6d8f8fa 100644
--- a/chrome/browser/ash/file_manager/copy_or_move_io_task_impl.cc
+++ b/chrome/browser/ash/file_manager/copy_or_move_io_task_impl.cc
@@ -346,8 +346,7 @@
   // Got file size for all files at this point!
   speedometer_.SetTotalBytes(progress_->total_bytes);
 
-  if (util::IsNonNativeFileSystemType(
-          progress_->GetDestinationFolder().type())) {
+  if (!progress_->GetDestinationFolder().TypeImpliesPathIsReal()) {
     // Destination is a virtual filesystem, so skip checking free space.
     GenerateDestinationURL(0);
   } else {
diff --git a/chrome/browser/ash/file_manager/extract_io_task.cc b/chrome/browser/ash/file_manager/extract_io_task.cc
index 3511d54f..bd4189a0 100644
--- a/chrome/browser/ash/file_manager/extract_io_task.cc
+++ b/chrome/browser/ash/file_manager/extract_io_task.cc
@@ -269,7 +269,7 @@
   if (--sizingCount_ == 0) {
     // After getting the size of all the ZIPs, check if we have
     // enough available disk space, and if so, extract them.
-    if (util::IsNonNativeFileSystemType(parent_folder_.type())) {
+    if (!parent_folder_.TypeImpliesPathIsReal()) {
       // Destination is a virtual filesystem, so skip the size check.
       ExtractAllSources();
     } else {
diff --git a/chrome/browser/ash/file_manager/file_manager_string_util.cc b/chrome/browser/ash/file_manager/file_manager_string_util.cc
index a25189f..8f3be58c 100644
--- a/chrome/browser/ash/file_manager/file_manager_string_util.cc
+++ b/chrome/browser/ash/file_manager/file_manager_string_util.cc
@@ -481,10 +481,6 @@
   SET_STRING("DEVICE_UNSUPPORTED_DEFAULT_MESSAGE",
              IDS_DEVICE_UNSUPPORTED_DEFAULT_MESSAGE);
   SET_STRING("DEVICE_UNSUPPORTED_MESSAGE", IDS_DEVICE_UNSUPPORTED_MESSAGE);
-  SET_STRING("DEVICE_WRITE_PROTECTED",
-             IDS_FILE_BROWSER_DROP_TARGET_DEVICE_WRITE_PROTECTED);
-  SET_STRING("DEVICE_ACCESS_RESTRICTED",
-             IDS_FILE_BROWSER_DROP_TARGET_ACCESS_RESTRICTED);
   SET_STRING("DIRECTORY_ALREADY_EXISTS",
              IDS_FILE_BROWSER_DIRECTORY_ALREADY_EXISTS);
   SET_STRING("DISABLED_MOBILE_SYNC_NOTIFICATION_ENABLE_BUTTON",
@@ -501,8 +497,6 @@
              IDS_FILE_BROWSER_DOWNLOADS_DIRECTORY_WARNING_FILESNG);
   SET_STRING("DRAGGING_MULTIPLE_ITEMS",
              IDS_FILE_BROWSER_DRAGGING_MULTIPLE_ITEMS);
-  SET_STRING("DROP_TARGET_FOLDER_NO_MOVE_PERMISSION",
-             IDS_FILE_BROWSER_DROP_TARGET_FOLDER_NO_MOVE_PERMISSION);
   SET_STRING("EMPTY_TRASH_BUTTON_LABEL",
              IDS_FILE_BROWSER_EMPTY_TRASH_BUTTON_LABEL);
   SET_STRING("ERROR_CREATING_FOLDER", IDS_FILE_BROWSER_ERROR_CREATING_FOLDER);
@@ -749,8 +743,6 @@
              IDS_FILE_BROWSER_OPEN_IN_OTHER_DESKTOP_MESSAGE_PLURAL);
   SET_STRING("OPEN_LABEL", IDS_FILE_BROWSER_OPEN_LABEL);
   SET_STRING("OPEN_WITH_BUTTON_LABEL", IDS_FILE_BROWSER_OPEN_WITH_BUTTON_LABEL);
-  SET_STRING("OPENING_LINUX_FILES",
-             IDS_FILE_BROWSER_DROP_TARGET_OPENING_LINUX_FILES);
   SET_STRING("GO_TO_FILE_LOCATION_BUTTON_LABEL",
              IDS_FILE_BROWSER_GO_TO_FILE_LOCATION_BUTTON_LABEL);
   SET_STRING("SEND_FEEDBACK", IDS_FILE_BROWSER_SEND_FEEDBACK_BUTTON_LABEL);
diff --git a/chrome/browser/ash/file_manager/fileapi_util.cc b/chrome/browser/ash/file_manager/fileapi_util.cc
index 85bbc593..e01b211 100644
--- a/chrome/browser/ash/file_manager/fileapi_util.cc
+++ b/chrome/browser/ash/file_manager/fileapi_util.cc
@@ -252,7 +252,7 @@
     return false;
   }
 
-  return IsNonNativeFileSystemType(url.type());
+  return !url.TypeImpliesPathIsReal();
 }
 
 // Helper class to convert SelectedFileInfoList into ChooserFileInfoList.
diff --git a/chrome/browser/ash/file_manager/filesystem_api_util.cc b/chrome/browser/ash/file_manager/filesystem_api_util.cc
index b1bc192c..0ca0e08 100644
--- a/chrome/browser/ash/file_manager/filesystem_api_util.cc
+++ b/chrome/browser/ash/file_manager/filesystem_api_util.cc
@@ -179,54 +179,6 @@
 
 }  // namespace
 
-bool IsNonNativeFileSystemType(storage::FileSystemType type) {
-  switch (type) {
-    // Public enum values, also exposed to JavaScript.
-    case storage::kFileSystemTypeTemporary:
-    case storage::kFileSystemTypePersistent:
-    case storage::kFileSystemTypeIsolated:
-    case storage::kFileSystemTypeExternal:
-      break;
-
-      // Everything else is a private (also known as internal) enum value.
-
-    case storage::kFileSystemInternalTypeEnumStart:
-    case storage::kFileSystemInternalTypeEnumEnd:
-      NOTREACHED();
-      break;
-
-    case storage::kFileSystemTypeLocal:
-    case storage::kFileSystemTypeRestrictedLocal:
-    case storage::kFileSystemTypeLocalMedia:
-    case storage::kFileSystemTypeLocalForPlatformApp:
-    case storage::kFileSystemTypeDriveFs:
-    case storage::kFileSystemTypeSmbFs:
-    case storage::kFileSystemTypeFuseBox:
-      return false;
-
-    case storage::kFileSystemTypeUnknown:
-    case storage::kFileSystemTypeTest:
-    case storage::kFileSystemTypeDragged:
-    case storage::kFileSystemTypeDeviceMedia:
-    case storage::kFileSystemTypeSyncable:
-    case storage::kFileSystemTypeSyncableForInternalSync:
-    case storage::kFileSystemTypeForTransientFile:
-    case storage::kFileSystemTypeProvided:
-    case storage::kFileSystemTypeDeviceMediaAsFileStorage:
-    case storage::kFileSystemTypeArcContent:
-    case storage::kFileSystemTypeArcDocumentsProvider:
-      break;
-
-      // We don't use a "default:" case. Whenever file_system_types.h gains a
-      // new enum value, raise a compiler error (with -Werror,-Wswitch) unless
-      // this switch statement is also updated.
-  }
-
-  // The path indeed corresponds to a mount point not associated with a native
-  // local path.
-  return true;
-}
-
 bool IsUnderNonNativeLocalPath(Profile* profile, const base::FilePath& path) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
@@ -243,7 +195,7 @@
     return false;
   }
 
-  return IsNonNativeFileSystemType(filesystem_url.type());
+  return !filesystem_url.TypeImpliesPathIsReal();
 }
 
 bool IsDriveLocalPath(Profile* profile, const base::FilePath& path) {
diff --git a/chrome/browser/ash/file_manager/filesystem_api_util.h b/chrome/browser/ash/file_manager/filesystem_api_util.h
index e27e25d..9e26e58a 100644
--- a/chrome/browser/ash/file_manager/filesystem_api_util.h
+++ b/chrome/browser/ash/file_manager/filesystem_api_util.h
@@ -25,9 +25,6 @@
 namespace file_manager {
 namespace util {
 
-// Obtains whether |type| is non-native file system or not.
-bool IsNonNativeFileSystemType(storage::FileSystemType type);
-
 // Checks whether the given |path| points to a non-local filesystem that
 // requires special handling.
 bool IsUnderNonNativeLocalPath(Profile* profile, const base::FilePath& path);
diff --git a/chrome/browser/ash/fusebox/fusebox_server.h b/chrome/browser/ash/fusebox/fusebox_server.h
index 58aaa38..7404001 100644
--- a/chrome/browser/ash/fusebox/fusebox_server.h
+++ b/chrome/browser/ash/fusebox/fusebox_server.h
@@ -82,6 +82,14 @@
   // previously registered (subdir, fs_url_prefix) that matched.
   base::FilePath InverseResolveFSURL(const storage::FileSystemURL& fs_url);
 
+  // Chains GetInstance and InverseResolveFSURL, returning an empty
+  // base::FilePath when there is no instance.
+  static base::FilePath SubstituteFuseboxFilePath(
+      const storage::FileSystemURL& fs_url) {
+    Server* server = GetInstance();
+    return server ? server->InverseResolveFSURL(fs_url) : base::FilePath();
+  }
+
   // Returns human-readable debugging information as a JSON value.
   base::Value GetDebugJSON();
 
diff --git a/chrome/browser/ash/login/enable_debugging_browsertest.cc b/chrome/browser/ash/login/enable_debugging_browsertest.cc
index e0726e9..1a9212e 100644
--- a/chrome/browser/ash/login/enable_debugging_browsertest.cc
+++ b/chrome/browser/ash/login/enable_debugging_browsertest.cc
@@ -214,7 +214,7 @@
   void ShowRemoveProtectionScreen() {
     debug_daemon_client_->SetDebuggingFeaturesStatus(
         DebugDaemonClient::DEV_FEATURE_NONE);
-    OobeBaseTest::MaybeWaitForLoginScreenLoad();
+    WaitForOobeUI();
     test::OobeJS().ExpectHidden(kDebuggingScreenId);
     InvokeEnableDebuggingScreen();
     test::OobeJS().ExpectVisiblePath(kRemoveProtectionDialog);
@@ -227,7 +227,7 @@
   void ShowSetupScreen() {
     debug_daemon_client_->SetDebuggingFeaturesStatus(
         debugd::DevFeatureFlag::DEV_FEATURE_ROOTFS_VERIFICATION_REMOVED);
-    OobeBaseTest::MaybeWaitForLoginScreenLoad();
+    WaitForOobeUI();
     test::OobeJS().ExpectHidden(kDebuggingScreenId);
     InvokeEnableDebuggingScreen();
     test::OobeJS().ExpectVisiblePath(kSetupDialog);
@@ -343,7 +343,7 @@
   debug_daemon_client_->SetDebuggingFeaturesStatus(
       debugd::DevFeatureFlag::DEV_FEATURE_SSH_SERVER_CONFIGURED |
       debugd::DevFeatureFlag::DEV_FEATURE_SYSTEM_ROOT_PASSWORD_SET);
-  OobeBaseTest::MaybeWaitForLoginScreenLoad();
+  WaitForOobeUI();
   test::OobeJS().ExpectHidden(kDebuggingScreenId);
   InvokeEnableDebuggingScreen();
   test::OobeJS().ExpectVisiblePath(kRemoveProtectionDialog);
@@ -360,7 +360,7 @@
   debug_daemon_client_->SetServiceIsAvailable(false);
   debug_daemon_client_->SetDebuggingFeaturesStatus(
       DebugDaemonClient::DEV_FEATURE_NONE);
-  OobeBaseTest::MaybeWaitForLoginScreenLoad();
+  WaitForOobeUI();
 
   // Invoking UI and it should land on wait-view.
   test::OobeJS().ExpectHidden(kDebuggingScreenId);
@@ -379,6 +379,7 @@
 
 // Try to show enable debugging dialog, we should see error screen here.
 IN_PROC_BROWSER_TEST_F(EnableDebuggingTest, NoShowInNonDevMode) {
+  WaitForOobeUI();
   test::OobeJS().ExpectHidden(kDebuggingScreenId);
   InvokeEnableDebuggingScreen();
   test::OobeJS().CreateVisibilityWaiter(true, kErrorDialog)->Wait();
diff --git a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
index d84fa14..9154ee14 100644
--- a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
+++ b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
@@ -916,7 +916,7 @@
 IN_PROC_BROWSER_TEST_F(AutoEnrollmentNoStateKeys, FREExplicitlyRequired) {
   SetFRERequiredKey("1");
   host()->StartWizard(AutoEnrollmentCheckScreenView::kScreenId);
-  OobeScreenWaiter(AutoEnrollmentCheckScreenView::kScreenId).Wait();
+  WaitForOobeUI();
 
   OobeScreenWaiter(ErrorScreenView::kScreenId).Wait();
   test::OobeJS().ExpectHiddenPath({"error-message", "error-guest-signin"});
@@ -929,7 +929,7 @@
                        FREExplicitlyRequiredInvalid) {
   SetFRERequiredKey("anything");
   host()->StartWizard(AutoEnrollmentCheckScreenView::kScreenId);
-  OobeScreenWaiter(AutoEnrollmentCheckScreenView::kScreenId).Wait();
+  WaitForOobeUI();
 
   OobeScreenWaiter(ErrorScreenView::kScreenId).Wait();
   test::OobeJS().ExpectHiddenPath({"error-message", "error-guest-signin"});
diff --git a/chrome/browser/ash/login/login_pref_names.cc b/chrome/browser/ash/login/login_pref_names.cc
index a4aa1d32..0fa5bd5 100644
--- a/chrome/browser/ash/login/login_pref_names.cc
+++ b/chrome/browser/ash/login/login_pref_names.cc
@@ -139,6 +139,9 @@
 const char kOobeLocaleChangedOnWelcomeScreen[] =
     "OobeLocaleChangedOnWelcomeScreen";
 
+// A boolean pref indicate if the critical update in OOBE applied.
+const char kOobeCriticalUpdate[] = "OobeCriticalUpdate";
+
 // A string pref containing url parameter name which can be used on SAML IdP web
 // page to autofill the username field.
 const char kUrlParameterToAutofillSAMLUsername[] =
diff --git a/chrome/browser/ash/login/login_pref_names.h b/chrome/browser/ash/login/login_pref_names.h
index e02fbd4..1d3aa934 100644
--- a/chrome/browser/ash/login/login_pref_names.h
+++ b/chrome/browser/ash/login/login_pref_names.h
@@ -13,6 +13,7 @@
 extern const char kOobeOnboardingTime[];
 extern const char kOobeMarketingOptInScreenFinished[];
 extern const char kOobeMarketingOptInChoice[];
+extern const char kOobeCriticalUpdate[];
 // TODO(https://crbug.com/1322394): deprecate this pref once update from
 // CloudReady won't be available anymore.
 extern const char kOobeRevenUpdatedToFlex[];
diff --git a/chrome/browser/ash/login/oobe_localization_browsertest.cc b/chrome/browser/ash/login/oobe_localization_browsertest.cc
index ce19d1c..7367d03 100644
--- a/chrome/browser/ash/login/oobe_localization_browsertest.cc
+++ b/chrome/browser/ash/login/oobe_localization_browsertest.cc
@@ -335,6 +335,7 @@
 }
 
 void OobeLocalizationTest::RunLocalizationTest() {
+  WaitForOobeUI();
   const std::string expected_locale(GetParam()->expected_locale);
   const std::string expected_keyboard_layout(
       GetParam()->expected_keyboard_layout);
diff --git a/chrome/browser/ash/login/oobe_quick_start/BUILD.gn b/chrome/browser/ash/login/oobe_quick_start/BUILD.gn
index e423e98..a01a879 100644
--- a/chrome/browser/ash/login/oobe_quick_start/BUILD.gn
+++ b/chrome/browser/ash/login/oobe_quick_start/BUILD.gn
@@ -34,6 +34,7 @@
     "//google_apis/common:common",
     "//services/data_decoder/public/cpp",
     "//services/network/public/cpp:cpp",
+    "//ui/chromeos",
   ]
   sources = [
     "second_device_auth_broker.cc",
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn b/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
index eb88892..fa19f7b 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
@@ -8,6 +8,7 @@
 
 source_set("connectivity") {
   deps = [
+    "proto",
     "//base",
     "//chrome/browser:browser_process",
     "//chrome/browser/ash/login/oobe_quick_start:oobe_quick_start_pref_names",
@@ -31,6 +32,8 @@
     "fast_pair_advertiser.h",
     "fido_assertion_info.cc",
     "fido_assertion_info.h",
+    "handshake_helpers.cc",
+    "handshake_helpers.h",
     "random_session_id.cc",
     "random_session_id.h",
     "target_device_connection_broker.cc",
@@ -67,6 +70,7 @@
   deps = [
     ":connectivity",
     ":test_support",
+    "proto",
     "//base",
     "//base/test:test_support",
     "//chrome/browser/nearby_sharing/public/cpp",
@@ -83,6 +87,7 @@
   sources = [
     "connection_unittest.cc",
     "fast_pair_advertiser_unittest.cc",
+    "handshake_helpers_unittest.cc",
     "target_device_connection_broker_impl_unittest.cc",
   ]
 }
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc
index c52dda7..5fb0db6 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc
@@ -12,6 +12,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/fido_assertion_info.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h"
 #include "chrome/browser/ash/login/oobe_quick_start/logging/logging.h"
@@ -22,7 +23,6 @@
 #include "chromeos/ash/services/nearby/public/mojom/quick_start_decoder_types.mojom-forward.h"
 #include "chromeos/ash/services/nearby/public/mojom/quick_start_decoder_types.mojom-shared.h"
 #include "chromeos/ash/services/nearby/public/mojom/quick_start_decoder_types.mojom.h"
-#include "crypto/random.h"
 
 namespace ash::quick_start {
 
@@ -41,31 +41,21 @@
     mojo::SharedRemote<mojom::QuickStartDecoder> quick_start_decoder,
     ConnectionClosedCallback on_connection_closed,
     ConnectionAuthenticatedCallback on_connection_authenticated) {
-  auto nonce_generator = std::make_unique<NonceGenerator>();
   return std::make_unique<Connection>(
       nearby_connection, session_context, std::move(quick_start_decoder),
-      std::move(nonce_generator), std::move(on_connection_closed),
-      std::move(on_connection_authenticated));
-}
-
-Connection::Nonce Connection::NonceGenerator::Generate() {
-  Nonce nonce;
-  crypto::RandBytes(nonce);
-  return nonce;
+      std::move(on_connection_closed), std::move(on_connection_authenticated));
 }
 
 Connection::Connection(
     NearbyConnection* nearby_connection,
     Connection::SessionContext session_context,
     mojo::SharedRemote<mojom::QuickStartDecoder> quick_start_decoder,
-    std::unique_ptr<NonceGenerator> nonce_generator,
     ConnectionClosedCallback on_connection_closed,
     ConnectionAuthenticatedCallback on_connection_authenticated)
     : nearby_connection_(nearby_connection),
       random_session_id_(session_context.session_id),
       shared_secret_(session_context.shared_secret),
       secondary_shared_secret_(session_context.secondary_shared_secret),
-      nonce_generator_(std::move(nonce_generator)),
       on_connection_closed_(std::move(on_connection_closed)),
       on_connection_authenticated_(std::move(on_connection_authenticated)),
       decoder_(std::move(quick_start_decoder)) {
@@ -120,24 +110,20 @@
                      weak_ptr_factory_.GetWeakPtr(),
                      &mojom::QuickStartDecoder::DecodeWifiCredentialsResponse,
                      std::move(callback));
-  SendMessage(requests::BuildRequestWifiCredentialsMessage(session_id,
-                                                           shared_secret_str),
-              std::move(on_response_received));
+  SendMessageAndReadResponse(requests::BuildRequestWifiCredentialsMessage(
+                                 session_id, shared_secret_str),
+                             std::move(on_response_received));
 }
 
 void Connection::NotifySourceOfUpdate(int32_t session_id,
                                       NotifySourceOfUpdateCallback callback) {
   // Send message to source that target device will perform an update.
-  // TODO(b/234655072): Cleanup BuildNotifySourceOfUpdateMessage plumbing to
-  // pass in session_id as a base::span<uint8_t,32> and avoid copying twice.
-  std::string shared_secret_str(secondary_shared_secret_.begin(),
-                                secondary_shared_secret_.end());
-
   response_timeout_timer_.Start(FROM_HERE, kNotifySourceOfUpdateResponseTimeout,
                                 base::BindOnce(&Connection::OnResponseTimeout,
                                                weak_ptr_factory_.GetWeakPtr()));
-  SendMessage(
-      requests::BuildNotifySourceOfUpdateMessage(session_id, shared_secret_str),
+  SendMessageAndReadResponse(
+      requests::BuildNotifySourceOfUpdateMessage(session_id,
+                                                 secondary_shared_secret_),
       base::BindOnce(&Connection::OnNotifySourceOfUpdateResponse,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
@@ -151,14 +137,16 @@
 
   auto request_assertion =
       base::IgnoreArgs<absl::optional<std::vector<uint8_t>>>(base::BindOnce(
-          &Connection::SendMessage, weak_ptr_factory_.GetWeakPtr(),
+          &Connection::SendMessageAndReadResponse,
+          weak_ptr_factory_.GetWeakPtr(),
           requests::BuildAssertionRequestMessage(challenge_b64url),
           std::move(parse_assertion_response)));
 
   // Set up a callback to call GetInfo, calling back into RequestAssertion
   // (and ignoring the results of GetInfo) after the call succeeds.
   auto get_info = base::IgnoreArgs<absl::optional<std::vector<uint8_t>>>(
-      base::BindOnce(&Connection::SendMessage, weak_ptr_factory_.GetWeakPtr(),
+      base::BindOnce(&Connection::SendMessageAndReadResponse,
+                     weak_ptr_factory_.GetWeakPtr(),
                      requests::BuildGetInfoRequestMessage(),
                      std::move(request_assertion)));
 
@@ -167,8 +155,8 @@
                      weak_ptr_factory_.GetWeakPtr(), std::move(get_info));
 
   // Call into SetBootstrapOptions, starting the chain of callbacks.
-  SendMessage(requests::BuildBootstrapOptionsRequest(),
-              std::move(bootstrap_configurations_response));
+  SendMessageAndReadResponse(requests::BuildBootstrapOptionsRequest(),
+                             std::move(bootstrap_configurations_response));
 }
 
 void Connection::OnNotifySourceOfUpdateResponse(
@@ -262,19 +250,45 @@
   std::move(callback).Run(absl::nullopt);
 }
 
-void Connection::SendMessage(std::unique_ptr<QuickStartMessage> message,
-                             ConnectionResponseCallback callback) {
-  SendPayload(*message->GenerateEncodedMessage());
+void Connection::SendMessageAndReadResponse(
+    std::unique_ptr<QuickStartMessage> message,
+    ConnectionResponseCallback callback) {
+  std::string json_serialized_payload;
+  CHECK(base::JSONWriter::Write(*message->GenerateEncodedMessage(),
+                                &json_serialized_payload));
+
+  SendBytesAndReadResponse(std::vector<uint8_t>(json_serialized_payload.begin(),
+                                                json_serialized_payload.end()),
+                           std::move(callback));
+}
+
+void Connection::SendBytesAndReadResponse(std::vector<uint8_t>&& bytes,
+                                          ConnectionResponseCallback callback) {
+  nearby_connection_->Write(std::move(bytes));
   nearby_connection_->Read(std::move(callback));
 }
 
 void Connection::InitiateHandshake(const std::string& authentication_token,
                                    HandshakeSuccessCallback callback) {
-  Connection::Nonce nonce = nonce_generator_->Generate();
-  nearby_connection_->Write(requests::BuildTargetDeviceHandshakeMessage(
-      authentication_token, shared_secret_, nonce));
+  SendBytesAndReadResponse(
+      handshake::BuildHandshakeMessage(authentication_token, shared_secret_),
+      base::BindOnce(&Connection::OnHandshakeResponse,
+                     weak_ptr_factory_.GetWeakPtr(), authentication_token,
+                     std::move(callback)));
+}
 
-  // TODO(b/234655072): Read response from phone and run callback.
+void Connection::OnHandshakeResponse(
+    const std::string& authentication_token,
+    HandshakeSuccessCallback callback,
+    absl::optional<std::vector<uint8_t>> response_bytes) {
+  if (!response_bytes) {
+    QS_LOG(ERROR) << "Failed to read handshake response from NearbyConnection";
+    std::move(callback).Run(/*success=*/false);
+    return;
+  }
+  bool success = handshake::VerifyHandshakeMessage(
+      *response_bytes, authentication_token, shared_secret_);
+  std::move(callback).Run(success);
 }
 
 void Connection::WaitForUserVerification(
@@ -353,14 +367,6 @@
       .Run();
 }
 
-void Connection::SendPayload(const base::Value::Dict& message_payload) {
-  std::string json_serialized_payload;
-  CHECK(base::JSONWriter::Write(message_payload, &json_serialized_payload));
-  std::vector<uint8_t> request_payload(json_serialized_payload.begin(),
-                                       json_serialized_payload.end());
-  nearby_connection_->Write(request_payload);
-}
-
 void Connection::OnConnectionClosed(
     TargetDeviceConnectionBroker::ConnectionClosedReason reason) {
   connection_state_ = Connection::State::kClosed;
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h
index a2f2a09..aca73da 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h
@@ -35,7 +35,6 @@
     : public TargetDeviceConnectionBroker::AuthenticatedConnection {
  public:
   using SharedSecret = TargetDeviceConnectionBroker::SharedSecret;
-  using Nonce = std::array<uint8_t, 12>;
   using HandshakeSuccessCallback = base::OnceCallback<void(bool)>;
   using ConnectionAuthenticatedCallback = base::OnceCallback<void(
       base::WeakPtr<TargetDeviceConnectionBroker::AuthenticatedConnection>)>;
@@ -71,20 +70,9 @@
         ConnectionAuthenticatedCallback on_connection_authenticated);
   };
 
-  class NonceGenerator {
-   public:
-    NonceGenerator() = default;
-    NonceGenerator(const NonceGenerator&) = delete;
-    NonceGenerator& operator=(const NonceGenerator&) = delete;
-    virtual ~NonceGenerator() = default;
-
-    virtual Nonce Generate();
-  };
-
   Connection(NearbyConnection* nearby_connection,
              SessionContext session_context,
              mojo::SharedRemote<mojom::QuickStartDecoder> quick_start_decoder,
-             std::unique_ptr<NonceGenerator> nonce_generator,
              ConnectionClosedCallback on_connection_closed,
              ConnectionAuthenticatedCallback on_connection_authenticated);
 
@@ -157,12 +145,14 @@
       BootstrapConfigurationsCallback callback,
       absl::optional<std::vector<uint8_t>> response_bytes);
 
-  void SendMessage(std::unique_ptr<QuickStartMessage> message,
-                   ConnectionResponseCallback callback);
+  void SendMessageAndReadResponse(std::unique_ptr<QuickStartMessage> message,
+                                  ConnectionResponseCallback callback);
+  void SendBytesAndReadResponse(std::vector<uint8_t>&& bytes,
+                                ConnectionResponseCallback callback);
 
-  // Reusable method to serialize a payload into JSON bytes and send via Nearby
-  // Connections.
-  void SendPayload(const base::Value::Dict& message_payload);
+  void OnHandshakeResponse(const std::string& authentication_token,
+                           HandshakeSuccessCallback callback,
+                           absl::optional<std::vector<uint8_t>> response_bytes);
 
   void OnConnectionClosed(
       TargetDeviceConnectionBroker::ConnectionClosedReason reason);
@@ -197,7 +187,6 @@
   SharedSecret shared_secret_;
   SharedSecret secondary_shared_secret_;
   State connection_state_ = State::kOpen;
-  std::unique_ptr<NonceGenerator> nonce_generator_;
   ConnectionClosedCallback on_connection_closed_;
   bool authenticated_ = false;
   ConnectionAuthenticatedCallback on_connection_authenticated_;
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection_unittest.cc
index 3369600..5c4d16c 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection_unittest.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/timer/mock_timer.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/fido_assertion_info.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h"
 #include "chrome/browser/nearby_sharing/fake_nearby_connection.h"
@@ -70,26 +71,13 @@
     0xab, 0xa0, 0xe3, 0xfc, 0xd3, 0x5a, 0x04, 0x01, 0x63, 0xf6, 0xf5,
     0xeb, 0x40, 0x7f, 0x4b, 0xac, 0xe4, 0xd1, 0xbf, 0x20, 0x19};
 
-// 12 random bytes to use as the nonce.
-constexpr std::array<uint8_t, 12> kNonce = {0x60, 0x3e, 0x87, 0x69, 0xa3, 0x55,
-                                            0xd3, 0x49, 0xbd, 0x0a, 0x63, 0xed};
-
-// A serialized auth message produced with |kAuthToken|, |kSharedSecret|, and
-// |kNonce|. Uses the "Target" role.
-constexpr std::array<uint8_t, 50> kTargetDeviceAuthMessage = {
-    0x08, 0x01, 0x12, 0x2e, 0x0a, 0x0c, 0x60, 0x3e, 0x87, 0x69,
-    0xa3, 0x55, 0xd3, 0x49, 0xbd, 0x0a, 0x63, 0xed, 0x12, 0x1e,
-    0x44, 0x28, 0x93, 0x04, 0xd3, 0xc0, 0x03, 0x50, 0xc9, 0x9d,
-    0x4f, 0x8d, 0x01, 0xaa, 0xcf, 0xc6, 0x43, 0x41, 0xa2, 0xcf,
-    0x4a, 0x91, 0x6e, 0x49, 0x14, 0x9d, 0x2e, 0xea, 0x9a, 0xf6};
-
 // 6 random bytes to use as the RandomSessionId.
 constexpr std::array<uint8_t, 6> kRandomSessionId = {0x6b, 0xb3, 0x85,
                                                      0x27, 0xbb, 0x28};
 
-class ConstantNonceGenerator : public Connection::NonceGenerator {
-  Connection::Nonce Generate() override { return kNonce; }
-};
+// 12 random bytes to use as the nonce.
+constexpr std::array<uint8_t, 12> kNonce = {0x60, 0x3e, 0x87, 0x69, 0xa3, 0x55,
+                                            0xd3, 0x49, 0xbd, 0x0a, 0x63, 0xed};
 
 constexpr base::TimeDelta kNotifySourceOfUpdateResponseTimeout =
     base::Seconds(3);
@@ -115,7 +103,6 @@
         nearby_connection, session_context_,
         mojo::SharedRemote<ash::quick_start::mojom::QuickStartDecoder>(
             fake_quick_start_decoder_->GetRemote()),
-        std::make_unique<ConstantNonceGenerator>(),
         /*on_connection_closed=*/base::DoNothing(),
         /*on_connection_authenticated=*/
         base::BindLambdaForTesting(
@@ -429,7 +416,6 @@
           fake_nearby_connection_.get(), session_context_,
           mojo::SharedRemote<ash::quick_start::mojom::QuickStartDecoder>(
               fake_quick_start_decoder_->GetRemote()),
-          std::make_unique<ConstantNonceGenerator>(),
           /*on_connection_closed=*/future.GetCallback(),
           /*on_connection_authenticated=*/base::DoNothing());
 
@@ -453,7 +439,6 @@
           fake_nearby_connection_.get(), session_context_,
           mojo::SharedRemote<ash::quick_start::mojom::QuickStartDecoder>(
               fake_quick_start_decoder_->GetRemote()),
-          std::make_unique<ConstantNonceGenerator>(),
           /*on_connection_closed=*/future.GetCallback(),
           /*on_connection_authenticated=*/base::DoNothing());
 
@@ -470,13 +455,28 @@
 }
 
 TEST_F(ConnectionTest, InitiateHandshake) {
-  connection_->InitiateHandshake(kAuthToken, base::DoNothing());
+  base::test::TestFuture<bool> future;
+  connection_->InitiateHandshake(kAuthToken, future.GetCallback());
+  EXPECT_TRUE(handshake::VerifyHandshakeMessage(
+      fake_nearby_connection_->GetWrittenData(), kAuthToken, kSharedSecret,
+      handshake::DeviceRole::kTarget));
+
+  std::vector<uint8_t> response = handshake::BuildHandshakeMessage(
+      kAuthToken, kSharedSecret, kNonce, handshake::DeviceRole::kSource);
+  fake_nearby_connection_->AppendReadableData(response);
+  EXPECT_TRUE(future.Get());
+}
+
+TEST_F(ConnectionTest, InitiateHandshake_BadResponse) {
+  base::test::TestFuture<bool> future;
+  connection_->InitiateHandshake(kAuthToken, future.GetCallback());
   std::vector<uint8_t> written_payload =
       fake_nearby_connection_->GetWrittenData();
-  ASSERT_EQ(kTargetDeviceAuthMessage.size(), written_payload.size());
-  for (size_t i = 0; i < kTargetDeviceAuthMessage.size(); i++) {
-    EXPECT_EQ(kTargetDeviceAuthMessage[i], written_payload[i]);
-  }
+
+  // Simulate the source device sending back the same message it received from
+  // the target device. Should fail because it uses the wrong role.
+  fake_nearby_connection_->AppendReadableData(written_payload);
+  EXPECT_FALSE(future.Get());
 }
 
 TEST_F(ConnectionTest, TestUserVerificationRequested_ReturnsResult) {
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_connection.cc
index c303829b..15c52f34 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_connection.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_connection.cc
@@ -32,7 +32,6 @@
     : Connection(nearby_connection,
                  session_context,
                  std::move(quick_start_decoder),
-                 std::make_unique<Connection::NonceGenerator>(),
                  std::move(on_connection_closed),
                  std::move(on_connection_authenticated)) {}
 
@@ -78,6 +77,11 @@
   std::move(request_account_transfer_assertion_callback_).Run(assertion_info);
 }
 
+void FakeConnection::HandleHandshakeResult(bool success) {
+  CHECK(handshake_success_callback_);
+  std::move(handshake_success_callback_).Run(success);
+}
+
 bool FakeConnection::WasHandshakeInitiated() {
   return handshake_initiated_;
 }
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_connection.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_connection.h
index 6bb6a1c..1c5e334b 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_connection.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_connection.h
@@ -54,6 +54,7 @@
   void VerifyUser(absl::optional<mojom::UserVerificationResponse> response);
   void SendAccountTransferAssertionInfo(
       absl::optional<FidoAssertionInfo> assertion_info);
+  void HandleHandshakeResult(bool success);
 
  private:
   bool handshake_initiated_ = false;
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc
index 37ce144..b9703c6 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc
@@ -52,12 +52,13 @@
 }
 
 FakeTargetDeviceConnectionBroker::FakeTargetDeviceConnectionBroker() {
+  random_session_id_ = RandomSessionId();
   fake_nearby_connection_ = std::make_unique<FakeNearbyConnection>();
   NearbyConnection* nearby_connection = fake_nearby_connection_.get();
   mojo::PendingRemote<mojom::QuickStartDecoder> remote;
   fake_quick_start_decoder_ = std::make_unique<FakeQuickStartDecoder>();
   Connection::SessionContext session_context = {
-      .session_id = RandomSessionId(),
+      .session_id = random_session_id_,
       .shared_secret = kSharedSecret,
       .secondary_shared_secret = kSecondarySharedSecret};
   connection_ = std::make_unique<FakeConnection>(
@@ -105,9 +106,8 @@
     connection_lifecycle_listener_->OnPinVerificationRequested(
         DerivePin(kAuthenticationToken));
   } else {
-    auto random_session_id = RandomSessionId();
     connection_lifecycle_listener_->OnQRCodeVerificationRequested(
-        GetQrCodeData(random_session_id, kSharedSecret));
+        GetQrCodeData(random_session_id_, kSharedSecret));
   }
 }
 
@@ -125,6 +125,10 @@
   connection_lifecycle_listener_->OnConnectionClosed(reason);
 }
 
+std::string FakeTargetDeviceConnectionBroker::GetSessionIdDisplayCode() {
+  return random_session_id_.GetDisplayCode();
+}
+
 FakeConnection* FakeTargetDeviceConnectionBroker::GetFakeConnection() {
   return connection_.get();
 }
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h
index 17cd62c3..a133e9d 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h
@@ -78,6 +78,8 @@
     MaybeNotifyFeatureStatus();
   }
 
+  std::string GetSessionIdDisplayCode() override;
+
   void set_use_pin_authentication(bool use_pin_authentication) {
     use_pin_authentication_ = use_pin_authentication;
   }
@@ -115,6 +117,8 @@
   std::unique_ptr<FakeQuickStartDecoder> fake_quick_start_decoder_;
   std::unique_ptr<FakeConnection> connection_;
 
+  RandomSessionId random_session_id_;
+
   base::WeakPtrFactory<FakeTargetDeviceConnectionBroker> weak_ptr_factory_{
       this};
 };
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.cc
new file mode 100644
index 0000000..c2c1643
--- /dev/null
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.cc
@@ -0,0 +1,166 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.h"
+
+#include "base/containers/span.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/proto/aes_gcm_authentication_message.pb.h"
+#include "chrome/browser/ash/login/oobe_quick_start/logging/logging.h"
+#include "crypto/aead.h"
+#include "crypto/random.h"
+
+namespace ash::quick_start::handshake {
+
+namespace {
+
+std::vector<uint8_t> EncryptPayload(
+    const proto::V1Message::AuthenticationPayload& payload,
+    base::span<const uint8_t> secret,
+    base::span<const uint8_t> nonce) {
+  std::string payload_bytes;
+  payload.SerializeToString(&payload_bytes);
+
+  crypto::Aead aead(crypto::Aead::AES_256_GCM);
+  aead.Init(secret);
+  return aead.Seal(
+      std::vector<uint8_t>(payload_bytes.begin(), payload_bytes.end()), nonce,
+      /*additional_data=*/base::span<uint8_t>());
+}
+
+absl::optional<std::vector<uint8_t>> DecryptPayload(
+    base::span<const uint8_t> payload,
+    base::span<const uint8_t> secret,
+    base::span<const uint8_t> nonce) {
+  crypto::Aead aead(crypto::Aead::AES_256_GCM);
+  aead.Init(secret);
+  return aead.Open(payload, nonce,
+                   /*additional_data=*/base::span<uint8_t>());
+}
+
+absl::optional<proto::V1Message> ParseAuthMessage(
+    base::span<const uint8_t> auth_message_bytes) {
+  proto::AesGcmAuthenticationMessage auth_message;
+  if (!auth_message.ParseFromString(
+          std::string(auth_message_bytes.begin(), auth_message_bytes.end()))) {
+    QS_LOG(ERROR) << "Failed to parse AesGcmAuthenticationMessage.";
+    return absl::nullopt;
+  }
+  if (!auth_message.has_version() || auth_message.version() != 1 ||
+      !auth_message.has_v1()) {
+    QS_LOG(ERROR) << "AesGcmAuthenticationMessage has unknown version.";
+    return absl::nullopt;
+  }
+  const proto::V1Message& v1_message = auth_message.v1();
+  if (!v1_message.has_nonce()) {
+    QS_LOG(ERROR) << "AesGcmAuthenticationMessage missing nonce.";
+    return absl::nullopt;
+  }
+  if (v1_message.nonce().size() != 12u) {
+    QS_LOG(ERROR) << "Nonce has bad length. Should be 12 bytes.";
+    return absl::nullopt;
+  }
+  if (!v1_message.has_payload()) {
+    QS_LOG(ERROR) << "AesGcmAuthenticationMessage missing payload.";
+    return absl::nullopt;
+  }
+  return v1_message;
+}
+
+absl::optional<proto::V1Message::AuthenticationPayload> ParseAuthPayload(
+    base::span<const uint8_t> bytes) {
+  proto::V1Message::AuthenticationPayload auth_payload;
+  if (!auth_payload.ParseFromString(std::string(bytes.begin(), bytes.end()))) {
+    QS_LOG(ERROR) << "Failed to parse AuthenticationPayload.";
+    return absl::nullopt;
+  }
+  if (!auth_payload.has_role()) {
+    QS_LOG(ERROR) << "AuthenticationPayload missing role.";
+    return absl::nullopt;
+  }
+
+  if (!auth_payload.has_auth_string()) {
+    QS_LOG(ERROR) << "AuthenticationPayload missing auth_string.";
+    return absl::nullopt;
+  }
+  return auth_payload;
+}
+
+}  // namespace
+
+std::vector<uint8_t> BuildHandshakeMessage(
+    const std::string& auth_token,
+    std::array<uint8_t, 32> secret,
+    absl::optional<std::array<uint8_t, 12>> nonce,
+    DeviceRole role) {
+  std::array<uint8_t, 12> nonce_bytes;
+  if (nonce) {
+    nonce_bytes = *nonce;
+  } else {
+    crypto::RandBytes(nonce_bytes);
+  }
+
+  proto::V1Message::AuthenticationPayload auth_payload;
+  auth_payload.set_role(static_cast<int32_t>(role));
+  auth_payload.set_auth_string(auth_token);
+
+  std::vector<uint8_t> encrypted_payload =
+      EncryptPayload(auth_payload, secret, nonce_bytes);
+
+  proto::AesGcmAuthenticationMessage auth_message;
+  auth_message.set_version(proto::AesGcmAuthenticationMessage::V1);
+  proto::V1Message* v1_message = auth_message.mutable_v1();
+  v1_message->set_nonce(std::string(nonce_bytes.begin(), nonce_bytes.end()));
+  v1_message->set_payload(
+      std::string(encrypted_payload.begin(), encrypted_payload.end()));
+
+  std::string auth_message_serialized;
+  auth_message.SerializeToString(&auth_message_serialized);
+
+  return std::vector<uint8_t>(auth_message_serialized.begin(),
+                              auth_message_serialized.end());
+}
+
+bool VerifyHandshakeMessage(base::span<const uint8_t> auth_message_bytes,
+                            const std::string& auth_token,
+                            std::array<uint8_t, 32> secret,
+                            DeviceRole role) {
+  absl::optional<proto::V1Message> v1_message =
+      ParseAuthMessage(auth_message_bytes);
+  if (!v1_message) {
+    return false;
+  }
+
+  absl::optional<std::vector<uint8_t>> decrypted_bytes =
+      DecryptPayload(std::vector<uint8_t>(v1_message->payload().begin(),
+                                          v1_message->payload().end()),
+                     secret,
+                     std::vector<uint8_t>(v1_message->nonce().begin(),
+                                          v1_message->nonce().end()));
+  if (!decrypted_bytes) {
+    QS_LOG(ERROR) << "Auth payload failed to decrypt.";
+    return false;
+  }
+
+  absl::optional<proto::V1Message::AuthenticationPayload> auth_payload =
+      ParseAuthPayload(*decrypted_bytes);
+  if (!auth_payload) {
+    return false;
+  }
+
+  if (auth_payload->role() != static_cast<int32_t>(role)) {
+    QS_LOG(ERROR) << "AuthenticationPayload role does not match expected role ("
+                  << (role == DeviceRole::kSource ? "Source" : "Target")
+                  << ").";
+    return false;
+  }
+
+  if (auth_payload->auth_string() != auth_token) {
+    QS_LOG(ERROR)
+        << "AuthenticationPayload auth_string does not match auth token.";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace ash::quick_start::handshake
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.h
new file mode 100644
index 0000000..329d183
--- /dev/null
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.h
@@ -0,0 +1,43 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_HANDSHAKE_HELPERS_H_
+#define CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_HANDSHAKE_HELPERS_H_
+
+#include <array>
+
+#include "base/containers/span.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace ash::quick_start::handshake {
+
+// The role for the device producing a handshake message. Values come from
+// this enum:
+// http://google3/java/com/google/android/gms/smartdevice/d2d/proto/aes_gcm_authentication_message.proto;l=26;rcl=489093041
+enum class DeviceRole {
+  kTarget = 1,
+  kSource = 2,
+};
+
+// Build and serialize an AesGcmAuthenticationMessage proto. If |nonce| and
+// |role| are not provided, then a new random nonce and the target device role
+// will be used.
+std::vector<uint8_t> BuildHandshakeMessage(
+    const std::string& auth_token,
+    std::array<uint8_t, 32> secret,
+    absl::optional<std::array<uint8_t, 12>> nonce = absl::nullopt,
+    DeviceRole role = DeviceRole::kTarget);
+
+// Decode an AesGcmAuthenticationMessage proto, attempt to decrypt the auth
+// payload using the secret, and verify that the payload contains the correct
+// role and auth token. If the return value is true, then the remote device is
+// authenticated.
+bool VerifyHandshakeMessage(base::span<const uint8_t> auth_message_bytes,
+                            const std::string& auth_token,
+                            std::array<uint8_t, 32> secret,
+                            DeviceRole role = DeviceRole::kSource);
+
+}  // namespace ash::quick_start::handshake
+
+#endif  // CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_HANDSHAKE_HELPERS_H_
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers_unittest.cc
new file mode 100644
index 0000000..a01edf81
--- /dev/null
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers_unittest.cc
@@ -0,0 +1,194 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/handshake_helpers.h"
+
+#include <string>
+#include <vector>
+
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/proto/aes_gcm_authentication_message.pb.h"
+#include "crypto/aead.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace ash::quick_start::handshake {
+
+namespace {
+
+// Arbitrary string to use as the connection's authentication token.
+constexpr char kAuthToken[] = "auth_token";
+
+// Another auth token that does not match |kAuthToken|.
+constexpr char kAuthToken2[] = "auth_token_2";
+
+// 32 random bytes to use as the shared secret.
+constexpr std::array<uint8_t, 32> kSharedSecret = {
+    0x54, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59,
+    0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4,
+    0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2};
+
+// Another shared secret that does not match |kSharedSecret|.
+constexpr std::array<uint8_t, 32> kSharedSecret2 = {
+    0x00, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59,
+    0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4,
+    0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2};
+
+// 12 random bytes to use as the nonce.
+constexpr std::array<uint8_t, 12> kNonce = {0x60, 0x3e, 0x87, 0x69, 0xa3, 0x55,
+                                            0xd3, 0x49, 0xbd, 0x0a, 0x63, 0xed};
+
+// Some nonsense data that shouldn't parse to anything.
+constexpr std::array<uint8_t, 3> kBadData = {0x01, 0x02, 0x03};
+
+std::vector<uint8_t> BuildRawAuthMessage(
+    absl::optional<proto::AesGcmAuthenticationMessage::Version> version,
+    absl::optional<base::span<const uint8_t>> payload,
+    absl::optional<base::span<const uint8_t>> nonce) {
+  proto::AesGcmAuthenticationMessage auth_message;
+
+  if (version) {
+    auth_message.set_version(*version);
+  }
+  proto::V1Message* v1 = auth_message.mutable_v1();
+  if (payload) {
+    crypto::Aead aead(crypto::Aead::AES_256_GCM);
+    aead.Init(kSharedSecret);
+    std::vector<uint8_t> enc_payload = aead.Seal(
+        std::vector<uint8_t>(payload->begin(), payload->end()), kNonce,
+        /*additional_data=*/base::span<uint8_t>());
+
+    v1->set_payload(std::string(enc_payload.begin(), enc_payload.end()));
+  }
+  if (nonce) {
+    v1->set_nonce(std::string(nonce->begin(), nonce->end()));
+  }
+
+  std::string serialized_auth_message;
+  auth_message.SerializeToString(&serialized_auth_message);
+  return std::vector<uint8_t>(serialized_auth_message.begin(),
+                              serialized_auth_message.end());
+}
+
+std::vector<uint8_t> BuildRawAuthPayload(
+    absl::optional<int32_t> role,
+    absl::optional<std::string> auth_string) {
+  proto::V1Message::AuthenticationPayload auth_payload;
+
+  if (role) {
+    auth_payload.set_role(*role);
+  }
+  if (auth_string) {
+    auth_payload.set_auth_string(*auth_string);
+  }
+
+  std::string serialized_auth_payload;
+  auth_payload.SerializeToString(&serialized_auth_payload);
+  return std::vector<uint8_t>(serialized_auth_payload.begin(),
+                              serialized_auth_payload.end());
+}
+
+struct VerifyHandshakeMessageTestCase {
+  std::string name;
+  std::vector<uint8_t> handshake_message;
+  bool expected_success;
+};
+
+const VerifyHandshakeMessageTestCase kVerifyHandshakeMessageTestCases[] = {
+    {"Success",
+     BuildHandshakeMessage(kAuthToken,
+                           kSharedSecret,
+                           kNonce,
+                           DeviceRole::kSource),
+     /*expected_success=*/true},
+    {"TargetRole",
+     BuildHandshakeMessage(kAuthToken,
+                           kSharedSecret,
+                           kNonce,
+                           DeviceRole::kTarget),
+     /*expected_success=*/false},
+    {"BadSecret",
+     BuildHandshakeMessage(kAuthToken,
+                           kSharedSecret2,
+                           kNonce,
+                           DeviceRole::kSource),
+     /*expected_success=*/false},
+    {"BadAuthToken",
+     BuildHandshakeMessage(kAuthToken2,
+                           kSharedSecret,
+                           kNonce,
+                           DeviceRole::kSource),
+     /*expected_success=*/false},
+    {"UnparsableAuthMessage",
+     std::vector<uint8_t>(kBadData.begin(), kBadData.end()),
+     /*expected_success=*/false},
+    {"UnknownVersion",
+     BuildRawAuthMessage(
+         proto::AesGcmAuthenticationMessage::UNKNOWN_VERSION,
+         BuildRawAuthPayload(static_cast<int32_t>(DeviceRole::kSource),
+                             kAuthToken),
+         kNonce),
+     /*expected_success=*/false},
+    {"MissingVersion",
+     BuildRawAuthMessage(
+         absl::nullopt,
+         BuildRawAuthPayload(static_cast<int32_t>(DeviceRole::kSource),
+                             kAuthToken),
+         kNonce),
+     /*expected_success=*/false},
+    {"UnparsablePayload",
+     BuildRawAuthMessage(proto::AesGcmAuthenticationMessage::V1,
+                         kBadData,
+                         kNonce),
+     /*expected_success=*/false},
+    {"MissingPayload",
+     BuildRawAuthMessage(proto::AesGcmAuthenticationMessage::V1,
+                         absl::nullopt,
+                         kNonce),
+     /*expected_success=*/false},
+    {"BadNonce",
+     BuildRawAuthMessage(
+         proto::AesGcmAuthenticationMessage::V1,
+         BuildRawAuthPayload(static_cast<int32_t>(DeviceRole::kSource),
+                             kAuthToken),
+         kBadData),
+     /*expected_success=*/false},
+    {"MissingNonce",
+     BuildRawAuthMessage(
+         proto::AesGcmAuthenticationMessage::V1,
+         BuildRawAuthPayload(static_cast<int32_t>(DeviceRole::kSource),
+                             kAuthToken),
+         absl::nullopt),
+     /*expected_success=*/false},
+    {"BadRole",
+     BuildRawAuthMessage(proto::AesGcmAuthenticationMessage::V1,
+                         BuildRawAuthPayload(3, kAuthToken),
+                         kNonce),
+     /*expected_success=*/false},
+    {"MissingRole",
+     BuildRawAuthMessage(proto::AesGcmAuthenticationMessage::V1,
+                         BuildRawAuthPayload(absl::nullopt, kAuthToken),
+                         kNonce),
+     /*expected_success=*/false},
+    {"MissingAuthString",
+     BuildRawAuthMessage(
+         proto::AesGcmAuthenticationMessage::V1,
+         BuildRawAuthPayload(static_cast<int32_t>(DeviceRole::kSource),
+                             absl::nullopt),
+         kNonce),
+     /*expected_success=*/false},
+};
+
+}  // namespace
+
+TEST(HandshakeHelpersTest, VerifyHandshakeMessage) {
+  for (const VerifyHandshakeMessageTestCase& test_case :
+       kVerifyHandshakeMessageTestCases) {
+    bool success = VerifyHandshakeMessage(test_case.handshake_message,
+                                          kAuthToken, kSharedSecret);
+    EXPECT_EQ(test_case.expected_success, success)
+        << "Testcase " << test_case.name << " failed";
+  }
+}
+
+}  // namespace ash::quick_start::handshake
diff --git a/chromeos/ash/components/quick_start/proto/BUILD.gn b/chrome/browser/ash/login/oobe_quick_start/connectivity/proto/BUILD.gn
similarity index 100%
rename from chromeos/ash/components/quick_start/proto/BUILD.gn
rename to chrome/browser/ash/login/oobe_quick_start/connectivity/proto/BUILD.gn
diff --git a/chromeos/ash/components/quick_start/proto/aes_gcm_authentication_message.proto b/chrome/browser/ash/login/oobe_quick_start/connectivity/proto/aes_gcm_authentication_message.proto
similarity index 96%
rename from chromeos/ash/components/quick_start/proto/aes_gcm_authentication_message.proto
rename to chrome/browser/ash/login/oobe_quick_start/connectivity/proto/aes_gcm_authentication_message.proto
index 8e174ce4..e026c82 100644
--- a/chromeos/ash/components/quick_start/proto/aes_gcm_authentication_message.proto
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/proto/aes_gcm_authentication_message.proto
@@ -3,7 +3,7 @@
 
 syntax = "proto2";
 
-package quick_start.proto;
+package ash.quick_start.proto;
 
 option optimize_for = LITE_RUNTIME;
 
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h
index c19e7ba..1dbf87d 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h
@@ -199,6 +199,9 @@
   // reboots.
   virtual base::Value::Dict GetPrepareForUpdateInfo() = 0;
 
+  // Gets the 3 digits of the discoverable name. e.g.: Chromebook (123)
+  virtual std::string GetSessionIdDisplayCode() = 0;
+
  protected:
   void MaybeNotifyFeatureStatus();
   void OnConnectionAuthenticated(
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
index 60e2828..885338d 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
@@ -10,7 +10,6 @@
 #include "base/base64.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
-#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -300,6 +299,10 @@
   return prepare_for_update_info;
 }
 
+std::string TargetDeviceConnectionBrokerImpl::GetSessionIdDisplayCode() {
+  return random_session_id_.GetDisplayCode();
+}
+
 void TargetDeviceConnectionBrokerImpl::FetchPersistedSessionContext() {
   PrefService* prefs = g_browser_process->local_state();
   CHECK(prefs->GetBoolean(prefs::kShouldResumeQuickStartAfterReboot));
@@ -509,8 +512,7 @@
 
   // TODO(b/234655072): Handle Connection Closed in the Connection Broker
   connection_ = connection_factory_->Create(
-      nearby_connection, BuildConnectionSessionContext(),
-      std::move(quick_start_decoder_),
+      nearby_connection, BuildConnectionSessionContext(), quick_start_decoder_,
       base::BindOnce(&TargetDeviceConnectionBrokerImpl::OnConnectionClosed,
                      weak_ptr_factory_.GetWeakPtr()),
       base::BindOnce(
@@ -525,12 +527,25 @@
     absl::optional<std::string> auth_token =
         nearby_connections_manager_->GetAuthenticationToken(endpoint_id);
     CHECK(auth_token);
-    // TODO(b/234655072): Handle the handshake callback once the handshake is
-    // fully implemented.
-    connection_->InitiateHandshake(*auth_token, base::DoNothing());
+    connection_->InitiateHandshake(
+        *auth_token,
+        base::BindOnce(&TargetDeviceConnectionBrokerImpl::OnHandshakeCompleted,
+                       weak_ptr_factory_.GetWeakPtr()));
   }
 }
 
+void TargetDeviceConnectionBrokerImpl::OnHandshakeCompleted(bool success) {
+  CHECK(connection_);
+  if (!success) {
+    QS_LOG(ERROR) << "Handshake failed! Dropping the connection.";
+    connection_->Close(ConnectionClosedReason::kAuthenticationFailed);
+    return;
+  }
+
+  QS_LOG(INFO) << "Handshake succeeded!";
+  connection_->MarkConnectionAuthenticated();
+}
+
 const Connection::SessionContext
 TargetDeviceConnectionBrokerImpl::BuildConnectionSessionContext() const {
   Connection::SessionContext context = {
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
index 546ec03..db2f430 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
@@ -65,6 +65,7 @@
                         ResultCallback on_start_advertising_callback) override;
   void StopAdvertising(base::OnceClosure on_stop_advertising_callback) override;
   base::Value::Dict GetPrepareForUpdateInfo() override;
+  std::string GetSessionIdDisplayCode() override;
 
  private:
   // Used to access the |random_session_id_| in tests, and to allow testing
@@ -107,6 +108,8 @@
       NearbyConnectionsManager::ConnectionsStatus status);
   const Connection::SessionContext BuildConnectionSessionContext() const;
 
+  void OnHandshakeCompleted(bool success);
+
   // A 4-digit decimal pin code derived from the connection's authentication
   // token for the pin authentication flow.
   std::string pin_;
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
index 4388159..53f7c3cd 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
@@ -750,8 +750,7 @@
   EXPECT_EQ(kAuthenticationTokenPin, DerivePin());
 }
 
-TEST_F(TargetDeviceConnectionBrokerImplTest,
-       HandshakeInitiatedOnConnectionAccepted) {
+TEST_F(TargetDeviceConnectionBrokerImplTest, Handshake_Success) {
   FinishFetchingBluetoothAdapter();
   connection_broker_->StartAdvertising(&connection_lifecycle_listener_,
                                        /* use_pin_authentication= */ false,
@@ -769,6 +768,34 @@
 
   ASSERT_TRUE(connection());
   EXPECT_TRUE(connection()->WasHandshakeInitiated());
+  EXPECT_FALSE(connection_lifecycle_listener_.connection_authenticated_);
+
+  connection()->HandleHandshakeResult(/*success=*/true);
+  EXPECT_TRUE(connection_lifecycle_listener_.connection_authenticated_);
+}
+
+TEST_F(TargetDeviceConnectionBrokerImplTest, Handshake_Failed) {
+  FinishFetchingBluetoothAdapter();
+  connection_broker_->StartAdvertising(&connection_lifecycle_listener_,
+                                       /* use_pin_authentication= */ false,
+                                       base::DoNothing());
+  EXPECT_FALSE(connection_lifecycle_listener_.qr_code_data_);
+  NearbyConnectionsManager::IncomingConnectionListener*
+      incoming_connection_listener =
+          fake_nearby_connections_manager_.GetAdvertisingListener();
+  ASSERT_TRUE(incoming_connection_listener);
+  incoming_connection_listener->OnIncomingConnectionInitiated(
+      kEndpointId, std::vector<uint8_t>());
+  ASSERT_TRUE(connection_lifecycle_listener_.qr_code_data_);
+  incoming_connection_listener->OnIncomingConnectionAccepted(
+      kEndpointId, std::vector<uint8_t>(), &fake_nearby_connection_);
+
+  ASSERT_TRUE(connection());
+  EXPECT_TRUE(connection()->WasHandshakeInitiated());
+  EXPECT_FALSE(connection_lifecycle_listener_.connection_authenticated_);
+
+  connection()->HandleHandshakeResult(/*success=*/false);
+  EXPECT_FALSE(connection_lifecycle_listener_.connection_authenticated_);
 }
 
 TEST_F(TargetDeviceConnectionBrokerImplTest,
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc
index bc09acb..3e710b7 100644
--- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc
@@ -9,6 +9,7 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/hash/hash.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/uuid.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/fido_assertion_info.h"
@@ -22,6 +23,7 @@
 #include "components/qr_code_generator/qr_code_generator.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
+#include "ui/chromeos/devicetype_utils.h"
 
 namespace ash::quick_start {
 
@@ -174,6 +176,12 @@
   NotifyObservers();
 }
 
+std::string TargetDeviceBootstrapController::GetDiscoverableName() {
+  std::string device_type = base::UTF16ToUTF8(ui::GetChromeOSDeviceName());
+  std::string code = connection_broker_->GetSessionIdDisplayCode();
+  return device_type + " (" + code + ")";
+}
+
 void TargetDeviceBootstrapController::NotifyObservers() {
   for (auto& obs : observers_) {
     obs.OnStatusChanged(status_);
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h
index 397f9cf..647b906 100644
--- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h
+++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h
@@ -108,6 +108,7 @@
   void OnConnectionClosed(
       TargetDeviceConnectionBroker::ConnectionClosedReason reason) override;
 
+  std::string GetDiscoverableName();
   void AttemptWifiCredentialTransfer();
   void AttemptGoogleAccountTransfer();
 
diff --git a/chrome/browser/ash/login/reporting/lock_unlock_reporter.cc b/chrome/browser/ash/login/reporting/lock_unlock_reporter.cc
index 20bac40..fb634368 100644
--- a/chrome/browser/ash/login/reporting/lock_unlock_reporter.cc
+++ b/chrome/browser/ash/login/reporting/lock_unlock_reporter.cc
@@ -9,7 +9,6 @@
 #include "base/logging.h"
 #include "base/task/bind_post_task.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
-#include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper.h"
 #include "chrome/browser/browser_process.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -55,12 +54,9 @@
 
 LockUnlockReporter::LockUnlockReporter(
     std::unique_ptr<::reporting::UserEventReporterHelper> helper,
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service,
     base::Clock* clock)
-    : clock_(clock),
-      helper_(std::move(helper)),
-      reporting_user_tracker_(reporting_user_tracker) {
+    : clock_(clock), helper_(std::move(helper)) {
   if (managed_session_service) {
     managed_session_observation_.Observe(managed_session_service);
   }
@@ -70,23 +66,20 @@
 
 // static
 std::unique_ptr<LockUnlockReporter> LockUnlockReporter::Create(
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service) {
   return base::WrapUnique(new LockUnlockReporter(
       std::make_unique<::reporting::UserEventReporterHelper>(
           ::reporting::Destination::LOCK_UNLOCK_EVENTS),
-      reporting_user_tracker, managed_session_service));
+      managed_session_service));
 }
 
 // static
 std::unique_ptr<LockUnlockReporter> LockUnlockReporter::CreateForTest(
     std::unique_ptr<::reporting::UserEventReporterHelper> reporter_helper,
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service,
     base::Clock* clock) {
-  return base::WrapUnique(
-      new LockUnlockReporter(std::move(reporter_helper), reporting_user_tracker,
-                             managed_session_service, clock));
+  return base::WrapUnique(new LockUnlockReporter(
+      std::move(reporter_helper), managed_session_service, clock));
 }
 
 void LockUnlockReporter::MaybeReportEvent(LockUnlockRecord record) {
@@ -95,7 +88,7 @@
   }
   const std::string& user_email =
       user_manager::UserManager::Get()->GetPrimaryUser()->GetDisplayEmail();
-  if (!reporting_user_tracker_->ShouldReportUser(user_email)) {
+  if (!helper_->ShouldReportUser(user_email)) {
     return;
   }
 
diff --git a/chrome/browser/ash/login/reporting/lock_unlock_reporter.h b/chrome/browser/ash/login/reporting/lock_unlock_reporter.h
index 0a9187a0..81c9e7f 100644
--- a/chrome/browser/ash/login/reporting/lock_unlock_reporter.h
+++ b/chrome/browser/ash/login/reporting/lock_unlock_reporter.h
@@ -14,13 +14,9 @@
 #include "chrome/browser/ash/policy/status_collector/managed_session_service.h"
 #include "chrome/browser/policy/messaging_layer/proto/synced/lock_unlock_event.pb.h"
 
-namespace policy {
-class ReportingUserTracker;
-}  // namespace policy
-
 namespace reporting {
 class UserEventReporterHelper;
-}  // namespace reporting
+}
 
 namespace ash {
 namespace reporting {
@@ -37,13 +33,11 @@
 
   // For prod. Uses the default implementation of UserEventReporterHelper.
   static std::unique_ptr<LockUnlockReporter> Create(
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service);
 
   // For use in testing only. Allows user to pass in a test helper.
   static std::unique_ptr<LockUnlockReporter> CreateForTest(
       std::unique_ptr<::reporting::UserEventReporterHelper> reporter_helper,
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service,
       base::Clock* clock = base::DefaultClock::GetInstance());
 
@@ -56,7 +50,6 @@
  private:
   LockUnlockReporter(
       std::unique_ptr<::reporting::UserEventReporterHelper> helper,
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service,
       base::Clock* clock = base::DefaultClock::GetInstance());
 
@@ -66,9 +59,6 @@
 
   std::unique_ptr<::reporting::UserEventReporterHelper> helper_;
 
-  const base::raw_ptr<policy::ReportingUserTracker, ExperimentalAsh>
-      reporting_user_tracker_;
-
   base::ScopedObservation<policy::ManagedSessionService,
                           policy::ManagedSessionService::Observer>
       managed_session_observation_{this};
diff --git a/chrome/browser/ash/login/reporting/lock_unlock_reporter_unittest.cc b/chrome/browser/ash/login/reporting/lock_unlock_reporter_unittest.cc
index 0949c27..bfb4dd8 100644
--- a/chrome/browser/ash/login/reporting/lock_unlock_reporter_unittest.cc
+++ b/chrome/browser/ash/login/reporting/lock_unlock_reporter_unittest.cc
@@ -9,11 +9,9 @@
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
-#include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/policy/messaging_layer/proto/synced/lock_unlock_event.pb.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/login/auth/public/auth_failure.h"
@@ -56,39 +54,30 @@
     user_manager_ = user_manager.get();
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         std::move(user_manager));
-
-    reporting_user_tracker_ =
-        std::make_unique<policy::ReportingUserTracker>(user_manager_);
   }
 
-  void Shutdown() {
-    reporting_user_tracker_.reset();
-    user_manager_enabler_.reset();
-    SessionManagerClient::Shutdown();
-    chromeos::PowerManagerClient::Shutdown();
-  }
+  void Shutdown() { chromeos::PowerManagerClient::Shutdown(); }
 
   session_manager::SessionManager* session_manager() {
     return &session_manager_;
   }
 
   std::unique_ptr<TestingProfile> CreateRegularUserProfile() {
-    const AccountId account_id = AccountId::FromUserEmail(kFakeEmail);
-
+    AccountId account_id = AccountId::FromUserEmail(kFakeEmail);
+    auto* const user = user_manager_->AddUser(account_id);
     TestingProfile::Builder profile_builder;
-    profile_builder.SetProfileName(account_id.GetUserEmail());
+    profile_builder.SetProfileName(user->GetAccountId().GetUserEmail());
     auto profile = profile_builder.Build();
-
-    auto* const user = user_manager_->AddUserWithAffiliationAndTypeAndProfile(
-        account_id, /*is_affiliated=*/true, user_manager::USER_TYPE_REGULAR,
-        profile.get());
-
+    ProfileHelper::Get()->SetProfileToUserMappingForTesting(user);
+    ProfileHelper::Get()->SetUserToProfileMappingForTesting(user,
+                                                            profile.get());
     user_manager_->LoginUser(user->GetAccountId(), true);
     return profile;
   }
 
   std::unique_ptr<::reporting::UserEventReporterHelperTesting>
   GetReporterHelper(bool reporting_enabled,
+                    bool should_report_user,
                     ::reporting::Status status = ::reporting::Status()) {
     record_.Clear();
     report_count_ = 0;
@@ -111,7 +100,8 @@
 
     auto reporter_helper =
         std::make_unique<::reporting::UserEventReporterHelperTesting>(
-            reporting_enabled, /*is_kiosk_user=*/false, std::move(mock_queue));
+            reporting_enabled, should_report_user, /*is_kiosk_user=*/false,
+            std::move(mock_queue));
     return reporter_helper;
   }
 
@@ -119,15 +109,9 @@
 
   int GetReportCount() { return report_count_; }
 
-  policy::ReportingUserTracker* reporting_user_tracker() {
-    return reporting_user_tracker_.get();
-  }
-
  private:
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   raw_ptr<FakeChromeUserManager, ExperimentalAsh> user_manager_;
   std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
-  std::unique_ptr<policy::ReportingUserTracker> reporting_user_tracker_;
   content::BrowserTaskEnvironment task_environment_;
 
   LockUnlockRecord record_;
@@ -150,11 +134,11 @@
 TEST_F(LockUnlockReporterTest, ReportLockPolicyEnabled) {
   policy::ManagedSessionService managed_session_service;
   auto reporter_helper = test_helper_.GetReporterHelper(
-      /*reporting_enabled=*/true);
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/true);
 
-  auto reporter = LockUnlockReporter::CreateForTest(
-      std::move(reporter_helper), test_helper_.reporting_user_tracker(),
-      &managed_session_service);
+  auto reporter = LockUnlockReporter::CreateForTest(std::move(reporter_helper),
+                                                    &managed_session_service);
 
   auto profile = test_helper_.CreateRegularUserProfile();
   auto* const user = ProfileHelper::Get()->GetUserByProfile(profile.get());
@@ -177,11 +161,11 @@
 TEST_F(LockUnlockReporterTest, ReportLockPolicyDisabled) {
   policy::ManagedSessionService managed_session_service;
   auto reporter_helper = test_helper_.GetReporterHelper(
-      /*reporting_enabled=*/false);
+      /*reporting_enabled=*/false,
+      /*should_report_user=*/true);
 
-  auto reporter = LockUnlockReporter::CreateForTest(
-      std::move(reporter_helper), test_helper_.reporting_user_tracker(),
-      &managed_session_service);
+  auto reporter = LockUnlockReporter::CreateForTest(std::move(reporter_helper),
+                                                    &managed_session_service);
 
   auto profile = test_helper_.CreateRegularUserProfile();
   auto* const user = ProfileHelper::Get()->GetUserByProfile(profile.get());
@@ -198,11 +182,11 @@
   const auto test_case = GetParam();
   policy::ManagedSessionService managed_session_service;
   auto reporter_helper = test_helper_.GetReporterHelper(
-      /*reporting_enabled=*/false);
+      /*reporting_enabled=*/false,
+      /*should_report_user=*/true);
 
-  auto reporter = LockUnlockReporter::CreateForTest(
-      std::move(reporter_helper), test_helper_.reporting_user_tracker(),
-      &managed_session_service);
+  auto reporter = LockUnlockReporter::CreateForTest(std::move(reporter_helper),
+                                                    &managed_session_service);
 
   auto profile = test_helper_.CreateRegularUserProfile();
   auto* const user = ProfileHelper::Get()->GetUserByProfile(profile.get());
@@ -218,11 +202,11 @@
   const auto test_case = GetParam();
   policy::ManagedSessionService managed_session_service;
   auto reporter_helper = test_helper_.GetReporterHelper(
-      /*reporting_enabled=*/true);
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/true);
 
-  auto reporter = LockUnlockReporter::CreateForTest(
-      std::move(reporter_helper), test_helper_.reporting_user_tracker(),
-      &managed_session_service);
+  auto reporter = LockUnlockReporter::CreateForTest(std::move(reporter_helper),
+                                                    &managed_session_service);
 
   auto profile = test_helper_.CreateRegularUserProfile();
   auto* const user = ProfileHelper::Get()->GetUserByProfile(profile.get());
diff --git a/chrome/browser/ash/login/reporting/login_logout_reporter.cc b/chrome/browser/ash/login/reporting/login_logout_reporter.cc
index 75265206..944e8a4 100644
--- a/chrome/browser/ash/login/reporting/login_logout_reporter.cc
+++ b/chrome/browser/ash/login/reporting/login_logout_reporter.cc
@@ -9,7 +9,6 @@
 #include "base/task/single_thread_task_runner.h"
 #include "chrome/browser/ash/login/existing_user_controller.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
-#include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/browser_process.h"
@@ -120,12 +119,10 @@
 LoginLogoutReporter::LoginLogoutReporter(
     std::unique_ptr<::reporting::UserEventReporterHelper> reporter_helper,
     std::unique_ptr<Delegate> delegate,
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service,
     base::Clock* clock)
     : reporter_helper_(std::move(reporter_helper)),
       delegate_(std::move(delegate)),
-      reporting_user_tracker_(reporting_user_tracker),
       clock_(clock) {
   if (managed_session_service) {
     managed_session_observation_.Observe(managed_session_service);
@@ -137,26 +134,24 @@
 
 // static
 std::unique_ptr<LoginLogoutReporter> LoginLogoutReporter::Create(
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service) {
   auto reporter_helper = std::make_unique<::reporting::UserEventReporterHelper>(
       ::reporting::Destination::LOGIN_LOGOUT_EVENTS);
   auto delegate = std::make_unique<LoginLogoutReporter::Delegate>();
-  return base::WrapUnique(
-      new LoginLogoutReporter(std::move(reporter_helper), std::move(delegate),
-                              reporting_user_tracker, managed_session_service));
+  return base::WrapUnique(new LoginLogoutReporter(std::move(reporter_helper),
+                                                  std::move(delegate),
+                                                  managed_session_service));
 }
 
 // static
 std::unique_ptr<LoginLogoutReporter> LoginLogoutReporter::CreateForTest(
     std::unique_ptr<::reporting::UserEventReporterHelper> reporter_helper,
     std::unique_ptr<LoginLogoutReporter::Delegate> delegate,
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service,
     base::Clock* clock) {
-  return base::WrapUnique(new LoginLogoutReporter(
-      std::move(reporter_helper), std::move(delegate), reporting_user_tracker,
-      managed_session_service, clock));
+  return base::WrapUnique(
+      new LoginLogoutReporter(std::move(reporter_helper), std::move(delegate),
+                              managed_session_service, clock));
 }
 
 void LoginLogoutReporter::MaybeReportEvent(LoginLogoutRecord record,
@@ -173,7 +168,7 @@
       session_type == LoginLogoutSessionType::GUEST_SESSION) {
     record.set_is_guest_session(true);
   } else if (session_type == LoginLogoutSessionType::REGULAR_USER_SESSION &&
-             reporting_user_tracker_->ShouldReportUser(user_email)) {
+             reporter_helper_->ShouldReportUser(user_email)) {
     record.mutable_affiliated_user()->set_user_email(user_email);
   }
   reporter_helper_->ReportEvent(
diff --git a/chrome/browser/ash/login/reporting/login_logout_reporter.h b/chrome/browser/ash/login/reporting/login_logout_reporter.h
index bdc6255..27f2a43 100644
--- a/chrome/browser/ash/login/reporting/login_logout_reporter.h
+++ b/chrome/browser/ash/login/reporting/login_logout_reporter.h
@@ -18,12 +18,10 @@
 
 class PrefRegistrySimple;
 
-namespace policy {
-class ReportingUserTracker;
-}  // namespace policy
-
 namespace reporting {
+
 class UserEventReporterHelper;
+
 }  // namespace reporting
 
 namespace ash {
@@ -54,13 +52,11 @@
   ~LoginLogoutReporter() override;
 
   static std::unique_ptr<LoginLogoutReporter> Create(
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service);
 
   static std::unique_ptr<LoginLogoutReporter> CreateForTest(
       std::unique_ptr<::reporting::UserEventReporterHelper> reporter_helper,
       std::unique_ptr<Delegate> delegate,
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service,
       base::Clock* clock = base::DefaultClock::GetInstance());
 
@@ -81,7 +77,6 @@
   LoginLogoutReporter(
       std::unique_ptr<::reporting::UserEventReporterHelper> reporter_helper,
       std::unique_ptr<Delegate> delegate,
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service,
       base::Clock* clock = base::DefaultClock::GetInstance());
 
@@ -93,9 +88,6 @@
 
   std::unique_ptr<Delegate> delegate_;
 
-  const base::raw_ptr<policy::ReportingUserTracker, ExperimentalAsh>
-      reporting_user_tracker_;
-
   base::ScopedObservation<policy::ManagedSessionService,
                           policy::ManagedSessionService::Observer>
       managed_session_observation_{this};
diff --git a/chrome/browser/ash/login/reporting/login_logout_reporter_unittest.cc b/chrome/browser/ash/login/reporting/login_logout_reporter_unittest.cc
index 9bb4e59..8114f5d1 100644
--- a/chrome/browser/ash/login/reporting/login_logout_reporter_unittest.cc
+++ b/chrome/browser/ash/login/reporting/login_logout_reporter_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
-#include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
@@ -49,21 +48,9 @@
     user_manager_ = user_manager.get();
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         std::move(user_manager));
-
-    reporting_user_tracker_ =
-        std::make_unique<policy::ReportingUserTracker>(user_manager_);
   }
 
-  void Shutdown() {
-    reporting_user_tracker_.reset();
-    user_manager_enabler_.reset();
-    session_termination_manager_.reset();
-    chromeos::PowerManagerClient::Shutdown();
-  }
-
-  void CreateRegularUser(const AccountId& account_id, bool is_affiliated) {
-    user_manager_->AddUserWithAffiliation(account_id, is_affiliated);
-  }
+  void Shutdown() { chromeos::PowerManagerClient::Shutdown(); }
 
   std::unique_ptr<TestingProfile> CreateProfile(user_manager::User* user) {
     TestingProfile::Builder profile_builder;
@@ -76,10 +63,9 @@
     return profile;
   }
 
-  std::unique_ptr<TestingProfile> CreateRegularUserProfile(bool is_affiliated) {
+  std::unique_ptr<TestingProfile> CreateRegularUserProfile() {
     AccountId account_id = AccountId::FromUserEmail(user_email);
-    auto* const user =
-        user_manager_->AddUserWithAffiliation(account_id, is_affiliated);
+    auto* const user = user_manager_->AddUser(account_id);
     return CreateProfile(user);
   }
 
@@ -121,11 +107,10 @@
   }
 
   std::unique_ptr<TestingProfile> CreateProfileByType(
-      user_manager::UserType user_type,
-      bool is_affiliated) {
+      user_manager::UserType user_type) {
     switch (user_type) {
       case user_manager::USER_TYPE_REGULAR:
-        return CreateRegularUserProfile(is_affiliated);
+        return CreateRegularUserProfile();
       case user_manager::USER_TYPE_GUEST:
         return CreateGuestProfile();
       case user_manager::USER_TYPE_PUBLIC_ACCOUNT:
@@ -144,6 +129,7 @@
 
   std::unique_ptr<::reporting::UserEventReporterHelperTesting>
   GetReporterHelper(bool reporting_enabled,
+                    bool should_report_user,
                     ::reporting::Status status = ::reporting::Status()) {
     record_.Clear();
     report_count_ = 0;
@@ -166,7 +152,8 @@
 
     auto reporter_helper =
         std::make_unique<::reporting::UserEventReporterHelperTesting>(
-            reporting_enabled, /*is_kiosk_user=*/false, std::move(mock_queue));
+            reporting_enabled, should_report_user, /*is_kiosk_user=*/false,
+            std::move(mock_queue));
     return reporter_helper;
   }
 
@@ -174,15 +161,9 @@
 
   int GetReportCount() { return report_count_; }
 
-  policy::ReportingUserTracker* reporting_user_tracker() {
-    return reporting_user_tracker_.get();
-  }
-
  private:
   raw_ptr<FakeChromeUserManager, ExperimentalAsh> user_manager_;
   std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
-  std::unique_ptr<policy::ReportingUserTracker> reporting_user_tracker_;
-
   content::BrowserTaskEnvironment task_environment_;
   std::unique_ptr<SessionTerminationManager> session_termination_manager_;
 
@@ -212,15 +193,16 @@
 
 TEST_F(LoginLogoutReporterTest, ReportAffiliatedLogin) {
   policy::ManagedSessionService managed_session_service;
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/true);
 
   auto reporter = LoginLogoutReporter::CreateForTest(
       std::move(reporter_helper),
       std::make_unique<LoginLogoutReporterTestDelegate>(),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+      &managed_session_service);
 
-  auto profile = test_helper_.CreateRegularUserProfile(/*is_affiliated=*/true);
+  auto profile = test_helper_.CreateRegularUserProfile();
   auto* const user = ProfileHelper::Get()->GetUserByProfile(profile.get());
   managed_session_service.OnUserProfileLoaded(user->GetAccountId());
   const LoginLogoutRecord& record = test_helper_.GetRecord();
@@ -246,16 +228,16 @@
       test_case.user_type == user_manager::USER_TYPE_GUEST;
 
   policy::ManagedSessionService managed_session_service;
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
   auto reporter = LoginLogoutReporter::CreateForTest(
       std::move(reporter_helper),
       std::make_unique<LoginLogoutReporterTestDelegate>(),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+      &managed_session_service);
 
-  auto profile = test_helper_.CreateProfileByType(test_case.user_type,
-                                                  /*is_affiliated=*/false);
+  auto profile = test_helper_.CreateProfileByType(test_case.user_type);
   auto* const user = ProfileHelper::Get()->GetUserByProfile(profile.get());
   managed_session_service.OnUserProfileLoaded(user->GetAccountId());
   const LoginLogoutRecord& record = test_helper_.GetRecord();
@@ -273,15 +255,16 @@
 
 TEST_F(LoginLogoutReporterTest, ReportAffiliatedLogout) {
   policy::ManagedSessionService managed_session_service;
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/true);
 
   auto reporter = LoginLogoutReporter::CreateForTest(
       std::move(reporter_helper),
       std::make_unique<LoginLogoutReporterTestDelegate>(),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+      &managed_session_service);
 
-  auto profile = test_helper_.CreateRegularUserProfile(/*is_affiliated=*/true);
+  auto profile = test_helper_.CreateRegularUserProfile();
   managed_session_service.OnSessionWillBeTerminated();
   const LoginLogoutRecord& record = test_helper_.GetRecord();
 
@@ -305,16 +288,16 @@
       test_case.user_type == user_manager::USER_TYPE_GUEST;
 
   policy::ManagedSessionService managed_session_service;
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
   auto reporter = LoginLogoutReporter::CreateForTest(
       std::move(reporter_helper),
       std::make_unique<LoginLogoutReporterTestDelegate>(),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+      &managed_session_service);
 
-  auto profile = test_helper_.CreateProfileByType(test_case.user_type,
-                                                  /*is_affiliated=*/false);
+  auto profile = test_helper_.CreateProfileByType(test_case.user_type);
   managed_session_service.OnSessionWillBeTerminated();
   const LoginLogoutRecord& record = test_helper_.GetRecord();
 
@@ -331,16 +314,16 @@
 TEST_P(LoginLogoutReporterTest, ReportLoginLogoutDisabled) {
   const auto test_case = GetParam();
   policy::ManagedSessionService managed_session_service;
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/false);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/false,
+      /*should_report_user=*/false);
 
   auto reporter = LoginLogoutReporter::CreateForTest(
       std::move(reporter_helper),
       std::make_unique<LoginLogoutReporterTestDelegate>(),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+      &managed_session_service);
 
-  auto profile = test_helper_.CreateProfileByType(test_case.user_type,
-                                                  /*is_affiliated=*/true);
+  auto profile = test_helper_.CreateProfileByType(test_case.user_type);
   auto* const user = ProfileHelper::Get()->GetUserByProfile(profile.get());
   managed_session_service.OnUserProfileLoaded(user->GetAccountId());
   managed_session_service.OnSessionWillBeTerminated();
@@ -380,15 +363,16 @@
 
 TEST_F(LoginFailureReporterTest, ReportAffiliatedLoginFailure_OwnerRequired) {
   policy::ManagedSessionService managed_session_service;
-  const AccountId account_id = AccountId::FromUserEmail(user_email);
-  auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(account_id);
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(
+      AccountId::FromUserEmail(user_email));
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/true);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
-  test_helper_.CreateRegularUser(account_id, /*is_affiliated=*/true);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
+
   managed_session_service.OnAuthFailure(
       AuthFailure(AuthFailure::OWNER_REQUIRED));
   const LoginLogoutRecord& record = test_helper_.GetRecord();
@@ -412,16 +396,16 @@
 TEST_F(LoginFailureReporterTest,
        ReportAffiliatedLoginFailure_UnrecoverableCryptohome) {
   policy::ManagedSessionService managed_session_service;
-  const AccountId account_id = AccountId::FromUserEmail(user_email);
-  auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(account_id);
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(
+      AccountId::FromUserEmail(user_email));
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/true);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
-  test_helper_.CreateRegularUser(account_id, /*is_affiliated=*/true);
   managed_session_service.OnAuthFailure(
       AuthFailure(AuthFailure::UNRECOVERABLE_CRYPTOHOME));
   const LoginLogoutRecord& record = test_helper_.GetRecord();
@@ -446,12 +430,13 @@
   policy::ManagedSessionService managed_session_service;
   auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(
       AccountId::FromUserEmail(user_email));
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
   managed_session_service.OnAuthFailure(AuthFailure(AuthFailure::TPM_ERROR));
   const LoginLogoutRecord& record = test_helper_.GetRecord();
@@ -477,12 +462,13 @@
       AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId(
           "managed_guest", policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION));
   auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(account_id);
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
   managed_session_service.OnAuthFailure(
       AuthFailure(AuthFailure::TPM_UPDATE_REQUIRED));
@@ -509,12 +495,13 @@
       AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId(
           "managed_guest", policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION));
   auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(account_id);
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
   managed_session_service.OnAuthFailure(
       AuthFailure(AuthFailure::COULD_NOT_MOUNT_TMPFS));
@@ -538,12 +525,13 @@
   policy::ManagedSessionService managed_session_service;
   auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(
       user_manager::GuestAccountId());
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
   managed_session_service.OnAuthFailure(
       AuthFailure(AuthFailure::MISSING_CRYPTOHOME));
@@ -566,12 +554,13 @@
   policy::ManagedSessionService managed_session_service;
   auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(
       AccountId::FromUserEmail(user_email));
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/false);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/false,
+      /*should_report_user=*/true);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
   managed_session_service.OnAuthFailure(
       AuthFailure(AuthFailure::MISSING_CRYPTOHOME));
@@ -586,14 +575,14 @@
     base::SimpleTestClock test_clock;
     test_clock.SetNow(failure_time);
     policy::ManagedSessionService managed_session_service;
-    auto reporter_helper =
-        test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+    auto reporter_helper = test_helper_.GetReporterHelper(
+        /*reporting_enabled=*/true,
+        /*should_report_user=*/false);
 
     auto reporter = LoginLogoutReporter::CreateForTest(
         std::move(reporter_helper),
         std::make_unique<LoginLogoutReporterTestDelegate>(),
-        test_helper_.reporting_user_tracker(), &managed_session_service,
-        &test_clock);
+        &managed_session_service, &test_clock);
     base::RunLoop().RunUntilIdle();
 
     managed_session_service.OnKioskProfileLoadFailed();
@@ -607,14 +596,14 @@
     test_clock.SetNow(failure_time + base::Hours(10));
     policy::ManagedSessionService managed_session_service;
     // Only |reporting_enabled| value at the time of kiosk login failure matter.
-    auto reporter_helper =
-        test_helper_.GetReporterHelper(/*reporting_enabled=*/false);
+    auto reporter_helper = test_helper_.GetReporterHelper(
+        /*reporting_enabled=*/false,
+        /*should_report_user=*/false);
 
     auto reporter = LoginLogoutReporter::CreateForTest(
         std::move(reporter_helper),
         std::make_unique<LoginLogoutReporterTestDelegate>(),
-        test_helper_.reporting_user_tracker(), &managed_session_service,
-        &test_clock);
+        &managed_session_service, &test_clock);
     base::RunLoop().RunUntilIdle();
     const LoginLogoutRecord& record = test_helper_.GetRecord();
 
@@ -637,14 +626,14 @@
     base::SimpleTestClock test_clock;
     test_clock.SetNow(failure_time + base::Hours(20));
     policy::ManagedSessionService managed_session_service;
-    auto reporter_helper =
-        test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+    auto reporter_helper = test_helper_.GetReporterHelper(
+        /*reporting_enabled=*/true,
+        /*should_report_user=*/false);
 
     auto reporter = LoginLogoutReporter::CreateForTest(
         std::move(reporter_helper),
         std::make_unique<LoginLogoutReporterTestDelegate>(),
-        test_helper_.reporting_user_tracker(), &managed_session_service,
-        &test_clock);
+        &managed_session_service, &test_clock);
     base::RunLoop().RunUntilIdle();
 
     ASSERT_THAT(test_helper_.GetReportCount(), Eq(0));
@@ -658,14 +647,14 @@
     base::SimpleTestClock test_clock;
     test_clock.SetNow(failure_time);
     policy::ManagedSessionService managed_session_service;
-    auto reporter_helper =
-        test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+    auto reporter_helper = test_helper_.GetReporterHelper(
+        /*reporting_enabled=*/true,
+        /*should_report_user=*/false);
 
     auto reporter = LoginLogoutReporter::CreateForTest(
         std::move(reporter_helper),
         std::make_unique<LoginLogoutReporterTestDelegate>(),
-        test_helper_.reporting_user_tracker(), &managed_session_service,
-        &test_clock);
+        &managed_session_service, &test_clock);
     base::RunLoop().RunUntilIdle();
 
     managed_session_service.OnKioskProfileLoadFailed();
@@ -682,13 +671,13 @@
     // Only |reporting_enabled| value at the time of kiosk login failure matter.
     auto reporter_helper = test_helper_.GetReporterHelper(
         /*reporting_enabled=*/true,
+        /*should_report_user=*/false,
         ::reporting::Status(::reporting::error::INTERNAL, ""));
 
     auto reporter = LoginLogoutReporter::CreateForTest(
         std::move(reporter_helper),
         std::make_unique<LoginLogoutReporterTestDelegate>(),
-        test_helper_.reporting_user_tracker(), &managed_session_service,
-        &test_clock);
+        &managed_session_service, &test_clock);
     base::RunLoop().RunUntilIdle();
 
     ASSERT_THAT(test_helper_.GetReportCount(), Eq(1));
@@ -700,14 +689,14 @@
     base::SimpleTestClock test_clock;
     test_clock.SetNow(failure_time + base::Hours(20));
     policy::ManagedSessionService managed_session_service;
-    auto reporter_helper =
-        test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+    auto reporter_helper = test_helper_.GetReporterHelper(
+        /*reporting_enabled=*/true,
+        /*should_report_user=*/false);
 
     auto reporter = LoginLogoutReporter::CreateForTest(
         std::move(reporter_helper),
         std::make_unique<LoginLogoutReporterTestDelegate>(),
-        test_helper_.reporting_user_tracker(), &managed_session_service,
-        &test_clock);
+        &managed_session_service, &test_clock);
     base::RunLoop().RunUntilIdle();
     const LoginLogoutRecord& record = test_helper_.GetRecord();
 
@@ -733,14 +722,14 @@
     base::SimpleTestClock test_clock;
     test_clock.SetNow(failure_time);
     policy::ManagedSessionService managed_session_service;
-    auto reporter_helper =
-        test_helper_.GetReporterHelper(/*reporting_enabled=*/false);
+    auto reporter_helper = test_helper_.GetReporterHelper(
+        /*reporting_enabled=*/false,
+        /*should_report_user=*/false);
 
     auto reporter = LoginLogoutReporter::CreateForTest(
         std::move(reporter_helper),
         std::make_unique<LoginLogoutReporterTestDelegate>(),
-        test_helper_.reporting_user_tracker(), &managed_session_service,
-        &test_clock);
+        &managed_session_service, &test_clock);
     base::RunLoop().RunUntilIdle();
 
     managed_session_service.OnKioskProfileLoadFailed();
@@ -754,14 +743,14 @@
     test_clock.SetNow(failure_time + base::Hours(10));
     policy::ManagedSessionService managed_session_service;
     // Only |reporting_enabled| value at the time of kiosk login failure matter.
-    auto reporter_helper =
-        test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+    auto reporter_helper = test_helper_.GetReporterHelper(
+        /*reporting_enabled=*/true,
+        /*should_report_user=*/false);
 
     auto reporter = LoginLogoutReporter::CreateForTest(
         std::move(reporter_helper),
         std::make_unique<LoginLogoutReporterTestDelegate>(),
-        test_helper_.reporting_user_tracker(), &managed_session_service,
-        &test_clock);
+        &managed_session_service, &test_clock);
     base::RunLoop().RunUntilIdle();
 
     ASSERT_THAT(test_helper_.GetReportCount(), Eq(0));
@@ -773,12 +762,13 @@
   policy::ManagedSessionService managed_session_service;
   auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(
       AccountId::FromUserEmail(user_email));
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
   managed_session_service.OnAuthFailure(GetParam());
   const LoginLogoutRecord& record = test_helper_.GetRecord();
@@ -804,12 +794,13 @@
       AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId(
           "managed_guest", policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION));
   auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(account_id);
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
   managed_session_service.OnAuthFailure(GetParam());
   const LoginLogoutRecord& record = test_helper_.GetRecord();
@@ -832,12 +823,13 @@
   policy::ManagedSessionService managed_session_service;
   auto delegate = std::make_unique<LoginLogoutReporterTestDelegate>(
       user_manager::GuestAccountId());
-  auto reporter_helper =
-      test_helper_.GetReporterHelper(/*reporting_enabled=*/true);
+  auto reporter_helper = test_helper_.GetReporterHelper(
+      /*reporting_enabled=*/true,
+      /*should_report_user=*/false);
 
-  auto reporter = LoginLogoutReporter::CreateForTest(
-      std::move(reporter_helper), std::move(delegate),
-      test_helper_.reporting_user_tracker(), &managed_session_service);
+  auto reporter = LoginLogoutReporter::CreateForTest(std::move(reporter_helper),
+                                                     std::move(delegate),
+                                                     &managed_session_service);
 
   managed_session_service.OnAuthFailure(GetParam());
   const LoginLogoutRecord& record = test_helper_.GetRecord();
diff --git a/chrome/browser/ash/login/screens/quick_start_screen.cc b/chrome/browser/ash/login/screens/quick_start_screen.cc
index 6ba11b8..30baf5b 100644
--- a/chrome/browser/ash/login/screens/quick_start_screen.cc
+++ b/chrome/browser/ash/login/screens/quick_start_screen.cc
@@ -52,6 +52,8 @@
       LoginDisplayHost::default_host()->GetQuickStartBootstrapController();
   bootstrap_controller_->AddObserver(this);
   bootstrap_controller_->StartAdvertising();
+
+  DetermineDiscoverableName();
 }
 
 void QuickStartScreen::HideImpl() {
@@ -110,6 +112,14 @@
   }
 }
 
+void QuickStartScreen::DetermineDiscoverableName() {
+  CHECK(bootstrap_controller_);
+  discoverable_name_ = bootstrap_controller_->GetDiscoverableName();
+  if (view_) {
+    view_->SetDiscoverableName(discoverable_name_);
+  }
+}
+
 void QuickStartScreen::UnbindFromBootstrapController() {
   if (!bootstrap_controller_) {
     return;
diff --git a/chrome/browser/ash/login/screens/quick_start_screen.h b/chrome/browser/ash/login/screens/quick_start_screen.h
index 3a49ec2..86ab6c4 100644
--- a/chrome/browser/ash/login/screens/quick_start_screen.h
+++ b/chrome/browser/ash/login/screens/quick_start_screen.h
@@ -46,6 +46,10 @@
   void OnStatusChanged(
       const quick_start::TargetDeviceBootstrapController::Status& status) final;
 
+  // Sets in the UI the discoverable name that will be used for advertising.
+  // Android devices will see this fast pair notification 'Chromebook (123)'
+  void DetermineDiscoverableName();
+
   void UnbindFromBootstrapController();
   void SendRandomFiguresForTesting() const;
 
@@ -53,6 +57,7 @@
   // MultideviceSetupScreen.
   void SavePhoneInstanceID();
 
+  std::string discoverable_name_;
   base::WeakPtr<TView> view_;
   ScreenExitCallback exit_callback_;
 
diff --git a/chrome/browser/ash/login/screens/update_screen.cc b/chrome/browser/ash/login/screens/update_screen.cc
index aed854d..c1a3f32d 100644
--- a/chrome/browser/ash/login/screens/update_screen.cc
+++ b/chrome/browser/ash/login/screens/update_screen.cc
@@ -17,6 +17,7 @@
 #include "build/branding_buildflags.h"
 #include "chrome/browser/ash/login/configuration_keys.h"
 #include "chrome/browser/ash/login/error_screens_histogram_helper.h"
+#include "chrome/browser/ash/login/login_pref_names.h"
 #include "chrome/browser/ash/login/screens/network_error.h"
 #include "chrome/browser/ash/login/wizard_context.h"
 #include "chrome/browser/ash/system/timezone_util.h"
@@ -358,6 +359,9 @@
     case update_engine::Operation::FINALIZING:
       if (view_)
         view_->SetUpdateState(UpdateView::UIState::kUpdateInProgress);
+      // set that critcial update applied in OOBE.
+      g_browser_process->local_state()->SetBoolean(prefs::kOobeCriticalUpdate,
+                                                   true);
       SetUpdateStatusMessage(update_info.better_update_progress,
                              update_info.total_time_left);
       // Make sure that VERIFYING and FINALIZING stages are recorded correctly.
@@ -528,7 +532,7 @@
     return false;
   auto country = system::GetCountryCodeFromTimezoneIfAvailable(
       g_browser_process->local_state()->GetString(
-          prefs::kSigninScreenTimezone));
+          ::prefs::kSigninScreenTimezone));
   if (!country.has_value()) {
     return false;
   }
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc
index db45519f..bab292f 100644
--- a/chrome/browser/ash/login/session/user_session_manager.cc
+++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -15,6 +15,7 @@
 
 #include "ash/components/arc/arc_prefs.h"
 #include "ash/constants/ash_features.h"
+#include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
 #include "base/base_paths.h"
 #include "base/command_line.h"
@@ -520,6 +521,42 @@
   known_user.SaveKnownUser(account_id);
 }
 
+// Returns true if current browser instance was restarted in-session.
+// I.e. restart after crash, restart to apply flags, etc.
+bool IsAfterInSessionRestart() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      ash::switches::kLoginUser);
+}
+
+void MaybeSaveSessionStartedTimeBeforeRestart(Profile* profile) {
+  // Ignore if the browser restarted after crash.
+  if (IsAfterInSessionRestart()) {
+    return;
+  }
+
+  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+  if (!user_manager) {
+    return;
+  }
+
+  PrefService* prefs = profile->GetPrefs();
+  prefs->ClearPref(ash::prefs::kAshLoginSessionStartedTime);
+  prefs->ClearPref(ash::prefs::kAshLoginSessionStartedIsFirstSession);
+
+  const user_manager::User* user =
+      ProfileHelper::Get()->GetUserByProfile(profile);
+
+  if (user_manager->GetPrimaryUser() != user) {
+    return;
+  }
+
+  // Record session started time before trying to restart.
+  prefs->SetTime(ash::prefs::kAshLoginSessionStartedTime, base::Time::Now());
+  if (user_manager->IsCurrentUserNew()) {
+    prefs->SetBoolean(ash::prefs::kAshLoginSessionStartedIsFirstSession, true);
+  }
+}
+
 }  // namespace
 
 UserSessionManagerDelegate::~UserSessionManagerDelegate() {}
@@ -967,6 +1004,8 @@
     return false;
   }
 
+  MaybeSaveSessionStartedTimeBeforeRestart(profile);
+
   // Kiosk sessions keeps the startup flags.
   if (user_manager::UserManager::Get() &&
       user_manager::UserManager::Get()->IsLoggedInAsKioskApp()) {
diff --git a/chrome/browser/ash/login/startup_utils.cc b/chrome/browser/ash/login/startup_utils.cc
index d6d932c..5ca4f5f 100644
--- a/chrome/browser/ash/login/startup_utils.cc
+++ b/chrome/browser/ash/login/startup_utils.cc
@@ -104,6 +104,7 @@
   registry->RegisterBooleanPref(kDisableHIDDetectionScreenForTests, false);
   registry->RegisterBooleanPref(prefs::kOobeGuestMetricsEnabled, false);
   registry->RegisterBooleanPref(prefs::kOobeGuestAcceptedTos, false);
+  registry->RegisterBooleanPref(prefs::kOobeCriticalUpdate, false);
   if (switches::IsRevenBranding()) {
     registry->RegisterBooleanPref(prefs::kOobeRevenUpdatedToFlex, false);
   }
diff --git a/chrome/browser/ash/login/ui/login_display_host_webui.cc b/chrome/browser/ash/login/ui/login_display_host_webui.cc
index a93d0430..b540f3b9 100644
--- a/chrome/browser/ash/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/ash/login/ui/login_display_host_webui.cc
@@ -781,8 +781,12 @@
     LOG(WARNING) << "LoginDisplayHostWebUI::OnCurrentScreenChanged() "
                     "NotifyLoginOrLockScreenVisible";
 
-    // Notify that the OOBE page is ready and the first screen is shown.
-    session_manager::SessionManager::Get()->NotifyLoginOrLockScreenVisible();
+    // Notify that the OOBE page is ready and the first screen is shown. It
+    // might happen that front-end part isn't fully initialized yet (when
+    // `OobeLazyLoading` is enabled), so wait for it to happen before notifying.
+    GetOobeUI()->IsJSReady(base::BindOnce(
+        &session_manager::SessionManager::NotifyLoginOrLockScreenVisible,
+        base::Unretained(session_manager::SessionManager::Get())));
   } else {
     // TODO(crbug.com/1305245) - Remove once the issue is fixed.
     LOG(WARNING) << "LoginDisplayHostWebUI::OnCurrentScreenChanged() Not "
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc
index 928b1c2..734c994 100644
--- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc
+++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc
@@ -292,14 +292,10 @@
 
 void DeviceCloudPolicyManagerAsh::OnUserManagerWillBeDestroyed(
     user_manager::UserManager* user_manager) {
-  // Several instances internally hold the reference to the
+  // DeviceStatusCollector internally holds the reference to the
   // ReportingUserTracker instance, so should be released via Shutdown()
   // before this is reached.
   DCHECK(!status_uploader_);
-  DCHECK(!login_logout_reporter_);
-  DCHECK(!user_added_removed_reporter_);
-  DCHECK(!lock_unlock_reporter_);
-
   reporting_user_tracker_.reset();
   user_manager_observation_.Reset();
 }
@@ -387,18 +383,17 @@
 
   managed_session_service_ = std::make_unique<ManagedSessionService>();
   login_logout_reporter_ = ash::reporting::LoginLogoutReporter::Create(
-      reporting_user_tracker_.get(), managed_session_service_.get());
+      managed_session_service_.get());
 
   user_added_removed_reporter_ = ::reporting::UserAddedRemovedReporter::Create(
-      std::move(users_to_be_removed_), reporting_user_tracker_.get(),
-      managed_session_service_.get());
+      std::move(users_to_be_removed_), managed_session_service_.get());
   for (const auto& [user_email, reason] : removed_users_) {
     user_added_removed_reporter_->ProcessRemovedUser(user_email, reason);
   }
   removed_users_.clear();
 
   lock_unlock_reporter_ = ash::reporting::LockUnlockReporter::Create(
-      reporting_user_tracker_.get(), managed_session_service_.get());
+      managed_session_service_.get());
 }
 
 }  // namespace policy
diff --git a/chrome/browser/ash/policy/remote_commands/curtain_mode_chromeos_browsertest.cc b/chrome/browser/ash/policy/remote_commands/curtain_mode_chromeos_browsertest.cc
index 06f9cc5b..cef3938 100644
--- a/chrome/browser/ash/policy/remote_commands/curtain_mode_chromeos_browsertest.cc
+++ b/chrome/browser/ash/policy/remote_commands/curtain_mode_chromeos_browsertest.cc
@@ -17,6 +17,7 @@
 #include "base/test/bind.h"
 #include "base/test/test_future.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
 #include "remoting/host/curtain_mode_chromeos.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -35,7 +36,7 @@
 
 bool ArePixelTestsEnabled() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
-      "browser-ui-tests-verify-pixels");
+      switches::kVerifyPixels);
 }
 
 std::string GetScreenshotName(ColorScheme color_scheme) {
diff --git a/chrome/browser/ash/policy/reporting/os_updates/os_updates_reporter_unittest.cc b/chrome/browser/ash/policy/reporting/os_updates/os_updates_reporter_unittest.cc
index b9679e6..8bf3672 100644
--- a/chrome/browser/ash/policy/reporting/os_updates/os_updates_reporter_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/os_updates/os_updates_reporter_unittest.cc
@@ -82,7 +82,8 @@
 
     auto reporter_helper =
         std::make_unique<::reporting::UserEventReporterHelperTesting>(
-            reporting_enabled, /*is_kiosk_user=*/false, std::move(mock_queue));
+            reporting_enabled, /*should_report_user=*/true,
+            /*is_kiosk_user=*/false, std::move(mock_queue));
     return reporter_helper;
   }
 
diff --git a/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl.cc b/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl.cc
index 68f0fd0..6487e7a 100644
--- a/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl.cc
+++ b/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl.cc
@@ -9,11 +9,7 @@
 #include "base/memory/ref_counted_delete_on_sequence.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/task/sequenced_task_runner.h"
-#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
-#include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_process_platform_part_ash.h"
 #include "chrome/browser/policy/messaging_layer/proto/synced/crd_event.pb.h"
 #include "chromeos/ash/components/settings/cros_settings_names.h"
 #include "components/reporting/proto/synced/record_constants.pb.h"
@@ -23,12 +19,10 @@
 
 // Production implementation of CRD event reporter for remoting host.
 HostEventReporterDelegateImpl::HostEventReporterDelegateImpl(
-    std::unique_ptr<::reporting::UserEventReporterHelper> user_event_helper,
-    policy::ReportingUserTracker* reporting_user_tracker)
+    std::unique_ptr<::reporting::UserEventReporterHelper> user_event_helper)
     : helper_(base::MakeRefCounted<Helper>(
           ::reporting::UserEventReporterHelper::valid_task_runner(),
-          std::move(user_event_helper),
-          reporting_user_tracker)) {}
+          std::move(user_event_helper))) {}
 
 HostEventReporterDelegateImpl::~HostEventReporterDelegateImpl() = default;
 
@@ -40,12 +34,10 @@
  public:
   Helper(
       scoped_refptr<base::SequencedTaskRunner> task_runner,
-      std::unique_ptr<::reporting::UserEventReporterHelper> user_event_helper,
-      policy::ReportingUserTracker* reporting_user_tracker)
+      std::unique_ptr<::reporting::UserEventReporterHelper> user_event_helper)
       : base::RefCountedDeleteOnSequence<Helper>(task_runner),
         task_runner_(task_runner),
-        user_event_helper_(std::move(user_event_helper)),
-        reporting_user_tracker_(reporting_user_tracker) {}
+        user_event_helper_(std::move(user_event_helper)) {}
 
   void EnqueueEvent(::ash::reporting::CRDRecord record) {
     task_runner_->PostTask(FROM_HERE, base::BindOnce(&Helper::EnqueueEventSync,
@@ -65,7 +57,7 @@
     if (!user_event_helper_->ReportingEnabled(::ash::kReportCRDSessions)) {
       return;
     }
-    if (!reporting_user_tracker_->ShouldReportUser(
+    if (!user_event_helper_->ShouldReportUser(
             record.host_user().user_email())) {
       record.clear_host_user();  // anonymize host user.
       if (user_event_helper_->IsKioskUser()) {
@@ -83,9 +75,6 @@
   // Helper for posting events.
   const std::unique_ptr<::reporting::UserEventReporterHelper>
       user_event_helper_;
-
-  const base::raw_ptr<policy::ReportingUserTracker, ExperimentalAsh>
-      reporting_user_tracker_;
 };
 
 void HostEventReporterDelegateImpl::EnqueueEvent(
@@ -97,14 +86,6 @@
 std::unique_ptr<HostEventReporter> HostEventReporter::Create(
     scoped_refptr<HostStatusMonitor> monitor) {
   return std::make_unique<HostEventReporterImpl>(
-      monitor, std::make_unique<HostEventReporterDelegateImpl>(
-                   std::make_unique<::reporting::UserEventReporterHelper>(
-                       ::reporting::Destination::CRD_EVENTS,
-                       ::reporting::EventType::kUser),
-                   g_browser_process->platform_part()
-                       ->browser_policy_connector_ash()
-                       ->GetDeviceCloudPolicyManager()
-                       ->reporting_user_tracker()));
+      monitor, std::make_unique<HostEventReporterDelegateImpl>());
 }
-
 }  // namespace remoting
diff --git a/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl.h b/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl.h
index 27107ec0..8811357 100644
--- a/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl.h
+++ b/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl.h
@@ -15,18 +15,16 @@
 #include "components/reporting/proto/synced/record_constants.pb.h"
 #include "remoting/host/chromeos/host_event_reporter_impl.h"
 
-namespace policy {
-class ReportingUserTracker;
-}  // namespace policy
-
 namespace remoting {
 
 // Production implementation of CRD event reporter for remoting host.
 class HostEventReporterDelegateImpl : public HostEventReporterImpl::Delegate {
  public:
-  HostEventReporterDelegateImpl(
-      std::unique_ptr<::reporting::UserEventReporterHelper> user_event_helper,
-      policy::ReportingUserTracker* reporting_user_tracker);
+  explicit HostEventReporterDelegateImpl(
+      std::unique_ptr<::reporting::UserEventReporterHelper> user_event_helper =
+          std::make_unique<::reporting::UserEventReporterHelper>(
+              ::reporting::Destination::CRD_EVENTS,
+              ::reporting::EventType::kUser));
 
   HostEventReporterDelegateImpl(const HostEventReporterDelegateImpl& other) =
       delete;
diff --git a/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl_unittest.cc b/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl_unittest.cc
index 5f913d7e..503181ff 100644
--- a/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/remoting_host_event_reporter_delegate_impl_unittest.cc
@@ -10,13 +10,9 @@
 #include "base/strings/string_piece.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/test/repeating_test_future.h"
-#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
-#include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper.h"
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h"
 #include "chrome/browser/policy/messaging_layer/proto/synced/crd_event.pb.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
-#include "chrome/test/base/testing_browser_process.h"
 #include "components/reporting/client/mock_report_queue.h"
 #include "components/reporting/proto/synced/record_constants.pb.h"
 #include "content/public/test/browser_task_environment.h"
@@ -39,14 +35,9 @@
 // Production implementation of CRD event reporter for remoting host.
 class HostEventReporterDelegateImplTest : public ::testing::Test {
  protected:
-  void SetUp() override {
-    user_manager_ = std::make_unique<ash::FakeChromeUserManager>();
-    reporting_user_tracker_ =
-        std::make_unique<policy::ReportingUserTracker>(user_manager_.get());
-  }
-
   std::unique_ptr<::reporting::UserEventReporterHelperTesting>
   GetReporterHelper(bool reporting_enabled,
+                    bool should_report_user,
                     bool is_kiosk_user,
                     ::reporting::Status status = ::reporting::Status()) {
     auto mock_queue = std::unique_ptr<::reporting::MockReportQueue,
@@ -71,7 +62,8 @@
 
     auto reporter_helper =
         std::make_unique<::reporting::UserEventReporterHelperTesting>(
-            reporting_enabled, is_kiosk_user, std::move(mock_queue));
+            reporting_enabled, should_report_user, is_kiosk_user,
+            std::move(mock_queue));
     return reporter_helper;
   }
 
@@ -79,17 +71,7 @@
 
   bool IsEmpty() const { return records_.IsEmpty(); }
 
-  ash::FakeChromeUserManager* user_manager() { return user_manager_.get(); }
-
-  policy::ReportingUserTracker* reporting_user_tracker() {
-    return reporting_user_tracker_.get();
-  }
-
  private:
-  ScopedTestingLocalState local_state{TestingBrowserProcess::GetGlobal()};
-  std::unique_ptr<ash::FakeChromeUserManager> user_manager_;
-  std::unique_ptr<policy::ReportingUserTracker> reporting_user_tracker_;
-
   content::BrowserTaskEnvironment task_environment;
 
   std::unique_ptr<HostEventReporterImpl::Delegate> delegate_;
@@ -99,11 +81,9 @@
 
 TEST_F(HostEventReporterDelegateImplTest, RegularCrdEvent) {
   static constexpr char kHostUser[] = "user@host.com";
-  user_manager()->AddUserWithAffiliation(AccountId::FromUserEmail(kHostUser),
-                                         /*is_affiliated=*/true);
   HostEventReporterDelegateImpl delegate(
-      GetReporterHelper(/*reporting_enabled=*/true, /*is_kiosk_user=*/false),
-      reporting_user_tracker());
+      GetReporterHelper(/*reporting_enabled=*/true, /*should_report_user=*/true,
+                        /*is_kiosk_user=*/false));
 
   {
     CRDRecord record;
@@ -122,9 +102,8 @@
 TEST_F(HostEventReporterDelegateImplTest, AnonymousCrdEvent) {
   static constexpr char kNonAffiliatedUser[] = "user@alien.com";
   HostEventReporterDelegateImpl delegate(GetReporterHelper(
-                                             /*reporting_enabled=*/true,
-                                             /*is_kiosk_user=*/false),
-                                         reporting_user_tracker());
+      /*reporting_enabled=*/true, /*should_report_user=*/false,
+      /*is_kiosk_user=*/false));
 
   {
     CRDRecord record;
@@ -143,9 +122,8 @@
 TEST_F(HostEventReporterDelegateImplTest, KioskCrdEvent) {
   static constexpr char kKioskUser[] = "user@host.com";
   HostEventReporterDelegateImpl delegate(GetReporterHelper(
-                                             /*reporting_enabled=*/true,
-                                             /*is_kiosk_user=*/true),
-                                         reporting_user_tracker());
+      /*reporting_enabled=*/true, /*should_report_user=*/false,
+      /*is_kiosk_user=*/true));
 
   {
     CRDRecord record;
@@ -164,9 +142,8 @@
 TEST_F(HostEventReporterDelegateImplTest, DisabledCrdEvent) {
   static constexpr char kHostUser[] = "user@host.com";
   HostEventReporterDelegateImpl delegate(GetReporterHelper(
-                                             /*reporting_enabled=*/false,
-                                             /*is_kiosk_user=*/false),
-                                         reporting_user_tracker());
+      /*reporting_enabled=*/false, /*should_report_user=*/true,
+      /*is_kiosk_user=*/false));
   {
     CRDRecord record;
     record.mutable_host_user()->set_user_email(kHostUser);
@@ -178,12 +155,10 @@
 
 TEST_F(HostEventReporterDelegateImplTest, ErrorPostingCrdEvent) {
   static constexpr char kHostUser[] = "user@host.com";
-  HostEventReporterDelegateImpl delegate(
-      GetReporterHelper(
-          /*reporting_enabled=*/true,
-          /*is_kiosk_user=*/false,
-          ::reporting::Status(::reporting::error::INTERNAL, "")),
-      reporting_user_tracker());
+  HostEventReporterDelegateImpl delegate(GetReporterHelper(
+      /*reporting_enabled=*/true, /*should_report_user=*/true,
+      /*is_kiosk_user=*/false,
+      ::reporting::Status(::reporting::error::INTERNAL, "")));
   {
     CRDRecord record;
     record.mutable_host_user()->set_user_email(kHostUser);
diff --git a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.cc b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.cc
index 61820346a..ee1dd50 100644
--- a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.cc
+++ b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.cc
@@ -8,7 +8,6 @@
 
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
-#include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part_ash.h"
@@ -23,13 +22,11 @@
 // static
 std::unique_ptr<UserAddedRemovedReporter> UserAddedRemovedReporter::Create(
     base::flat_map<AccountId, bool> users_to_be_removed,
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service) {
   return base::WrapUnique(new UserAddedRemovedReporter(
       std::make_unique<UserEventReporterHelper>(
           Destination::ADDED_REMOVED_EVENTS),
-      std::move(users_to_be_removed), reporting_user_tracker,
-      managed_session_service));
+      std::move(users_to_be_removed), managed_session_service));
 }
 
 // static
@@ -37,10 +34,9 @@
 UserAddedRemovedReporter::CreateForTesting(
     std::unique_ptr<UserEventReporterHelper> helper,
     base::flat_map<AccountId, bool> users_to_be_removed,
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service) {
   return base::WrapUnique(new UserAddedRemovedReporter(
-      std::move(helper), std::move(users_to_be_removed), reporting_user_tracker,
+      std::move(helper), std::move(users_to_be_removed),
       managed_session_service));
 }
 
@@ -77,7 +73,7 @@
   auto email = user->GetAccountId().GetUserEmail();
   auto record = std::make_unique<UserAddedRemovedRecord>();
   record->mutable_user_added_event();
-  if (reporting_user_tracker_->ShouldReportUser(email)) {
+  if (helper_->ShouldReportUser(email)) {
     record->mutable_affiliated_user()->set_user_email(email);
   }
   record->set_event_timestamp_sec(base::Time::Now().ToTimeT());
@@ -98,8 +94,8 @@
   }
 
   const std::string email = account_id.GetUserEmail();
-  users_to_be_removed_.insert_or_assign(
-      account_id, reporting_user_tracker_->ShouldReportUser(email));
+  users_to_be_removed_.insert_or_assign(account_id,
+                                        helper_->ShouldReportUser(email));
 }
 
 void UserAddedRemovedReporter::OnUserRemoved(
@@ -124,11 +120,9 @@
 UserAddedRemovedReporter::UserAddedRemovedReporter(
     std::unique_ptr<UserEventReporterHelper> helper,
     base::flat_map<AccountId, bool> users_to_be_removed,
-    policy::ReportingUserTracker* reporting_user_tracker,
     policy::ManagedSessionService* managed_session_service)
     : helper_(std::move(helper)),
-      users_to_be_removed_(std::move(users_to_be_removed)),
-      reporting_user_tracker_(reporting_user_tracker) {
+      users_to_be_removed_(std::move(users_to_be_removed)) {
   managed_session_observation_.Observe(managed_session_service);
 }
 
diff --git a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.h b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.h
index 31d686c..54893c6 100644
--- a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.h
+++ b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.h
@@ -14,10 +14,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "components/reporting/client/report_queue_provider.h"
 
-namespace policy {
-class ReportingUserTracker;
-}  // namespace policy
-
 namespace reporting {
 
 // This class is used to report events when a user it added or removed to a
@@ -30,14 +26,12 @@
   // For prod. Uses the default implementation of UserEventReporterHelper.
   static std::unique_ptr<UserAddedRemovedReporter> Create(
       base::flat_map<AccountId, bool> users_to_be_removed,
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service);
 
   // For use in testing only. Allows user to pass in a test helper.
   static std::unique_ptr<UserAddedRemovedReporter> CreateForTesting(
       std::unique_ptr<UserEventReporterHelper> helper,
       base::flat_map<AccountId, bool> users_to_be_removed,
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service);
 
   UserAddedRemovedReporter(const UserAddedRemovedReporter& other) = delete;
@@ -68,7 +62,6 @@
   UserAddedRemovedReporter(
       std::unique_ptr<UserEventReporterHelper> helper,
       base::flat_map<AccountId, bool> users_to_be_removed,
-      policy::ReportingUserTracker* reporting_user_tracker,
       policy::ManagedSessionService* managed_session_service);
 
   std::unique_ptr<UserEventReporterHelper> helper_;
@@ -77,9 +70,6 @@
   // if their email may be reported.
   base::flat_map<AccountId, bool> users_to_be_removed_;
 
-  const base::raw_ptr<policy::ReportingUserTracker, ExperimentalAsh>
-      reporting_user_tracker_;
-
   base::ScopedObservation<policy::ManagedSessionService,
                           policy::ManagedSessionService::Observer>
       managed_session_observation_{this};
diff --git a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_unittest.cc b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_unittest.cc
index aad7f23..424335e 100644
--- a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_unittest.cc
@@ -15,12 +15,9 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/test/task_environment.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
-#include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/policy/status_collector/managed_session_service.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/policy/messaging_layer/proto/synced/add_remove_user_event.pb.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
-#include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "components/reporting/client/mock_report_queue.h"
@@ -38,12 +35,18 @@
                              base::OnTaskRunnerDeleter> report_queue,
              base::WeakPtr<::reporting::MockReportQueueStrict> mock_queue,
              bool should_report_event,
+             bool should_report_user,
              bool is_user_new)
       : UserEventReporterHelper(std::move(report_queue)),
         mock_queue_(mock_queue),
         should_report_event_(should_report_event),
+        should_report_user_(should_report_user),
         is_user_new_(is_user_new) {}
 
+  bool ShouldReportUser(const std::string& user_email) const override {
+    return should_report_user_;
+  }
+
   bool ReportingEnabled(const std::string& policy_path) const override {
     return should_report_event_;
   }
@@ -62,6 +65,8 @@
 
   bool should_report_event_;
 
+  bool should_report_user_;
+
   bool is_user_new_;
 
   bool event_reported_;
@@ -77,35 +82,28 @@
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         std::move(user_manager));
 
-    reporting_user_tracker_ =
-        std::make_unique<policy::ReportingUserTracker>(user_manager_);
-
     mock_queue_ = new ::reporting::MockReportQueueStrict();
     weak_mock_queue_factory_ = std::make_unique<
         base::WeakPtrFactory<::reporting::MockReportQueueStrict>>(mock_queue_);
   }
 
   void TearDown() override {
-    reporting_user_tracker_.reset();
-    user_manager_enabler_.reset();
     chromeos::PowerManagerClient::Shutdown();
     delete mock_queue_;
   }
 
   std::unique_ptr<TestingProfile> LoginRegularProfile(
       base::StringPiece user_email,
-      bool is_affiliated,
       policy::ManagedSessionService* managed_session_service) {
     const AccountId account_id =
         AccountId::FromUserEmail(std::string(user_email));
     TestingProfile::Builder profile_builder;
     profile_builder.SetProfileName(account_id.GetUserEmail());
     auto profile = profile_builder.Build();
-    user_manager_->AddUserWithAffiliationAndTypeAndProfile(
-        account_id, is_affiliated, user_manager::USER_TYPE_REGULAR,
-        profile.get());
-
+    auto* const user = user_manager_->AddUser(account_id);
     user_manager_->LoginUser(account_id, true);
+    ash::ProfileHelper::Get()->SetUserToProfileMappingForTesting(user,
+                                                                 profile.get());
     managed_session_service->OnUserProfileLoaded(account_id);
     return profile;
   }
@@ -142,19 +140,11 @@
   std::unique_ptr<base::WeakPtrFactory<::reporting::MockReportQueueStrict>>
       weak_mock_queue_factory_;
 
-  policy::ReportingUserTracker* reporting_user_tracker() {
-    return reporting_user_tracker_.get();
-  }
-
  private:
-  ScopedTestingLocalState local_state{TestingBrowserProcess::GetGlobal()};
-
   raw_ptr<ash::FakeChromeUserManager, ExperimentalAsh> user_manager_;
 
   std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
 
-  std::unique_ptr<policy::ReportingUserTracker> reporting_user_tracker_;
-
   content::BrowserTaskEnvironment task_environment_;
 };
 
@@ -180,16 +170,15 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/true);
+                                   /*report_user=*/true, /*user_new=*/true);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
-  LoginRegularProfile(user_email, /*is_affiliated=*/true,
-                      managed_session_service.get());
+  LoginRegularProfile(user_email, managed_session_service.get());
 
   EXPECT_THAT(priority, testing::Eq(::reporting::Priority::IMMEDIATE));
   EXPECT_TRUE(record.has_event_timestamp_sec());
@@ -220,16 +209,15 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/true);
+                                   /*report_user=*/false, /*user_new=*/true);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
-  LoginRegularProfile(user_email, /*is_affiliated=*/false,
-                      managed_session_service.get());
+  LoginRegularProfile(user_email, managed_session_service.get());
 
   EXPECT_THAT(priority, testing::Eq(::reporting::Priority::IMMEDIATE));
   EXPECT_TRUE(record.has_event_timestamp_sec());
@@ -252,16 +240,15 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/false,
-                                   /*user_new=*/true);
+                                   /*report_user=*/true, /*user_new=*/true);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
-  auto profile = LoginRegularProfile(user_email, /*is_affiliated=*/true,
-                                     managed_session_service.get());
+  auto profile = LoginRegularProfile(user_email, managed_session_service.get());
   managed_session_service->OnUserToBeRemoved(account_id);
   managed_session_service->OnUserRemoved(
       account_id, user_manager::UserRemovalReason::GAIA_REMOVED);
@@ -279,16 +266,15 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/false);
+                                   /*report_user=*/true, /*user_new=*/false);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
-  LoginRegularProfile(user_email, /*is_affiliated=*/true,
-                      managed_session_service.get());
+  LoginRegularProfile(user_email, managed_session_service.get());
 }
 
 TEST_F(UserAddedRemovedReporterTest, TestGuestSessionLogsIn) {
@@ -302,13 +288,13 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/true);
+                                   /*report_user=*/true, /*user_new=*/true);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
   LoginGuestProfile(managed_session_service.get());
 }
@@ -327,13 +313,13 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/true);
+                                   /*report_user=*/true, /*user_new=*/true);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
   LoginKioskProfile(user_email, managed_session_service.get());
 }
@@ -362,16 +348,15 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/false);
+                                   /*report_user=*/true, /*user_new=*/false);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
-  auto profile = LoginRegularProfile(user_email, /*is_affiliated=*/true,
-                                     managed_session_service.get());
+  auto profile = LoginRegularProfile(user_email, managed_session_service.get());
   managed_session_service->OnUserToBeRemoved(account_id);
   managed_session_service->OnUserRemoved(
       account_id, user_manager::UserRemovalReason::GAIA_REMOVED);
@@ -410,16 +395,15 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/false);
+                                   /*report_user=*/false, /*user_new=*/false);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
-  auto profile = LoginRegularProfile(user_email, /*is_affiliated=*/false,
-                                     managed_session_service.get());
+  auto profile = LoginRegularProfile(user_email, managed_session_service.get());
   managed_session_service->OnUserToBeRemoved(account_id);
   managed_session_service->OnUserRemoved(
       account_id, user_manager::UserRemovalReason::GAIA_REMOVED);
@@ -446,13 +430,13 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/true);
+                                   /*report_user=*/true, /*user_new=*/true);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
 
   auto profile = LoginKioskProfile(user_email, managed_session_service.get());
   managed_session_service->OnUserToBeRemoved(account_id);
@@ -483,13 +467,13 @@
   auto test_helper =
       std::make_unique<TestHelper>(std::move(dummy_queue), mock_queue,
                                    /*report_event=*/true,
-                                   /*user_new=*/true);
+                                   /*report_user=*/false, /*user_new=*/true);
   auto managed_session_service =
       std::make_unique<policy::ManagedSessionService>();
 
   auto reporter = UserAddedRemovedReporter::CreateForTesting(
       std::move(test_helper), /*users_to_be_removed=*/{},
-      reporting_user_tracker(), managed_session_service.get());
+      managed_session_service.get());
   reporter->ProcessRemovedUser(
       user_email, user_manager::UserRemovalReason::REMOTE_ADMIN_INITIATED);
 
diff --git a/chrome/browser/ash/policy/reporting/user_event_reporter_helper.cc b/chrome/browser/ash/policy/reporting/user_event_reporter_helper.cc
index a0d61e07..d23aa610 100644
--- a/chrome/browser/ash/policy/reporting/user_event_reporter_helper.cc
+++ b/chrome/browser/ash/policy/reporting/user_event_reporter_helper.cc
@@ -13,6 +13,8 @@
 #include "chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h"
 #include "chrome/browser/ash/policy/core/reporting_user_tracker.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part_ash.h"
 #include "components/reporting/client/report_queue_factory.h"
 #include "components/reporting/util/status.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -33,6 +35,15 @@
 
 UserEventReporterHelper::~UserEventReporterHelper() = default;
 
+bool UserEventReporterHelper::ShouldReportUser(const std::string& email) const {
+  DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
+  auto* reporting_user_tracker = g_browser_process->platform_part()
+                                     ->browser_policy_connector_ash()
+                                     ->GetDeviceCloudPolicyManager()
+                                     ->reporting_user_tracker();
+  return reporting_user_tracker->ShouldReportUser(email);
+}
+
 bool UserEventReporterHelper::ReportingEnabled(
     const std::string& policy_path) const {
   DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
@@ -79,5 +90,4 @@
              << status;
   }
 }
-
 }  // namespace reporting
diff --git a/chrome/browser/ash/policy/reporting/user_event_reporter_helper.h b/chrome/browser/ash/policy/reporting/user_event_reporter_helper.h
index fc73e24..615d1df5 100644
--- a/chrome/browser/ash/policy/reporting/user_event_reporter_helper.h
+++ b/chrome/browser/ash/policy/reporting/user_event_reporter_helper.h
@@ -39,6 +39,11 @@
       delete;
   virtual ~UserEventReporterHelper();
 
+  // DEPRECATED: please use ReportingUserTracker::ShouldReport() by passing
+  // its instance from DeviceCloudPolicyManagerAsh.
+  // TODO(b/267685577): Remove this.
+  virtual bool ShouldReportUser(const std::string& user_email) const;
+
   // Returns whether the provided reporting policy is set.
   // Must be called on UI task runner (returned by valid_task_runner() below).
   virtual bool ReportingEnabled(const std::string& policy_path) const;
diff --git a/chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.cc b/chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.cc
index 4e5710a..eaaccd4 100644
--- a/chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.cc
+++ b/chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.cc
@@ -10,10 +10,12 @@
 
 UserEventReporterHelperTesting::UserEventReporterHelperTesting(
     bool reporting_enabled,
+    bool should_report_user,
     bool is_kiosk_user,
     std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter> report_queue)
     : UserEventReporterHelper(std::move(report_queue)),
       reporting_enabled_(reporting_enabled),
+      should_report_user_(should_report_user),
       is_kiosk_user_(is_kiosk_user) {}
 
 bool UserEventReporterHelperTesting::ReportingEnabled(
@@ -21,6 +23,11 @@
   return reporting_enabled_;
 }
 
+bool UserEventReporterHelperTesting::ShouldReportUser(
+    const std::string&) const {
+  return should_report_user_;
+}
+
 bool UserEventReporterHelperTesting::IsKioskUser() const {
   return is_kiosk_user_;
 }
diff --git a/chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h b/chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h
index e9455b9..d7528470 100644
--- a/chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h
+++ b/chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h
@@ -13,16 +13,20 @@
  public:
   UserEventReporterHelperTesting(
       bool reporting_enabled,
+      bool should_report_user,
       bool is_kiosk_user,
       std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter> report_queue);
   ~UserEventReporterHelperTesting() override;
 
   bool ReportingEnabled(const std::string&) const override;
 
+  bool ShouldReportUser(const std::string&) const override;
+
   bool IsKioskUser() const override;
 
  private:
   const bool reporting_enabled_;
+  const bool should_report_user_;
   const bool is_kiosk_user_;
 };
 }  // namespace reporting
diff --git a/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc b/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc
index dcf710f..be35ebc0 100644
--- a/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc
+++ b/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc
@@ -96,7 +96,7 @@
       auto file_url = apps::GetFileSystemURL(profile_, file->url);
       // TODO(crbug.com/1274983) : Add support for copying from MTP and
       // FileSystemProviders.
-      if (!file_manager::util::IsNonNativeFileSystemType(file_url.type())) {
+      if (file_url.TypeImpliesPathIsReal()) {
         file_infos.emplace_back(
             ui::FileInfo(file_url.path(), base::FilePath()));
       }
@@ -129,8 +129,7 @@
   if (!intent->files.empty()) {
     for (const auto& file : intent->files) {
       auto file_url = apps::GetFileSystemURL(profile_, file->url);
-      contains_uncopyable_file =
-          file_manager::util::IsNonNativeFileSystemType(file_url.type());
+      contains_uncopyable_file = !file_url.TypeImpliesPathIsReal();
       if (contains_uncopyable_file) {
         break;
       }
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
index bd5858f..fcc1e86 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
@@ -29,6 +29,7 @@
 #include "chromeos/ui/base/window_properties.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/render_widget_host_view.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -324,7 +325,7 @@
 
   bool IsExperimentalBrowserPixelTestEnabled() {
     return base::CommandLine::ForCurrentProcess()->HasSwitch(
-        "browser-ui-tests-verify-pixels");
+        switches::kVerifyPixels);
   }
 
   void PrepareUi() {
diff --git a/chrome/browser/ash/web_applications/shortcut_customization_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/shortcut_customization_app_integration_browsertest.cc
index ed70c0e..1d80c58 100644
--- a/chrome/browser/ash/web_applications/shortcut_customization_app_integration_browsertest.cc
+++ b/chrome/browser/ash/web_applications/shortcut_customization_app_integration_browsertest.cc
@@ -43,9 +43,8 @@
 IN_PROC_BROWSER_TEST_P(ShortcutCustomizationAppIntegrationTest,
                        ShortcutCustomizationAppInLauncher) {
   const GURL url(ash::kChromeUIShortcutCustomizationAppURL);
-  EXPECT_NO_FATAL_FAILURE(
-      ExpectSystemWebAppValid(ash::SystemWebAppType::SHORTCUT_CUSTOMIZATION,
-                              url, "Keyboard shortcuts"));
+  EXPECT_NO_FATAL_FAILURE(ExpectSystemWebAppValid(
+      ash::SystemWebAppType::SHORTCUT_CUSTOMIZATION, url, "Key Shortcuts"));
 
   histogram_tester_.ExpectBucketCount(
       "Webapp.InstallResult.System.Apps.ShortcutCustomization",
diff --git a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
index 710d8fa..a8f241a 100644
--- a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
+++ b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
@@ -59,7 +59,6 @@
 constexpr base::Time kTime2 =
     base::Time::FromDeltaSinceWindowsEpoch(base::Days(2));
 
-constexpr size_t kTaxonomySize = 349;
 constexpr int kTaxonomyVersion = 1;
 constexpr int64_t kModelVersion = 2;
 constexpr size_t kPaddedTopTopicsStartIndex = 5;
@@ -91,8 +90,8 @@
   }
 
   return EpochTopics(std::move(top_topics_and_observing_domains),
-                     kPaddedTopTopicsStartIndex, kTaxonomySize,
-                     kTaxonomyVersion, kModelVersion, calculation_time);
+                     kPaddedTopTopicsStartIndex, kTaxonomyVersion,
+                     kModelVersion, calculation_time);
 }
 
 class PortalActivationWaiter : public content::WebContentsObserver {
diff --git a/chrome/browser/chromeos/app_mode/DEPS b/chrome/browser/chromeos/app_mode/DEPS
index 73c2374..90be68e 100644
--- a/chrome/browser/chromeos/app_mode/DEPS
+++ b/chrome/browser/chromeos/app_mode/DEPS
@@ -19,5 +19,6 @@
     "+ash/session/session_controller_impl.h",
     "+ash/shell.h",
     "+ash/test/ash_test_helper.h",
+    "+ash/wm/overview/overview_controller.h"
   ],
 }
\ No newline at end of file
diff --git a/chrome/browser/chromeos/app_mode/app_session_unittest.cc b/chrome/browser/chromeos/app_mode/app_session_unittest.cc
index afd8f87..46b942f 100644
--- a/chrome/browser/chromeos/app_mode/app_session_unittest.cc
+++ b/chrome/browser/chromeos/app_mode/app_session_unittest.cc
@@ -41,6 +41,7 @@
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_helper.h"
+#include "ash/wm/overview/overview_controller.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/keycodes/keyboard_codes_posix.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -192,7 +193,6 @@
 
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     ash_test_helper_.SetUp(ash::AshTestHelper::InitParams());
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -988,19 +988,25 @@
     ash::Shell::Get()->session_controller()->SetSessionInfo(info);
   }
 
-  bool is_new_window_called() const {
+  bool IsOverviewToggled() const {
+    ash::OverviewController* overview_controller =
+        ash::Shell::Get()->overview_controller();
+    return overview_controller->InOverviewSession();
+  }
+
+  bool IsNewWindowCalled() const {
     return fake_new_window_delegate_->is_new_window_called();
   }
 
-  bool is_new_tab_called() const {
+  bool IsNewTabCalled() const {
     return fake_new_window_delegate_->is_new_tab_called();
   }
 
-  bool is_task_manager_called() const {
+  bool IsTaskManagerCalled() const {
     return fake_new_window_delegate_->is_task_manager_called();
   }
 
-  bool is_open_feedback_page_called() const {
+  bool IsOpenFeedbackPageCalled() const {
     return fake_new_window_delegate_->is_open_feedback_page_called();
   }
 
@@ -1011,6 +1017,8 @@
       ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN);
   ui::Accelerator open_feedback_page_accelerator =
       ui::Accelerator(ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
+  ui::Accelerator toggle_overview_accelerator =
+      ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE);
 
  private:
   raw_ptr<FakeNewWindowDelegate> fake_new_window_delegate_;
@@ -1023,7 +1031,7 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/true);
 
   ProcessInController(new_window_accelerator);
-  EXPECT_TRUE(is_new_window_called());
+  EXPECT_TRUE(IsNewWindowCalled());
 }
 
 // Just confirm that other shortcuts (e.g. new tab) do not work.
@@ -1032,8 +1040,8 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/true);
 
   ProcessInController(ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN));
-  EXPECT_FALSE(is_new_tab_called());
-  EXPECT_FALSE(is_new_window_called());
+  EXPECT_FALSE(IsNewTabCalled());
+  EXPECT_FALSE(IsNewWindowCalled());
 }
 
 TEST_P(AppSessionTroubleshootingShortcutsTest,
@@ -1041,7 +1049,7 @@
   SetUpKioskSession();
 
   ProcessInController(new_window_accelerator);
-  EXPECT_FALSE(is_new_window_called());
+  EXPECT_FALSE(IsNewWindowCalled());
 }
 
 TEST_P(AppSessionTroubleshootingShortcutsTest,
@@ -1050,7 +1058,7 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/false);
 
   ProcessInController(new_window_accelerator);
-  EXPECT_FALSE(is_new_window_called());
+  EXPECT_FALSE(IsNewWindowCalled());
 }
 
 TEST_P(AppSessionTroubleshootingShortcutsTest, TaskManagerShortcutEnabled) {
@@ -1058,7 +1066,7 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/true);
 
   ProcessInController(task_manager_accelerator);
-  EXPECT_TRUE(is_task_manager_called());
+  EXPECT_TRUE(IsTaskManagerCalled());
 }
 
 TEST_P(AppSessionTroubleshootingShortcutsTest,
@@ -1066,7 +1074,7 @@
   SetUpKioskSession();
 
   ProcessInController(task_manager_accelerator);
-  EXPECT_FALSE(is_task_manager_called());
+  EXPECT_FALSE(IsTaskManagerCalled());
 }
 
 TEST_P(AppSessionTroubleshootingShortcutsTest,
@@ -1075,7 +1083,7 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/false);
 
   ProcessInController(task_manager_accelerator);
-  EXPECT_FALSE(is_task_manager_called());
+  EXPECT_FALSE(IsTaskManagerCalled());
 }
 
 TEST_P(AppSessionTroubleshootingShortcutsTest,
@@ -1084,7 +1092,7 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/true);
 
   ProcessInController(open_feedback_page_accelerator);
-  EXPECT_TRUE(is_open_feedback_page_called());
+  EXPECT_TRUE(IsOpenFeedbackPageCalled());
 }
 
 TEST_P(AppSessionTroubleshootingShortcutsTest,
@@ -1092,7 +1100,7 @@
   SetUpKioskSession();
 
   ProcessInController(open_feedback_page_accelerator);
-  EXPECT_FALSE(is_open_feedback_page_called());
+  EXPECT_FALSE(IsOpenFeedbackPageCalled());
 }
 
 TEST_P(AppSessionTroubleshootingShortcutsTest,
@@ -1101,7 +1109,32 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/false);
 
   ProcessInController(open_feedback_page_accelerator);
-  EXPECT_FALSE(is_open_feedback_page_called());
+  EXPECT_FALSE(IsOpenFeedbackPageCalled());
+}
+
+TEST_P(AppSessionTroubleshootingShortcutsTest, ToggleOverviewShortcutEnabled) {
+  SetUpKioskSession();
+  UpdateTroubleshootingToolsPolicy(/*enable=*/true);
+
+  ProcessInController(toggle_overview_accelerator);
+  EXPECT_TRUE(IsOverviewToggled());
+}
+
+TEST_P(AppSessionTroubleshootingShortcutsTest,
+       ToggleOverviewShortcutNoActionByDefault) {
+  SetUpKioskSession();
+
+  ProcessInController(toggle_overview_accelerator);
+  EXPECT_FALSE(IsOverviewToggled());
+}
+
+TEST_P(AppSessionTroubleshootingShortcutsTest,
+       ToggleOverviewShortcutNoActionIfPolicyDisabled) {
+  SetUpKioskSession();
+  UpdateTroubleshootingToolsPolicy(/*enable=*/false);
+
+  ProcessInController(toggle_overview_accelerator);
+  EXPECT_FALSE(IsOverviewToggled());
 }
 
 INSTANTIATE_TEST_SUITE_P(AppSessionTroubleshootingShortcuts,
diff --git a/chrome/browser/chromeos/app_mode/kiosk_troubleshooting_controller_ash.cc b/chrome/browser/chromeos/app_mode/kiosk_troubleshooting_controller_ash.cc
index cb23c38..7f1049f 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_troubleshooting_controller_ash.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_troubleshooting_controller_ash.cc
@@ -29,13 +29,15 @@
 
 bool KioskTroubleshootingControllerAsh::AcceleratorPressed(
     const ui::Accelerator& accelerator) {
-  // Do not process any accelerators if troubleshooting tools are disabled.
-  if (!AreKioskTroubleshootingToolsEnabled()) {
+  auto it = accelerators_with_actions_.find(accelerator);
+  if (it == accelerators_with_actions_.end()) {
     return false;
   }
 
-  auto it = accelerators_with_actions_.find(accelerator);
-  DCHECK(it != accelerators_with_actions_.end());
+  // Block registered accelerators if the troubleshooting tools are disabled.
+  if (!AreKioskTroubleshootingToolsEnabled()) {
+    return true;
+  }
 
   switch (it->second) {
     case TroubleshootingAcceleratorAction::NEW_WINDOW:
@@ -53,13 +55,16 @@
     case TroubleshootingAcceleratorAction::OPEN_FEEDBACK_PAGE:
       accelerators::OpenFeedbackPage();
       return true;
+    case TroubleshootingAcceleratorAction::TOGGLE_OVERVIEW:
+      accelerators::ToggleOverview();
+      return true;
   }
 
   return false;
 }
 
 bool KioskTroubleshootingControllerAsh::CanHandleAccelerators() const {
-  return AreKioskTroubleshootingToolsEnabled();
+  return true;
 }
 
 void KioskTroubleshootingControllerAsh::RegisterTroubleshootingAccelerators() {
@@ -87,6 +92,10 @@
   accelerators_with_actions_.insert(
       {ui::Accelerator(ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN),
        TroubleshootingAcceleratorAction::OPEN_FEEDBACK_PAGE});
+  // F5
+  accelerators_with_actions_.insert(
+      {ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE),
+       TroubleshootingAcceleratorAction::TOGGLE_OVERVIEW});
   Shell::Get()->accelerator_controller()->Register(GetAllAccelerators(), this);
 }
 
diff --git a/chrome/browser/chromeos/app_mode/kiosk_troubleshooting_controller_ash.h b/chrome/browser/chromeos/app_mode/kiosk_troubleshooting_controller_ash.h
index 285fe3be..38fb2b4 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_troubleshooting_controller_ash.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_troubleshooting_controller_ash.h
@@ -37,6 +37,7 @@
     SWITCH_WINDOWS_BACKWARD,
     SHOW_TASK_MANAGER,
     OPEN_FEEDBACK_PAGE,
+    TOGGLE_OVERVIEW,
   };
 
   // ui::AcceleratorTarget:
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/events/BUILD.gn b/chrome/browser/chromeos/extensions/telemetry/api/events/BUILD.gn
index e30ed74..16ebd31 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/events/BUILD.gn
+++ b/chrome/browser/chromeos/extensions/telemetry/api/events/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//chrome/common/chromeos/extensions/api/api_sources.gni")
 import("//extensions/buildflags/buildflags.gni")
+import("//build/config/chromeos/ui_mode.gni")
 
 assert(enable_extensions,
        "Cannot depend on extensions because enable_extensions=false.")
@@ -24,8 +25,16 @@
     "//chrome/common/chromeos/extensions/api",
     "//chromeos/crosapi/mojom",
     "//extensions/browser",
+    "//url",
   ]
 
+  if (is_chromeos_ash) {
+    deps += [
+      "//chrome/browser/profiles:profile",
+      "//chrome/browser/ui",
+    ]
+  }
+
   if (is_chromeos_lacros) {
     deps += [ "//chromeos/lacros" ]
   }
@@ -114,6 +123,7 @@
     "//extensions/common",
     "//mojo/public/cpp/bindings",
     "//testing/gtest",
+    "//url",
   ]
 
   data = [ "//chrome/test/data" ]
@@ -124,7 +134,11 @@
       "fake_events_service_factory.h",
     ]
 
-    deps += [ "//chrome/browser/ash/telemetry_extension/events" ]
+    deps += [
+      "//chrome/browser/ash/telemetry_extension/events",
+      "//chrome/browser/profiles:profile",
+      "//chrome/browser/ui",
+    ]
   }
 
   if (is_chromeos_lacros) {
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/events/event_observation_crosapi.cc b/chrome/browser/chromeos/extensions/telemetry/api/events/event_observation_crosapi.cc
index f61dea8b..e9b2b2d 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/events/event_observation_crosapi.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/events/event_observation_crosapi.cc
@@ -104,10 +104,18 @@
         break;
       }
       case crosapi::internal::TelemetryEventInfo_Data::TelemetryEventInfo_Tag::
-          kKeyboardDiagnosticEventInfo: {
-        NOTIMPLEMENTED();
+          kKeyboardDiagnosticEventInfo:
+        base::Value::List args;
+        args.Append(converters::ConvertStructPtr<
+                        api::os_events::KeyboardDiagnosticEventInfo>(
+                        std::move(info->get_keyboard_diagnostic_event_info()))
+                        .ToValue());
+
+        event = std::make_unique<extensions::Event>(
+            extensions::events::OS_EVENTS_ON_KEYBOARD_DIAGNOSTIC_EVENT,
+            api::os_events::OnKeyboardDiagnosticEvent::kEventName,
+            std::move(args), browser_context_);
         break;
-      }
     }
 
     extensions::EventRouter::Get(browser_context_)
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/events/events_api.cc b/chrome/browser/chromeos/extensions/telemetry/api/events/events_api.cc
index 1a9eaba..49e6f63f 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/events/events_api.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/events/events_api.cc
@@ -12,11 +12,21 @@
 #include "chrome/browser/chromeos/extensions/telemetry/api/events/remote_event_service_strategy.h"
 #include "chrome/common/chromeos/extensions/api/events.h"
 #include "chromeos/crosapi/mojom/telemetry_extension_exception.mojom.h"
+#include "content/public/browser/browser_context.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "url/gurl.h"
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/profiles/profile.h" // nogncheck
+#include "chrome/browser/ui/browser_navigator.h" // nogncheck
+#include "chrome/browser/ui/browser_navigator_params.h" // nogncheck
+#include "ui/base/page_transition_types.h" // nogncheck
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "chromeos/crosapi/mojom/telemetry_event_service.mojom.h"
+#include "chromeos/crosapi/mojom/url_handler.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
@@ -24,9 +34,34 @@
 
 namespace {
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+const char kKeyboardDiagnosticsUrl[] = "chrome://diagnostics?input";
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+const char kKeyboardDiagnosticsUrl[] = "os://diagnostics?input";
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 namespace cx_events = ::chromeos::api::os_events;
 namespace crosapi = ::crosapi::mojom;
 
+void OpenDiagnosticsKeyboardPage(content::BrowserContext* browser_context) {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  NavigateParams navigate_params(Profile::FromBrowserContext(browser_context),
+                                 GURL(kKeyboardDiagnosticsUrl),
+                                 ui::PAGE_TRANSITION_FIRST);
+  Navigate(&navigate_params);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  auto* lacros_service = LacrosService::Get();
+  DCHECK(lacros_service);
+  DCHECK(lacros_service->IsAvailable<crosapi::UrlHandler>());
+
+  lacros_service->GetRemote<crosapi::UrlHandler>()->OpenUrl(
+      GURL(kKeyboardDiagnosticsUrl));
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+}
+
 }  // namespace
 
 // EventsApiFunctionBase -------------------------------------------------------
@@ -111,6 +146,12 @@
   }
 
   auto* event_manager = EventManager::Get(browser_context());
+  // If this is the "kKeyboardDiagnostic", we want to open the first party diag
+  // tool to allow the user to run the diagnostic and then return the event.
+  if (params->category == cx_events::EventCategory::kKeyboardDiagnostic) {
+    OpenDiagnosticsKeyboardPage(browser_context());
+  }
+
   auto result = event_manager->RegisterExtensionForEvent(
       extension_id(), converters::Convert(params->category));
 
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/events/events_api_browsertests.cc b/chrome/browser/chromeos/extensions/telemetry/api/events/events_api_browsertests.cc
index 603cf0e8..f46163f0 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/events/events_api_browsertests.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/events/events_api_browsertests.cc
@@ -12,19 +12,25 @@
 #include "base/test/test_future.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/common/base_telemetry_extension_browser_test.h"
+#include "chrome/browser/chromeos/extensions/telemetry/api/events/events_api.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/events/fake_events_service.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/crosapi/mojom/telemetry_event_service.mojom.h"
 #include "chromeos/crosapi/mojom/telemetry_extension_exception.mojom.h"
+#include "chromeos/crosapi/mojom/telemetry_keyboard_event.mojom.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "extensions/common/extension_features.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ash/telemetry_extension/events/telemetry_event_service_ash.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/events/fake_events_service_factory.h"
+#include "chrome/browser/profiles/profile.h" // nogncheck
+#include "chrome/browser/ui/browser_list.h" // nogncheck
+#include "chrome/browser/ui/tabs/tab_strip_model.h" // nogncheck
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -38,6 +44,10 @@
 
 namespace crosapi = ::crosapi::mojom;
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+const char kKeyboardDiagnosticsUrl[] = "chrome://diagnostics?input";
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+
 }  // namespace
 
 class TelemetryExtensionEventsApiBrowserTest
@@ -334,6 +344,44 @@
 }
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionEventsApiBrowserTest,
+                       KeyboardDiagnosticEventOpensDiagnosticApp) {
+  // Open the PWA.
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(pwa_page_url())));
+
+  CreateExtensionAndRunServiceWorker(R"(
+    chrome.test.runTests([
+      async function startCapturingEvents() {
+        await chrome.os.events.startCapturingEvents("keyboard_diagnostic");
+        chrome.test.succeed();
+      }
+    ]);
+  )");
+
+// If this is executed in Lacros we can stop the test here. If the above
+// call succeeded, a request for opening the diagnostics application was
+// sent to Ash. Since we only test Lacros, we stop the test here instead
+// of checking if Ash opened the UI correctly.
+// If we run in Ash however, we can check that the UI was correctly open.
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  bool is_diagnostic_app_open = false;
+  for (auto* target_browser : *BrowserList::GetInstance()) {
+    TabStripModel* target_tab_strip = target_browser->tab_strip_model();
+    for (int i = 0; i < target_tab_strip->count(); ++i) {
+      content::WebContents* target_contents =
+          target_tab_strip->GetWebContentsAt(i);
+
+      if (target_contents->GetLastCommittedURL() ==
+          GURL(kKeyboardDiagnosticsUrl)) {
+        is_diagnostic_app_open = true;
+      }
+    }
+  }
+
+  EXPECT_TRUE(is_diagnostic_app_open);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+}
+
+IN_PROC_BROWSER_TEST_F(TelemetryExtensionEventsApiBrowserTest,
                        CheckSdCardApiWithoutFeatureFlagFail) {
   // Open the PWA.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(pwa_page_url())));
@@ -377,6 +425,28 @@
   )");
 }
 
+IN_PROC_BROWSER_TEST_F(TelemetryExtensionEventsApiBrowserTest,
+                       CheckKeyboardDiagnosticApiWithoutFeatureFlagFail) {
+  // Open the PWA.
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(pwa_page_url())));
+
+  CreateExtensionAndRunServiceWorker(R"(
+    chrome.test.runTests([
+      function sdCardNotWorking() {
+        chrome.test.assertThrows(() => {
+          chrome.os.events.onKeyboardDiagnosticEvent.addListener((event) => {
+            // unreachable.
+          });
+        }, [],
+          'Cannot read properties of undefined (reading \'addListener\')'
+        );
+
+        chrome.test.succeed();
+      }
+    ]);
+  )");
+}
+
 class PendingApprovalTelemetryExtensionEventsApiBrowserTest
     : public TelemetryExtensionEventsApiBrowserTest {
  public:
@@ -456,4 +526,64 @@
   )");
 }
 
+IN_PROC_BROWSER_TEST_F(PendingApprovalTelemetryExtensionEventsApiBrowserTest,
+                       CheckKeyboardDiagnosticApiWithFeatureFlagWork) {
+  // Open the PWA.
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(pwa_page_url())));
+
+  GetFakeService()->SetOnSubscriptionChange(
+      base::BindLambdaForTesting([this]() {
+        auto keyboard_info = crosapi::TelemetryKeyboardInfo::New();
+        keyboard_info->id = crosapi::UInt32Value::New(1);
+        keyboard_info->connection_type =
+            crosapi::TelemetryKeyboardConnectionType::kBluetooth;
+        keyboard_info->name = "TestName";
+        keyboard_info->physical_layout =
+            crosapi::TelemetryKeyboardPhysicalLayout::kChromeOS;
+        keyboard_info->mechanical_layout =
+            crosapi::TelemetryKeyboardMechanicalLayout::kAnsi;
+        keyboard_info->region_code = "de";
+        keyboard_info->number_pad_present =
+            crosapi::TelemetryKeyboardNumberPadPresence::kPresent;
+
+        auto info = crosapi::TelemetryKeyboardDiagnosticEventInfo::New();
+        info->keyboard_info = std::move(keyboard_info);
+        info->tested_keys = {1, 2, 3};
+        info->tested_top_row_keys = {4, 5, 6};
+
+        GetFakeService()->EmitEventForCategory(
+            crosapi::TelemetryEventCategoryEnum::kKeyboardDiagnostic,
+            crosapi::TelemetryEventInfo::NewKeyboardDiagnosticEventInfo(
+                std::move(info)));
+      }));
+
+  CreateExtensionAndRunServiceWorker(R"(
+    chrome.test.runTests([
+      async function startCapturingEvents() {
+        chrome.os.events.onKeyboardDiagnosticEvent.addListener((event) => {
+          chrome.test.assertEq(event, {
+            "keyboardInfo": {
+              "connectionType":"bluetooth",
+              "id":1,
+              "mechanicalLayout":"ansi",
+              "name":"TestName",
+              "numberPadPresent":"present",
+              "physicalLayout":"chrome_os",
+              "regionCode":"de",
+              "topRowKeys":[]
+            },
+            "testedKeys":[1,2,3],
+            "testedTopRowKeys":[4,5,6]
+            }
+          );
+
+          chrome.test.succeed();
+        });
+
+        await chrome.os.events.startCapturingEvents("keyboard_diagnostic");
+      }
+    ]);
+  )");
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_files_controller.cc b/chrome/browser/chromeos/policy/dlp/dlp_files_controller.cc
index 4e6cc12..67133d5 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_files_controller.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_files_controller.cc
@@ -136,20 +136,9 @@
       MapFilePathtoPolicyComponent(profile, destination.path());
   absl::optional<data_controls::Component> src_component =
       MapFilePathtoPolicyComponent(profile, source_file.path());
-  ::dlp::DlpComponent component_proto;
-  if (!src_component.has_value()) {
-    src_component = data_controls::Component::kUnknownComponent;
-  }
-  if (dst_component.has_value()) {
-    component_proto = MapPolicyComponentToProto(dst_component.value());
-  } else {
-    // Treat non external as system. We want to allow the operation and system
-    // is allowed always
-    component_proto = ::dlp::SYSTEM;
-  }
 
   // Copy from external is not limited by DLP.
-  if (src_component != data_controls::Component::kUnknownComponent) {
+  if (src_component.has_value()) {
     std::move(result_callback)
         .Run(std::make_unique<file_access::ScopedFileAccess>(
             file_access::ScopedFileAccess::Allowed()));
@@ -160,7 +149,7 @@
   file_access_request.add_files_paths(source_file.path().value());
   file_access_request.set_destination_url(destination.path().DirName().value());
 
-  if (component_proto == ::dlp::SYSTEM) {
+  if (!dst_component.has_value()) {
     // We allow internal copy, we still have to get the scopedFS
     // and we might need to copy the source URL information.
     auto inode = GetInodeValue(source_file.path());
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
index 54deb8e..68c2b55 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
@@ -550,7 +550,7 @@
          restriction == Restriction::kFiles);
 
   std::map<Level, std::set<data_controls::Component>> result;
-  for (data_controls::Component component : components) {
+  for (data_controls::Component component : data_controls::kAllComponents) {
     std::string out_source_pattern;
     Level level = IsRestrictedComponent(source, component, restriction,
                                         &out_source_pattern, nullptr);
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
index 5d71a16..fcffef1b 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
@@ -890,7 +890,7 @@
   auto result = dlp_rules_manager_.GetAggregatedComponents(
       GURL(kExampleUrl), DlpRulesManager::Restriction::kClipboard);
   std::map<DlpRulesManager::Level, std::set<data_controls::Component>> expected;
-  for (auto component : DlpRulesManager::components) {
+  for (auto component : data_controls::kAllComponents) {
     expected[DlpRulesManager::Level::kAllow].insert(component);
   }
 
diff --git a/chrome/browser/companion/core/BUILD.gn b/chrome/browser/companion/core/BUILD.gn
index 777fc49..0a14098 100644
--- a/chrome/browser/companion/core/BUILD.gn
+++ b/chrome/browser/companion/core/BUILD.gn
@@ -17,7 +17,7 @@
     "promo_handler.h",
     "signin_delegate.h",
   ]
-  public_deps = [ "//third_party/abseil-cpp:absl" ]
+
   deps = [
     "mojom:mojo_bindings",
     "proto",
diff --git a/chrome/browser/companion/core/features.cc b/chrome/browser/companion/core/features.cc
index 5480c38..5459415 100644
--- a/chrome/browser/companion/core/features.cc
+++ b/chrome/browser/companion/core/features.cc
@@ -39,32 +39,10 @@
 const char kDisableCheckUserPermissionsForCompanion[] =
     "disable-checking-companion-user-permissions";
 
-const char kForceCompanionPinnedState[] = "force-companion-pinned-state";
-
 bool ShouldOverrideCheckingUserPermissionsForCompanion() {
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   return command_line->HasSwitch(kDisableCheckUserPermissionsForCompanion);
 }
 
-absl::optional<bool> ShouldForceOverrideCompanionPinState() {
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (!command_line->HasSwitch(kForceCompanionPinnedState)) {
-    return absl::nullopt;
-  }
-
-  std::string pinned_state =
-      command_line->GetSwitchValueASCII(kForceCompanionPinnedState);
-  if (pinned_state == "pinned") {
-    return true;
-  }
-  if (pinned_state == "unpinned") {
-    return false;
-  }
-
-  NOTREACHED() << "Invalid Companion pin state command line switch value: "
-               << pinned_state;
-  return absl::nullopt;
-}
-
 }  // namespace switches
 }  // namespace companion
diff --git a/chrome/browser/companion/core/features.h b/chrome/browser/companion/core/features.h
index 7d28b3b..974e795 100644
--- a/chrome/browser/companion/core/features.h
+++ b/chrome/browser/companion/core/features.h
@@ -8,7 +8,6 @@
 #include "base/feature_list.h"
 #include "base/metrics/field_trial_params.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace companion {
 namespace features {
@@ -24,16 +23,11 @@
 
 namespace switches {
 extern const char kDisableCheckUserPermissionsForCompanion[];
-extern const char kForceCompanionPinnedState[];
 
 // Returns true if checking of the user's permissions to share page information
 // with the Companion server should be ignored. Returns true only in tests.
 bool ShouldOverrideCheckingUserPermissionsForCompanion();
 
-// Returns whether the Companion pin state should force overridden, regardless
-// of prefs or labs state.
-absl::optional<bool> ShouldForceOverrideCompanionPinState();
-
 }  // namespace switches
 }  // namespace companion
 
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java b/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
index 7d3b033c..af62d958 100644
--- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
+++ b/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
@@ -7,7 +7,9 @@
 import android.net.Uri;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
 
+import org.chromium.content_public.browser.Impression;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.common.Referrer;
 import org.chromium.url.GURL;
@@ -83,8 +85,10 @@
      * the current {@link Tab}.
      * @param url The URL to open.
      * @param navigateToTab Whether or not to navigate to the new tab.
+     * @param impression The attribution impression to associate with the navigation.
      */
-    void onOpenInNewTab(GURL url, Referrer referrer, boolean navigateToTab);
+    void onOpenInNewTab(
+            GURL url, Referrer referrer, boolean navigateToTab, @Nullable Impression impression);
 
     /**
      * Called when {@code url} should be opened in a new tab in the same group as the current
diff --git a/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc b/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc
index 95bcc65..0cdc9a99 100644
--- a/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc
+++ b/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/strings/strcat.h"
+#include "base/test/scoped_feature_list.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/devtools/protocol/devtools_protocol_test_support.h"
 #include "chrome/browser/ui/browser.h"
@@ -127,6 +128,8 @@
  private:
   autofill::TestAutofillManagerInjector<TestAutofillManager>
       autofill_manager_injector_;
+  base::test::ScopedFeatureList feature_list_{
+      autofill::features::kAutofillAcrossIframes};
 };
 
 IN_PROC_BROWSER_TEST_F(DevToolsAutofillTest, TriggerCreditCard) {
@@ -152,10 +155,7 @@
   EXPECT_EQ(GetFilledOutForm(""), GetTestCreditCard());
 }
 
-// TODO(crbug.com/1445476): The test currently fails with Chrome-branded
-// patterns in Autofill.
-IN_PROC_BROWSER_TEST_F(DevToolsAutofillTest,
-                       DISABLED_TriggerCreditCardInIframe) {
+IN_PROC_BROWSER_TEST_F(DevToolsAutofillTest, TriggerCreditCardInIframe) {
   embedded_test_server()->ServeFilesFromSourceDirectory(
       "chrome/test/data/autofill");
   ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/dips/dips_bounce_detector.cc b/chrome/browser/dips/dips_bounce_detector.cc
index 81db125..fbb7e72 100644
--- a/chrome/browser/dips/dips_bounce_detector.cc
+++ b/chrome/browser/dips/dips_bounce_detector.cc
@@ -393,7 +393,7 @@
       std::move(redirects), std::move(chain),
       base::BindRepeating(
           &DIPSWebContentsObserver::IncrementPageSpecificBounceCount,
-          base::Unretained(this)));
+          weak_factory_.GetWeakPtr()));
 }
 
 void DIPSWebContentsObserver::IncrementPageSpecificBounceCount(
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
index 7e27f617..f0b5e42 100644
--- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc
+++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -736,8 +736,9 @@
           ("[1/1] blank -> a.test/title1.html (None) -> d.test/title1.html")));
 }
 
+// TODO(crrev/1448453): flaky test.
 IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
-                       DiscardPrerenderedPageCookieServerAccess) {
+                       DISABLED_DiscardPrerenderedPageCookieServerAccess) {
   std::vector<std::string> redirects;
   StartAppendingRedirectsTo(&redirects);
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
index cefcc80..78ec683 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.h"
 
+#include <vector>
+
 #include "base/memory/singleton.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -23,15 +25,23 @@
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/enterprise/connectors/device_trust/attestation/browser/browser_attestation_service.h"
+#include "chrome/browser/enterprise/connectors/device_trust/attestation/browser/device_attester.h"
+#include "chrome/browser/enterprise/connectors/device_trust/attestation/browser/profile_attester.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h"
+#include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h"
+#include "chrome/browser/enterprise/identifiers/profile_id_service_factory.h"
 #include "chrome/browser/enterprise/signals/signals_aggregator_factory.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "components/enterprise/browser/controller/browser_dm_token_storage.h"
 #include "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h"
 #include "components/enterprise/browser/device_trust/device_trust_key_manager.h"
+#include "components/enterprise/browser/identifiers/profile_id_service.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
 #include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
 #include "components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h"
+#include "components/policy/core/common/cloud/profile_cloud_policy_manager.h"
+#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -44,6 +54,24 @@
       policy::ManagementServiceFactory::GetForProfile(profile);
   return management_service && management_service->IsManaged();
 }
+
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
+policy::CloudPolicyStore* GetUserCloudPolicyStore(Profile* profile) {
+  policy::CloudPolicyManager* user_policy_manager =
+      profile->GetUserCloudPolicyManager();
+  if (!user_policy_manager) {
+    user_policy_manager = profile->GetProfileCloudPolicyManager();
+  }
+  if (user_policy_manager) {
+    auto* core = user_policy_manager->core();
+    if (core) {
+      return core->store();
+    }
+  }
+  return nullptr;
+}
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
+
 }  // namespace
 
 namespace enterprise_connectors {
@@ -81,6 +109,9 @@
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
   // Depends on this service via the SignalsService having a dependency on it.
   DependsOn(enterprise_signals::SignalsAggregatorFactory::GetInstance());
+  // Depends on this service via the ProfileAttester having a dependency on it
+  // which is used to construct the BrowserAttestationService.
+  DependsOn(enterprise::ProfileIdServiceFactory::GetInstance());
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
 }
 
@@ -99,6 +130,17 @@
     // supported.
     return nullptr;
 
+  auto* dt_connector_service =
+      DeviceTrustConnectorServiceFactory::GetForProfile(profile);
+
+  // If `profile` is a OTR profile but not the login profile on ChromeOS login
+  // screen. Then `dt_connector_service` will be null. Hence a
+  // DeviceTrustService won't be created for OTR profiles besides the one
+  // mentioned before.
+  if (!dt_connector_service) {
+    return nullptr;
+  }
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<AttestationService> attestation_service =
       std::make_unique<AshAttestationService>(profile);
@@ -124,10 +166,26 @@
     return nullptr;
   }
 
-  std::unique_ptr<AttestationService> attestation_service =
-      std::make_unique<DesktopAttestationService>(
-          policy::BrowserDMTokenStorage::Get(), key_manager,
-          browser_cloud_policy_store);
+  std::unique_ptr<AttestationService> attestation_service;
+  if (IsUserInlineFlowFeatureEnabled()) {
+    // TODO(b/281838243): Update the DTS browser test to account for the browser
+    // attestation service once the new policies are created and supported on DM
+    // Server.
+    std::vector<std::unique_ptr<Attester>> attesters;
+    attesters.push_back(std::make_unique<DeviceAttester>(
+        key_manager, policy::BrowserDMTokenStorage::Get(),
+        browser_cloud_policy_store));
+    attesters.push_back(std::make_unique<ProfileAttester>(
+        enterprise::ProfileIdServiceFactory::GetForProfile(profile),
+        GetUserCloudPolicyStore(profile)));
+
+    attestation_service =
+        std::make_unique<BrowserAttestationService>(std::move(attesters));
+  } else {
+    attestation_service = std::make_unique<DesktopAttestationService>(
+        policy::BrowserDMTokenStorage::Get(), key_manager,
+        browser_cloud_policy_store);
+  }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   auto signals_service = CreateSignalsService(profile);
@@ -136,17 +194,6 @@
     return nullptr;
   }
 
-  auto* dt_connector_service =
-      DeviceTrustConnectorServiceFactory::GetForProfile(profile);
-
-  // If `profile` is a OTR profile but not the login profile on ChromeOS login
-  // screen. Then `dt_connector_service` will be null. Hence a
-  // DeviceTrustService won't be created for OTR profiles besides the one
-  // mentioned before.
-  if (!dt_connector_service) {
-    return nullptr;
-  }
-
   // Only return an actual instance if all of the service's dependencies can be
   // resolved (meaning that the current management configuration is supported).
   return new DeviceTrustService(std::move(attestation_service),
diff --git a/chrome/browser/enterprise/data_controls/BUILD.gn b/chrome/browser/enterprise/data_controls/BUILD.gn
index 67140e6..677d0f19 100644
--- a/chrome/browser/enterprise/data_controls/BUILD.gn
+++ b/chrome/browser/enterprise/data_controls/BUILD.gn
@@ -4,20 +4,30 @@
 
 source_set("data_controls") {
   sources = [
+    "action_context.h",
+    "attributes_condition.cc",
+    "attributes_condition.h",
+    "condition.h",
     "data_controls_policy_handler.cc",
     "data_controls_policy_handler.h",
     "dlp_rules_manager_base.h",
   ]
 
   deps = [
+    "//base",
     "//components/keyed_service/core",
     "//components/policy/core/browser",
     "//components/prefs",
+    "//components/url_matcher",
+    "//third_party/abseil-cpp:absl",
     "//url",
   ]
 
   if (is_chromeos) {
-    sources += [ "component.h" ]
+    sources += [
+      "component.cc",
+      "component.h",
+    ]
   }
 }
 
@@ -33,3 +43,14 @@
     "//third_party/abseil-cpp:absl",
   ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "attributes_condition_unittest.cc" ]
+
+  deps = [
+    ":data_controls",
+    "//base",
+    "//testing/gtest",
+  ]
+}
diff --git a/chrome/browser/enterprise/data_controls/action_context.h b/chrome/browser/enterprise/data_controls/action_context.h
new file mode 100644
index 0000000..7d98eda
--- /dev/null
+++ b/chrome/browser/enterprise/data_controls/action_context.h
@@ -0,0 +1,29 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_ACTION_CONTEXT_H_
+#define CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_ACTION_CONTEXT_H_
+
+#include "build/chromeos_buildflags.h"
+#include "url/gurl.h"
+
+#if BUILDFLAG(IS_CHROMEOS)
+#include "chrome/browser/enterprise/data_controls/component.h"
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
+namespace data_controls {
+
+// Generic struct that represents metadata about an action involved in Data
+// Controls. It can be used to either represent a source or destination tied
+// to an action.
+struct ActionContext {
+  GURL url;
+#if BUILDFLAG(IS_CHROMEOS)
+  Component component = Component::kUnknownComponent;
+#endif  // BUILDFLAG(IS_CHROMEOS)
+};
+
+}  // namespace data_controls
+
+#endif  // CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_ACTION_CONTEXT_H_
diff --git a/chrome/browser/enterprise/data_controls/attributes_condition.cc b/chrome/browser/enterprise/data_controls/attributes_condition.cc
new file mode 100644
index 0000000..050e7e4
--- /dev/null
+++ b/chrome/browser/enterprise/data_controls/attributes_condition.cc
@@ -0,0 +1,107 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/data_controls/attributes_condition.h"
+
+#include "base/containers/contains.h"
+#include "components/url_matcher/url_util.h"
+
+namespace data_controls {
+
+namespace {
+
+// Constants used to parse sub-dictionaries of DLP policies that should map to
+// an AttributesCondition.
+constexpr char kKeyUrls[] = "urls";
+
+#if BUILDFLAG(IS_CHROMEOS)
+constexpr char kKeyComponents[] = "components";
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
+}  // namespace
+
+AttributesCondition::AttributesCondition() = default;
+AttributesCondition::~AttributesCondition() = default;
+
+// static
+std::unique_ptr<AttributesCondition> AttributesCondition::Create(
+    const base::Value& value) {
+  if (!value.is_dict()) {
+    return nullptr;
+  }
+
+  return AttributesCondition::Create(value.GetDict());
+}
+
+// static
+std::unique_ptr<AttributesCondition> AttributesCondition::Create(
+    const base::Value::Dict& value) {
+  auto attributes_condition = std::make_unique<AttributesCondition>();
+
+  const base::Value::List* urls_value = value.FindList(kKeyUrls);
+  if (urls_value) {
+    for (const base::Value& url_pattern : *urls_value) {
+      if (!url_pattern.is_string()) {
+        return nullptr;
+      }
+    }
+
+    auto url_matcher = std::make_unique<url_matcher::URLMatcher>();
+    base::MatcherStringPattern::ID id(0);
+    url_matcher::util::AddFilters(url_matcher.get(), true, &id, *urls_value);
+
+    if (!url_matcher->IsEmpty()) {
+      attributes_condition->url_matcher_ = std::move(url_matcher);
+    }
+  }
+
+#if BUILDFLAG(IS_CHROMEOS)
+  const base::Value::List* components_value = value.FindList(kKeyComponents);
+  if (components_value) {
+    std::set<Component> components;
+    for (const auto& component_string : *components_value) {
+      if (!component_string.is_string()) {
+        continue;
+      }
+
+      Component component = GetComponentMapping(component_string.GetString());
+      if (component != Component::kUnknownComponent) {
+        components.insert(component);
+      }
+    }
+    attributes_condition->components_ = std::move(components);
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
+  if (attributes_condition->IsValid()) {
+    return attributes_condition;
+  }
+
+  return nullptr;
+}
+
+bool AttributesCondition::IsTriggered(
+    const ActionContext& action_context) const {
+#if BUILDFLAG(IS_CHROMEOS)
+  if (!components_.empty() &&
+      !base::Contains(components_, action_context.component)) {
+    return false;
+  }
+#endif
+  if (url_matcher_ && action_context.url.is_valid() &&
+      url_matcher_->MatchURL(action_context.url).empty()) {
+    return false;
+  }
+  return true;
+}
+
+bool AttributesCondition::IsValid() const {
+#if BUILDFLAG(IS_CHROMEOS)
+  return (url_matcher_ && !url_matcher_->IsEmpty()) || !components_.empty();
+#else
+  return url_matcher_ && !url_matcher_->IsEmpty();
+#endif  // BUILDFLAG(IS_CHROMEOS)
+}
+
+}  // namespace data_controls
diff --git a/chrome/browser/enterprise/data_controls/attributes_condition.h b/chrome/browser/enterprise/data_controls/attributes_condition.h
new file mode 100644
index 0000000..39d25e7f
--- /dev/null
+++ b/chrome/browser/enterprise/data_controls/attributes_condition.h
@@ -0,0 +1,56 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_ATTRIBUTES_CONDITION_H_
+#define CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_ATTRIBUTES_CONDITION_H_
+
+#include <memory>
+
+#include "base/values.h"
+#include "chrome/browser/enterprise/data_controls/condition.h"
+#include "components/url_matcher/url_matcher.h"
+
+#if BUILDFLAG(IS_CHROMEOS)
+#include <set>
+
+#include "chrome/browser/enterprise/data_controls/component.h"
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
+namespace data_controls {
+
+// Implementation of the "root" level condition of a Data Control policy, which
+// evaluates all the attributes in an `ActionContext`. This class is a
+// representation of the following JSON:
+// {
+//   urls: [string],
+//   components: [ARC|CROSTINI|PLUGIN_VM|DRIVE|USB], <= CrOS only
+// }
+// This can represent either the `sources` or `destinations` fields of the
+// DataLeakPreventionRulesList policy.
+class AttributesCondition : public Condition {
+ public:
+  AttributesCondition();
+  virtual ~AttributesCondition();
+
+  // Returns nullptr if the passed JSON doesn't match the expected schema.
+  static std::unique_ptr<AttributesCondition> Create(const base::Value& value);
+  static std::unique_ptr<AttributesCondition> Create(
+      const base::Value::Dict& value);
+
+  // Condition:
+  bool IsTriggered(const ActionContext& action_context) const override;
+
+ private:
+  // Returns true if at least one of the internal values is non-null/empty.
+  bool IsValid() const;
+
+  std::unique_ptr<url_matcher::URLMatcher> url_matcher_;
+#if BUILDFLAG(IS_CHROMEOS)
+  std::set<Component> components_;
+#endif  // BUILDFLAG(IS_CHROMEOS)
+};
+
+}  // namespace data_controls
+
+#endif  // CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_ATTRIBUTES_CONDITION_H_
diff --git a/chrome/browser/enterprise/data_controls/attributes_condition_unittest.cc b/chrome/browser/enterprise/data_controls/attributes_condition_unittest.cc
new file mode 100644
index 0000000..6f7b7d3
--- /dev/null
+++ b/chrome/browser/enterprise/data_controls/attributes_condition_unittest.cc
@@ -0,0 +1,183 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/data_controls/attributes_condition.h"
+
+#include <vector>
+
+#include "base/json/json_reader.h"
+#include "base/strings/stringprintf.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace data_controls {
+
+namespace {
+
+constexpr char kGoogleUrl[] = "https://google.com";
+constexpr char kChromiumUrl[] = "https://chromium.org";
+
+base::Value CreateDict(const std::string& value) {
+  auto dict = base::JSONReader::Read(value, base::JSON_ALLOW_TRAILING_COMMAS);
+  EXPECT_TRUE(dict.has_value());
+  return std::move(dict.value());
+}
+
+}  // namespace
+
+TEST(AttributesConditionTest, InvalidInputs) {
+  // Invalid JSON types are rejected.
+  ASSERT_FALSE(AttributesCondition::Create(base::Value("some string")));
+  ASSERT_FALSE(AttributesCondition::Create(base::Value(12345)));
+  ASSERT_FALSE(AttributesCondition::Create(base::Value(99.999)));
+  ASSERT_FALSE(AttributesCondition::Create(
+      base::Value(std::vector<char>({1, 2, 3, 4, 5}))));
+
+  // Invalid dictionaries are rejected.
+  ASSERT_FALSE(AttributesCondition::Create(base::Value::Dict()));
+  ASSERT_FALSE(AttributesCondition::Create(CreateDict(R"({"foo": 1})")));
+
+  // Dictionaries with correct keys but wrong schema for values are rejected
+  ASSERT_FALSE(AttributesCondition::Create(
+      CreateDict(R"({"urls": "https://foo.com"})")));
+  ASSERT_FALSE(AttributesCondition::Create(CreateDict(R"({"urls": 1})")));
+  ASSERT_FALSE(AttributesCondition::Create(CreateDict(R"({"urls": 99.999})")));
+#if BUILDFLAG(IS_CHROMEOS)
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"urls": "https://foo.com",
+                                                    "components": "ARC"})")));
+  ASSERT_FALSE(AttributesCondition::Create(CreateDict(R"({"urls": 1,
+                                                    "components": "ARC"})")));
+  ASSERT_FALSE(AttributesCondition::Create(CreateDict(R"({"urls": 99.999,
+                                                    "components": "ARC"})")));
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"components": "ARC"})")));
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"components": 12345})")));
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"components": 99.999})")));
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
+  // Dictionaries with valid schemas but invalid URL patterns or components are
+  // rejected.
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"urls": ["http://:port"]})")));
+  ASSERT_FALSE(AttributesCondition::Create(
+      CreateDict(R"({"urls": ["http://?query"]})")));
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"urls": ["https://"]})")));
+  ASSERT_FALSE(AttributesCondition::Create(CreateDict(R"({"urls": ["//"]})")));
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"urls": ["a", 1]})")));
+#if BUILDFLAG(IS_CHROMEOS)
+  ASSERT_FALSE(AttributesCondition::Create(CreateDict(R"({"urls": ["a", 1],
+                                                    "components": ["ARC"]})")));
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"components": ["1", "a"]})")));
+  ASSERT_FALSE(
+      AttributesCondition::Create(CreateDict(R"({"components": ["5.5"]})")));
+#endif  // BUILDFLAG(IS_CHROMEOS)
+}
+
+TEST(AttributesConditionTest, AnyURL) {
+  auto any_url = AttributesCondition::Create(CreateDict(R"({"urls": ["*"]})"));
+  ASSERT_TRUE(any_url);
+  for (const char* url : {kGoogleUrl, kChromiumUrl}) {
+    ActionContext context = {.url = GURL(url)};
+    ASSERT_TRUE(any_url->IsTriggered(context));
+  }
+}
+
+TEST(AttributesConditionTest, SpecificURL) {
+  auto google_url =
+      AttributesCondition::Create(CreateDict(R"({"urls": ["google.com"]})"));
+  auto chromium_url =
+      AttributesCondition::Create(CreateDict(R"({"urls": ["chromium.org"]})"));
+
+  ASSERT_TRUE(google_url);
+  ASSERT_TRUE(chromium_url);
+
+  ASSERT_TRUE(google_url->IsTriggered({.url = GURL(kGoogleUrl)}));
+  ASSERT_TRUE(chromium_url->IsTriggered({.url = GURL(kChromiumUrl)}));
+
+  ASSERT_FALSE(google_url->IsTriggered({.url = GURL(kChromiumUrl)}));
+  ASSERT_FALSE(chromium_url->IsTriggered({.url = GURL(kGoogleUrl)}));
+}
+
+#if BUILDFLAG(IS_CHROMEOS)
+TEST(AttributesConditionTest, AllComponents) {
+  auto any_component = AttributesCondition::Create(CreateDict(R"(
+      {
+        "components": ["ARC", "CROSTINI", "PLUGIN_VM", "USB", "DRIVE",
+                       "ONEDRIVE"]
+      })"));
+  ASSERT_TRUE(any_component);
+  for (Component component : kAllComponents) {
+    ActionContext context = {.component = component};
+    ASSERT_TRUE(any_component->IsTriggered(context));
+  }
+}
+
+TEST(AttributesConditionTest, OneComponent) {
+  for (Component condition_component : kAllComponents) {
+    constexpr char kTemplate[] = R"({"components": ["%s"]})";
+    auto one_component =
+        AttributesCondition::Create(CreateDict(base::StringPrintf(
+            kTemplate, GetComponentMapping(condition_component).c_str())));
+
+    for (Component context_component : kAllComponents) {
+      ActionContext context = {.component = context_component};
+      if (context_component == condition_component) {
+        ASSERT_TRUE(one_component->IsTriggered(context));
+      } else {
+        ASSERT_FALSE(one_component->IsTriggered(context));
+      }
+    }
+  }
+}
+
+TEST(AttributesConditionTest, URLAndAllComponents) {
+  auto any_component_or_url = AttributesCondition::Create(CreateDict(R"(
+      {
+        "urls": ["*"],
+        "components": ["ARC", "CROSTINI", "PLUGIN_VM", "USB", "DRIVE",
+                       "ONEDRIVE"]
+      })"));
+  ASSERT_TRUE(any_component_or_url);
+  for (Component component : kAllComponents) {
+    for (const char* url : {kGoogleUrl, kChromiumUrl}) {
+      ActionContext context = {.url = GURL(url), .component = component};
+      ASSERT_TRUE(any_component_or_url->IsTriggered(context));
+    }
+  }
+}
+
+TEST(AttributesConditionTest, URLAndOneComponent) {
+  for (Component condition_component : kAllComponents) {
+    constexpr char kTemplate[] =
+        R"({"urls": ["google.com"], "components": ["%s"]})";
+    auto google_and_one_component =
+        AttributesCondition::Create(CreateDict(base::StringPrintf(
+            kTemplate, GetComponentMapping(condition_component).c_str())));
+
+    ASSERT_TRUE(google_and_one_component);
+    for (Component context_component : kAllComponents) {
+      for (const char* url : {kGoogleUrl, kChromiumUrl}) {
+        ActionContext context = {.url = GURL(url),
+                                 .component = context_component};
+        if (context_component == condition_component && url == kGoogleUrl) {
+          ASSERT_TRUE(google_and_one_component->IsTriggered(context))
+              << "Expected " << GetComponentMapping(context_component)
+              << " to trigger for " << url;
+        } else {
+          ASSERT_FALSE(google_and_one_component->IsTriggered(context))
+              << "Expected " << GetComponentMapping(context_component)
+              << " to not trigger for " << url;
+        }
+      }
+    }
+  }
+}
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
+}  // namespace data_controls
diff --git a/chrome/browser/enterprise/data_controls/component.cc b/chrome/browser/enterprise/data_controls/component.cc
new file mode 100644
index 0000000..dee1327
--- /dev/null
+++ b/chrome/browser/enterprise/data_controls/component.cc
@@ -0,0 +1,60 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/data_controls/component.h"
+
+#include "base/containers/fixed_flat_map.h"
+#include "base/strings/string_piece.h"
+
+namespace data_controls {
+
+namespace {
+
+// String equivalents of the `Component` enum, used for parsing JSON.
+constexpr char kArc[] = "ARC";
+constexpr char kCrostini[] = "CROSTINI";
+constexpr char kPluginVm[] = "PLUGIN_VM";
+constexpr char kDrive[] = "DRIVE";
+constexpr char kOneDrive[] = "ONEDRIVE";
+constexpr char kUsb[] = "USB";
+
+static constexpr auto kStringToComponentMap =
+    base::MakeFixedFlatMap<base::StringPiece, Component>(
+        {{kArc, Component::kArc},
+         {kCrostini, Component::kCrostini},
+         {kPluginVm, Component::kPluginVm},
+         {kDrive, Component::kDrive},
+         {kUsb, Component::kUsb},
+         {kOneDrive, Component::kOneDrive}});
+
+}  // namespace
+
+Component GetComponentMapping(const std::string& component) {
+  auto* it = kStringToComponentMap.find(component);
+  return (it == kStringToComponentMap.end()) ? Component::kUnknownComponent
+                                             : it->second;
+}
+
+std::string GetComponentMapping(Component component) {
+  // Using a switch statement here ensures that adding a value to the
+  // `Component` enum will fail compilation if the code isn't updated.
+  switch (component) {
+    case Component::kArc:
+      return kArc;
+    case Component::kCrostini:
+      return kCrostini;
+    case Component::kPluginVm:
+      return kPluginVm;
+    case Component::kDrive:
+      return kDrive;
+    case Component::kOneDrive:
+      return kOneDrive;
+    case Component::kUsb:
+      return kUsb;
+    case Component::kUnknownComponent:
+      return "";
+  }
+}
+
+}  // namespace data_controls
diff --git a/chrome/browser/enterprise/data_controls/component.h b/chrome/browser/enterprise/data_controls/component.h
index 3750aa2..c7a417e7 100644
--- a/chrome/browser/enterprise/data_controls/component.h
+++ b/chrome/browser/enterprise/data_controls/component.h
@@ -5,6 +5,9 @@
 #ifndef CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_COMPONENT_H_
 #define CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_COMPONENT_H_
 
+#include <array>
+#include <string>
+
 namespace data_controls {
 
 // A representation of destinations to which sharing confidential data is
@@ -22,6 +25,19 @@
   kMaxValue = kOneDrive
 };
 
+// List of all possible component values, used to simplify iterating over all
+// the options.
+constexpr static const std::array<Component,
+                                  static_cast<size_t>(Component::kMaxValue)>
+    kAllComponents = {Component::kArc,      Component::kCrostini,
+                      Component::kPluginVm, Component::kUsb,
+                      Component::kDrive,    Component::kOneDrive};
+
+// Maps a string to the corresponding `Component`, or vice-versa.
+// `Component::kUnknownComponent` is return if the string matches no component.
+Component GetComponentMapping(const std::string& component);
+std::string GetComponentMapping(Component component);
+
 }  // namespace data_controls
 
 #endif  // CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_COMPONENT_H_
diff --git a/chrome/browser/enterprise/data_controls/condition.h b/chrome/browser/enterprise/data_controls/condition.h
new file mode 100644
index 0000000..0c5a21b
--- /dev/null
+++ b/chrome/browser/enterprise/data_controls/condition.h
@@ -0,0 +1,20 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_CONDITION_H_
+#define CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_CONDITION_H_
+
+#include "chrome/browser/enterprise/data_controls/action_context.h"
+
+namespace data_controls {
+
+// Interface for a generic condition to be evaluated by a Data Controls policy.
+class Condition {
+ public:
+  virtual bool IsTriggered(const ActionContext& action_context) const = 0;
+};
+
+}  // namespace data_controls
+
+#endif  // CHROME_BROWSER_ENTERPRISE_DATA_CONTROLS_CONDITION_H_
diff --git a/chrome/browser/enterprise/idle/action.cc b/chrome/browser/enterprise/idle/action.cc
index fc7a98a..6f6bdd0 100644
--- a/chrome/browser/enterprise/idle/action.cc
+++ b/chrome/browser/enterprise/idle/action.cc
@@ -16,6 +16,7 @@
 #include "base/scoped_observation.h"
 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h"
 #include "chrome/browser/enterprise/idle/action_runner.h"
+#include "chrome/browser/enterprise/idle/idle_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
@@ -58,7 +59,7 @@
 
   void Run(Profile* profile, Continuation continuation) override {
     base::TimeDelta timeout =
-        profile->GetPrefs()->GetTimeDelta(prefs::kIdleTimeout);
+        IdleServiceFactory::GetForBrowserContext(profile)->GetTimeout();
     continuation_ = std::move(continuation);
     // Action object's lifetime extends until it calls `continuation_`, so
     // passing `this` as a raw pointer is safe.
@@ -291,9 +292,10 @@
     if (browser && browser->profile() == profile &&
         !base::Contains(action_types_, ActionType::kCloseBrowsers)) {
       // A browser for this profile has focus. Show the bubble there.
-      ShowIdleBubble(browser,
-                     profile->GetPrefs()->GetTimeDelta(prefs::kIdleTimeout),
-                     ActionsToActionSet(action_types_));
+      ShowIdleBubble(
+          browser,
+          IdleServiceFactory::GetForBrowserContext(profile)->GetTimeout(),
+          ActionsToActionSet(action_types_));
     } else {
       // No active browser for this profile. Show the bubble when a browser
       // gains focus, or on next startup. Let IdleServide::BrowserObserver do
diff --git a/chrome/browser/enterprise/idle/dialog_manager.cc b/chrome/browser/enterprise/idle/dialog_manager.cc
index 91afa8b..cbe2b142 100644
--- a/chrome/browser/enterprise/idle/dialog_manager.cc
+++ b/chrome/browser/enterprise/idle/dialog_manager.cc
@@ -8,13 +8,16 @@
 
 #include "base/check.h"
 #include "base/check_is_test.h"
+#include "base/command_line.h"
 #include "base/functional/bind.h"
 #include "base/task/single_thread_task_runner.h"
+#include "chrome/common/chrome_switches.h"
 
 namespace enterprise_idle {
 
 namespace {
 
+constexpr base::TimeDelta kTestDialogTimeout = base::Seconds(5);
 constexpr base::TimeDelta kDialogTimeout = base::Seconds(30);
 
 }  // namespace
@@ -42,12 +45,16 @@
     return subscription;
   }
 
-  dialog_ = IdleDialog::Show(
-      kDialogTimeout, threshold, ActionsToActionSet(action_types),
-      base::BindOnce(&DialogManager::OnDialogDismissedByUser,
-                     base::Unretained(this)));
+  base::TimeDelta timeout = base::CommandLine::ForCurrentProcess()->HasSwitch(
+                                switches::kSimulateIdleTimeout)
+                                ? kTestDialogTimeout
+                                : kDialogTimeout;
+  dialog_ =
+      IdleDialog::Show(timeout, threshold, ActionsToActionSet(action_types),
+                       base::BindOnce(&DialogManager::OnDialogDismissedByUser,
+                                      base::Unretained(this)));
   dialog_timer_.Start(
-      FROM_HERE, kDialogTimeout,
+      FROM_HERE, timeout,
       base::BindOnce(&DialogManager::OnDialogExpired, base::Unretained(this)));
   return subscription;
 }
diff --git a/chrome/browser/enterprise/idle/idle_service.cc b/chrome/browser/enterprise/idle/idle_service.cc
index daeb1e0..47b0a22 100644
--- a/chrome/browser/enterprise/idle/idle_service.cc
+++ b/chrome/browser/enterprise/idle/idle_service.cc
@@ -6,10 +6,12 @@
 
 #include <algorithm>
 
+#include "base/command_line.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/json/values_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "ui/base/idle/idle.h"
@@ -98,8 +100,7 @@
 IdleService::~IdleService() = default;
 
 void IdleService::OnIdleTimeoutPrefChanged() {
-  base::TimeDelta timeout =
-      profile_->GetPrefs()->GetTimeDelta(prefs::kIdleTimeout);
+  base::TimeDelta timeout = GetTimeout();
   if (timeout.is_positive()) {
     // `is_idle_` will auto-update in 1 second, no need to set it here.
     idle_threshold_ = timeout;
@@ -116,6 +117,13 @@
   }
 }
 
+base::TimeDelta IdleService::GetTimeout() const {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+             switches::kSimulateIdleTimeout)
+             ? base::Seconds(5)
+             : profile_->GetPrefs()->GetTimeDelta(prefs::kIdleTimeout);
+}
+
 void IdleService::OnIdleStateChange(
     const ui::IdlePollingService::State& polled_state) {
   if (is_idle_) {
diff --git a/chrome/browser/enterprise/idle/idle_service.h b/chrome/browser/enterprise/idle/idle_service.h
index 6c3bad5..cbd76c7 100644
--- a/chrome/browser/enterprise/idle/idle_service.h
+++ b/chrome/browser/enterprise/idle/idle_service.h
@@ -39,6 +39,8 @@
   void OnIdleStateChange(
       const ui::IdlePollingService::State& polled_state) override;
 
+  base::TimeDelta GetTimeout() const;
+
  private:
   // Called when the IdleTimeout policy changes, via the
   // "idle_profile_close_timeout" pref it's mapped to.
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index e01f813..0ee11a31 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -1187,8 +1187,8 @@
       "//chromeos/ash/components/dbus/update_engine",
       "//chromeos/ash/components/disks",
       "//chromeos/ash/components/enhanced_network_tts/mojom",
-      "//chromeos/ash/components/language/language_packs",
-      "//chromeos/ash/components/language/public/mojom",
+      "//chromeos/ash/components/language_packs",
+      "//chromeos/ash/components/language_packs/public/mojom",
       "//chromeos/ash/components/login/auth",
       "//chromeos/ash/components/login/login_state",
       "//chromeos/ash/components/network",
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index f2a0e5a2..362165b 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -60,6 +60,7 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/policy/core/common/policy_pref_names.h"
+#include "components/supervised_user/core/common/buildflags.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
@@ -96,6 +97,7 @@
 #include "extensions/browser/warning_service.h"
 #include "extensions/browser/warning_service_factory.h"
 #include "extensions/browser/zipfile_installer.h"
+#include "extensions/common/extension_features.h"
 #include "extensions/common/extension_set.h"
 #include "extensions/common/feature_switch.h"
 #include "extensions/common/features/feature_developer_mode_only.h"
@@ -1400,9 +1402,18 @@
 
   ExtensionService* service = GetExtensionService(browser_context());
   if (path.MatchesExtension(FILE_PATH_LITERAL(".zip"))) {
-    ZipFileInstaller::Create(GetExtensionFileTaskRunner(),
-                             MakeRegisterInExtensionServiceCallback(service))
-        ->LoadFromZipFile(path);
+    if (base::FeatureList::IsEnabled(
+            extensions_features::kExtensionsZipFileInstalledInProfileDir)) {
+      ZipFileInstaller::Create(GetExtensionFileTaskRunner(),
+                               MakeRegisterInExtensionServiceCallback(service))
+          ->InstallZipFileToUnpackedExtensionsDir(
+              path, service->unpacked_install_directory());
+    } else {
+      ZipFileInstaller::Create(GetExtensionFileTaskRunner(),
+                               MakeRegisterInExtensionServiceCallback(service))
+          ->InstallZipFileToTempDir(path);
+    }
+
   } else {
     auto prompt = std::make_unique<ExtensionInstallPrompt>(web_contents);
     scoped_refptr<CrxInstaller> crx_installer =
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
index 8f30b4e..9e2aa2a 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -7,11 +7,13 @@
 #include <memory>
 #include <utility>
 
+#include "base/base_paths.h"
 #include "base/files/file_util.h"
 #include "base/functional/bind.h"
 #include "base/json/json_writer.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/path_service.h"
 #include "base/scoped_observation.h"
 #include "base/stl_util.h"
 #include "base/strings/strcat.h"
@@ -276,6 +278,10 @@
   DeveloperPrivateApiUnitTest() {}
   ~DeveloperPrivateApiUnitTest() override {}
 
+  // ExtensionServiceTestBase:
+  void SetUp() override;
+  void TearDown() override;
+
   void AddMockExternalProvider(
       std::unique_ptr<ExternalProviderInterface> provider) {
     service()->AddProviderForTesting(std::move(provider));
@@ -331,10 +337,6 @@
   }
 
  private:
-  // ExtensionServiceTestBase:
-  void SetUp() override;
-  void TearDown() override;
-
   // The browser (and accompanying window).
   std::unique_ptr<TestBrowserWindow> browser_window_;
   std::unique_ptr<Browser> browser_;
@@ -1951,7 +1953,42 @@
       api::developer_private::EVENT_TYPE_PERMISSIONS_CHANGED));
 }
 
-TEST_F(DeveloperPrivateApiUnitTest, InstallDroppedFileZip) {
+class DeveloperPrivateApiZipFileUnitTest
+    : public DeveloperPrivateApiUnitTest,
+      public testing::WithParamInterface<bool> {
+ public:
+  void SetUp() override {
+    DeveloperPrivateApiUnitTest::SetUp();
+    const bool kFeatureEnabled = GetParam();
+    feature_list_.InitWithFeatureState(
+        extensions_features::kExtensionsZipFileInstalledInProfileDir,
+        kFeatureEnabled);
+    if (kFeatureEnabled) {
+      expected_extension_install_directory_ =
+          service()->unpacked_install_directory();
+    } else {
+      base::FilePath dir_temp;
+      ASSERT_TRUE(base::PathService::Get(base::DIR_TEMP, &dir_temp));
+      expected_extension_install_directory_ = dir_temp;
+    }
+  }
+
+ protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  base::FilePath expected_extension_install_directory_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    DeveloperPrivateApiZipFileUnitTest,
+    // extensions_features::kExtensionsZipFileInstalledInProfileDir enabled.
+    testing::Bool(),
+    [](const testing::TestParamInfo<
+        DeveloperPrivateApiZipFileUnitTest::ParamType>& info) {
+      return info.param ? "ProfileDir" : "TempDir";
+    });
+
+TEST_P(DeveloperPrivateApiZipFileUnitTest, InstallDroppedFileZip) {
   base::FilePath zip_path = data_dir().AppendASCII("simple_empty.zip");
   extensions::ExtensionInstallUI::set_disable_ui_for_tests();
   ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT);
@@ -1972,6 +2009,17 @@
       observer.WaitForExtensionInstalled();
   ASSERT_TRUE(extension);
   EXPECT_EQ("Simple Empty Extension", extension->name());
+
+  // Expect extension install directory to be immediate subdir of expected
+  // unpacked install directory. E.g. /a/b/c/d == /a/b/c + /d.
+  EXPECT_EQ(extension->path(), expected_extension_install_directory_.Append(
+                                   extension->path().BaseName()));
+
+  // Expect extension install directory to exist and be named with the right
+  // prefix.
+  EXPECT_TRUE(base::PathExists(extension->path()));
+  EXPECT_TRUE(
+      extension->path().BaseName().AsUTF8Unsafe().starts_with("simple_empty"));
 }
 
 // Test developerPrivate.getUserSiteSettings.
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
index 64c6f13b..bcfa485 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
@@ -39,6 +39,7 @@
 #include "chrome/browser/web_applications/web_app_id_constants.h"
 #include "chrome/browser/web_applications/web_app_install_params.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/webauthn/passkey_model_factory.h"
 #include "chrome/common/extensions/api/passwords_private.h"
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/constants/chromeos_features.h"
@@ -53,6 +54,7 @@
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/signin_metrics.h"
+#include "components/sync/base/features.h"
 #include "components/sync/service/sync_service.h"
 #include "components/url_formatter/elide_url.h"
 #include "content/public/browser/navigation_handle.h"
@@ -257,6 +259,16 @@
 #endif
 }
 
+// Returns a passkey model instance if the feature is enabled.
+PasskeyModel* MaybeGetPasskeyModel(Profile* profile) {
+  if (base::FeatureList::IsEnabled(
+          password_manager::features::kPasswordManagerPasskeys) &&
+      base::FeatureList::IsEnabled(syncer::kSyncWebauthnCredentials)) {
+    return PasskeyModelFactory::GetInstance()->GetForProfile(profile);
+  }
+  return nullptr;
+}
+
 }  // namespace
 
 namespace extensions {
@@ -270,7 +282,8 @@
               ServiceAccessType::EXPLICIT_ACCESS),
           AccountPasswordStoreFactory::GetForProfile(
               profile,
-              ServiceAccessType::EXPLICIT_ACCESS)),
+              ServiceAccessType::EXPLICIT_ACCESS),
+          MaybeGetPasskeyModel(profile)),
       password_manager_porter_(std::make_unique<PasswordManagerPorter>(
           profile,
           &saved_passwords_presenter_,
@@ -1049,8 +1062,12 @@
           return domainInfo;
         });
   }
+  entry.is_passkey = credential.is_passkey;
   entry.urls = extensions::CreateUrlCollectionFromCredential(credential);
   entry.username = base::UTF16ToUTF8(credential.username);
+  if (credential.is_passkey) {
+    entry.display_name = base::UTF16ToUTF8(credential.user_display_name);
+  }
   entry.stored_in = extensions::StoreSetFromCredential(credential);
   entry.is_android_credential = password_manager::IsValidAndroidFacetURI(
       credential.GetFirstSignonRealm());
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
index 6c196e16..8236d85 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
@@ -37,10 +37,12 @@
 #include "chrome/browser/web_applications/web_app_command_manager.h"
 #include "chrome/browser/web_applications/web_app_id_constants.h"
 #include "chrome/browser/webapps/chrome_webapps_client.h"
+#include "chrome/browser/webauthn/passkey_model_factory.h"
 #include "chrome/common/extensions/api/passwords_private.h"
 #include "chrome/test/base/test_browser_window.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/device_reauth/mock_device_authenticator.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "components/password_manager/content/browser/password_manager_log_router_factory.h"
 #include "components/password_manager/core/browser/affiliation/fake_affiliation_service.h"
 #include "components/password_manager/core/browser/insecure_credentials_table.h"
@@ -54,7 +56,9 @@
 #include "components/password_manager/core/browser/ui/import_results.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/signin/public/base/signin_metrics.h"
+#include "components/sync/base/features.h"
 #include "components/sync/test/test_sync_service.h"
+#include "components/webauthn/core/browser/test_passkey_model.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_renderer_host.h"
@@ -296,8 +300,10 @@
 }
 
 MATCHER_P(PasswordUiEntryDataEquals, expected, "") {
-  return testing::Value(expected.get().urls.link, arg.urls.link) &&
+  return testing::Value(expected.get().is_passkey, arg.is_passkey) &&
+         testing::Value(expected.get().urls.link, arg.urls.link) &&
          testing::Value(expected.get().username, arg.username) &&
+         testing::Value(expected.get().display_name, arg.display_name) &&
          testing::Value(expected.get().stored_in, arg.stored_in) &&
          testing::Value(expected.get().is_android_credential,
                         arg.is_android_credential);
@@ -360,6 +366,12 @@
       }));
   SetUpRouters();
   SetUpSyncInTransportMode(profile());
+  PasskeyModelFactory::GetInstance()->SetTestingFactoryAndUse(
+      profile(),
+      base::BindRepeating(
+          [](content::BrowserContext*) -> std::unique_ptr<KeyedService> {
+            return std::make_unique<TestPasskeyModel>();
+          }));
 }
 
 void PasswordsPrivateDelegateImplTest::SetUpPasswordStores(
@@ -1454,4 +1466,53 @@
   histogram_tester.ExpectUniqueSample("PasswordManager.ShortcutMetric", 1, 1);
 }
 
+TEST_F(PasswordsPrivateDelegateImplTest, GetPasskeyInGroups) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitWithFeatures(
+      {password_manager::features::kPasswordsGrouping,
+       password_manager::features::kPasswordManagerPasskeys,
+       syncer::kSyncWebauthnCredentials},
+      /*disabled_features=*/{});
+
+  auto delegate = CreateDelegate();
+
+  PasskeyModel* passkey_model = PasskeyModelFactory::GetForProfile(profile());
+  ASSERT_EQ(passkey_model, PasskeyModelFactory::GetForProfile(profile()));
+  ASSERT_TRUE(passkey_model);
+  sync_pb::WebauthnCredentialSpecifics passkey;
+  passkey.set_sync_id(base::RandBytesAsString(16));
+  passkey.set_credential_id(base::RandBytesAsString(16));
+  passkey.set_rp_id("abc1.com");
+  passkey.set_user_id({1, 2, 3, 4});
+  passkey.set_user_name("passkey_username");
+  passkey.set_user_display_name("passkey_display_name");
+  passkey_model->AddNewPasskeyForTesting(std::move(passkey));
+
+  password_manager::PasswordForm password = CreateSampleForm(
+      password_manager::PasswordForm::Store::kProfileStore, u"username1");
+  SetUpPasswordStores({password});
+
+  auto groups = delegate->GetCredentialGroups();
+  EXPECT_EQ(1u, groups.size());
+  EXPECT_EQ(2u, groups[0].entries.size());
+  EXPECT_EQ("abc1.com", groups[0].name);
+  EXPECT_EQ("https://abc1.com/favicon.ico", groups[0].icon_url);
+
+  api::passwords_private::PasswordUiEntry expected_entry1;
+  expected_entry1.urls.link = "https://abc1.com/";
+  expected_entry1.username = "username1";
+  expected_entry1.stored_in = api::passwords_private::PASSWORD_STORE_SET_DEVICE;
+  api::passwords_private::PasswordUiEntry expected_entry2;
+  expected_entry2.is_passkey = true;
+  expected_entry2.urls.link = "https://abc1.com/";
+  expected_entry2.username = "passkey_username";
+  expected_entry2.display_name = "passkey_display_name";
+  expected_entry2.stored_in =
+      api::passwords_private::PASSWORD_STORE_SET_ACCOUNT;
+  EXPECT_THAT(groups[0].entries,
+              testing::UnorderedElementsAre(
+                  PasswordUiEntryDataEquals(testing::ByRef(expected_entry1)),
+                  PasswordUiEntryDataEquals(testing::ByRef(expected_entry2))));
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_utils.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_utils.cc
index 2f5f3e30..68248fed 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_utils.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_utils.cc
@@ -6,6 +6,7 @@
 
 #include <tuple>
 
+#include "chrome/common/extensions/api/passwords_private.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_list_sorter.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
@@ -42,6 +43,9 @@
 
 extensions::api::passwords_private::PasswordStoreSet StoreSetFromCredential(
     const CredentialUIEntry& credential) {
+  if (credential.is_passkey) {
+    return extensions::api::passwords_private::PASSWORD_STORE_SET_ACCOUNT;
+  }
   if (credential.stored_in.contains(Store::kAccountStore) &&
       credential.stored_in.contains(Store::kProfileStore)) {
     return extensions::api::passwords_private::
diff --git a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
index 4d775228..956b8a1a 100644
--- a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
+++ b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
@@ -29,8 +29,8 @@
 #include "chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chromeos/ash/components/enhanced_network_tts/mojom/enhanced_network_tts.mojom.h"
-#include "chromeos/ash/components/language/language_packs/language_packs_impl.h"
-#include "chromeos/ash/components/language/public/mojom/language_packs.mojom.h"
+#include "chromeos/ash/components/language_packs/language_packs_impl.h"
+#include "chromeos/ash/components/language_packs/public/mojom/language_packs.mojom.h"
 #include "chromeos/ash/services/chromebox_for_meetings/public/cpp/appid_util.h"
 #include "chromeos/ash/services/chromebox_for_meetings/public/mojom/cfm_service_manager.mojom.h"
 #include "chromeos/components/remote_apps/mojom/remote_apps.mojom.h"
diff --git a/chrome/browser/extensions/extension_assets_manager.cc b/chrome/browser/extensions/extension_assets_manager.cc
index bb1abe9..c152950 100644
--- a/chrome/browser/extensions/extension_assets_manager.cc
+++ b/chrome/browser/extensions/extension_assets_manager.cc
@@ -42,10 +42,11 @@
 
   void UninstallExtension(const std::string& id,
                           const std::string& profile_user_name,
-                          const base::FilePath& local_install_dir,
-                          const base::FilePath& extension_root,
+                          const base::FilePath& extensions_install_dir,
+                          const base::FilePath& extension_dir_to_delete,
                           const base::FilePath& profile_dir) override {
-    file_util::UninstallExtension(profile_dir, local_install_dir, id);
+    file_util::UninstallExtension(profile_dir, extensions_install_dir,
+                                  extension_dir_to_delete);
   }
 
  private:
diff --git a/chrome/browser/extensions/extension_assets_manager.h b/chrome/browser/extensions/extension_assets_manager.h
index 86c45c3..60bbad6 100644
--- a/chrome/browser/extensions/extension_assets_manager.h
+++ b/chrome/browser/extensions/extension_assets_manager.h
@@ -41,10 +41,14 @@
       bool updates_from_webstore_or_empty_update_url) = 0;
 
   // Remove extension assets if it is not used by anyone else.
+  // `extensions_install_dir` is the path to where extensions of this type are
+  // being installed. E.g. "/path/to/Profile/Extensions".
+  // `extension_dir_to_delete` is the directory that should be deleted to
+  // uninstall the extension.
   virtual void UninstallExtension(const std::string& id,
                                   const std::string& profile_user_name,
-                                  const base::FilePath& local_install_dir,
-                                  const base::FilePath& extension_root,
+                                  const base::FilePath& extensions_install_dir,
+                                  const base::FilePath& extension_dir_to_delete,
                                   const base::FilePath& profile_dir) = 0;
 
  protected:
diff --git a/chrome/browser/extensions/extension_assets_manager_chromeos.cc b/chrome/browser/extensions/extension_assets_manager_chromeos.cc
index bd4adb6e..cac1e71 100644
--- a/chrome/browser/extensions/extension_assets_manager_chromeos.cc
+++ b/chrome/browser/extensions/extension_assets_manager_chromeos.cc
@@ -175,15 +175,16 @@
 void ExtensionAssetsManagerChromeOS::UninstallExtension(
     const std::string& id,
     const std::string& profile_user_name,
-    const base::FilePath& local_install_dir,
-    const base::FilePath& extension_root,
+    const base::FilePath& extensions_install_dir,
+    const base::FilePath& extension_dir_to_delete,
     const base::FilePath& profile_dir) {
-  if (local_install_dir.IsParent(extension_root)) {
-    file_util::UninstallExtension(profile_dir, local_install_dir, id);
+  if (extensions_install_dir.IsParent(extension_dir_to_delete)) {
+    file_util::UninstallExtension(profile_dir, extensions_install_dir,
+                                  extension_dir_to_delete);
     return;
   }
 
-  if (GetSharedInstallDir().IsParent(extension_root)) {
+  if (GetSharedInstallDir().IsParent(extension_dir_to_delete)) {
     // In some test extensions installed outside local_install_dir emulate
     // previous behavior that just do nothing in this case.
     content::GetUIThreadTaskRunner({})->PostTask(
diff --git a/chrome/browser/extensions/extension_assets_manager_chromeos.h b/chrome/browser/extensions/extension_assets_manager_chromeos.h
index 6325abb..3da1de0 100644
--- a/chrome/browser/extensions/extension_assets_manager_chromeos.h
+++ b/chrome/browser/extensions/extension_assets_manager_chromeos.h
@@ -51,8 +51,8 @@
       bool updates_from_webstore_or_empty_update_url) override;
   void UninstallExtension(const std::string& id,
                           const std::string& profile_user_name,
-                          const base::FilePath& local_install_dir,
-                          const base::FilePath& extension_root,
+                          const base::FilePath& extensions_install_dir,
+                          const base::FilePath& extension_dir_to_delete,
                           const base::FilePath& profile_dir) override;
 
   // Return shared install dir.
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc
index af616bc..f35103e 100644
--- a/chrome/browser/extensions/extension_context_menu_model.cc
+++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -593,21 +593,11 @@
   // We store the origin to make sure it's the same when executing page access
   // commands.
   origin_ = url::Origin::Create(url);
-
   auto* permissions_manager = PermissionsManager::Get(profile_);
 
   if (base::FeatureList::IsEnabled(
           extensions_features::kExtensionsMenuAccessControl)) {
-    auto add_page_access_secondary_buttons = [](ui::SimpleMenuModel* parent) {
-      parent->AddSeparator(ui::NORMAL_SEPARATOR);
-      parent->AddItemWithStringId(
-          PAGE_ACCESS_PERMISSIONS_PAGE,
-          IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_PERMISSIONS_PAGE);
-      parent->AddItemWithStringId(
-          PAGE_ACCESS_LEARN_MORE,
-          IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_LEARN_MORE);
-    };
-
+    bool add_separator_for_permissions_page = true;
     // User site setting takes preference over extension settings. Therefore, we
     // only show the page access submenu with change extension settings options
     // if the site settings is set to "customize by extension". Otherwise, shows
@@ -620,8 +610,7 @@
             l10n_util::GetStringFUTF16(
                 IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_ALL_EXTENSIONS_GRANTED,
                 GetCurrentSite(url)));
-        add_page_access_secondary_buttons(this);
-        return;
+        break;
 
       case PermissionsManager::UserSiteSetting::kBlockAllExtensions:
         AddItem(
@@ -629,18 +618,17 @@
             l10n_util::GetStringFUTF16(
                 IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_ALL_EXTENSIONS_BLOCKED,
                 GetCurrentSite(url)));
-        add_page_access_secondary_buttons(this);
-        return;
+        break;
 
       case PermissionsManager::UserSiteSetting::kCustomizeByExtension:
-        // The extension wants site access but cant't run on the page if it does
+        // The extension wants site access but can't run on the page if it does
         // not have at least "on click" access.
         if (!permissions_manager->CanUserSelectSiteAccess(
                 *extension, url,
                 PermissionsManager::UserSiteAccess::kOnClick)) {
           AddItemWithStringId(PAGE_ACCESS_CANT_ACCESS,
                               IDS_EXTENSIONS_CONTEXT_MENU_CANT_ACCESS_PAGE);
-          return;
+          break;
         }
 
         // The extension wants site access and can ran on the page.  Add the
@@ -662,14 +650,25 @@
             PAGE_ACCESS_RUN_ON_ALL_SITES,
             IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_ALL_SITES_V2,
             kRadioGroup);
-        add_page_access_secondary_buttons(page_access_submenu_.get());
 
         AddSubMenuWithStringId(PAGE_ACCESS_SUBMENU,
-                               IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS,
+                               IDS_EXTENSIONS_CONTEXT_MENU_SITE_PERMISSIONS,
                                page_access_submenu_.get());
+
+        // Permissions page entry should be in the same section (no separator)
+        // when the site permissions submenu is present.
+        add_separator_for_permissions_page = false;
+        break;
     }
+
+    if (add_separator_for_permissions_page) {
+      AddSeparator(ui::NORMAL_SEPARATOR);
+    }
+    AddItemWithStringId(
+        PAGE_ACCESS_PERMISSIONS_PAGE,
+        IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_PERMISSIONS_PAGE);
   } else {
-    // The extension wants site access but cant't run on the page if it does
+    // The extension wants site access but can't run on the page if it does
     // not have at least "on click" access.
     if (!permissions_manager->CanUserSelectSiteAccess(
             *extension, url, PermissionsManager::UserSiteAccess::kOnClick)) {
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
index 9abf81f..d2ca4fd 100644
--- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc
+++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -1971,6 +1971,7 @@
 
 TEST_P(ExtensionContextMenuModelWithUserHostControlsTest,
        PageAccessItemsVisibilityBasedOnSiteSettings) {
+  bool is_feature_enabled = GetParam();
   InitializeEmptyExtensionService();
 
   const Extension* extension =
@@ -1983,8 +1984,8 @@
 
   {
     // By default, the site permission is set to "customize by extension".
-    // Verify page access submenu is visible and enabled, and the "learn more"
-    // item is in in the submenu.
+    // Verify "page access" submenu item and "permissions page" item are visible
+    // and enabled.
     ExtensionContextMenuModel menu(extension, GetBrowser(),
                                    ExtensionContextMenuModel::PINNED, nullptr,
                                    true, ContextMenuSource::kToolbarAction);
@@ -1994,16 +1995,16 @@
               CommandState::kAbsent);
     EXPECT_EQ(GetCommandState(menu, kPageAccessSubmenu),
               CommandState::kEnabled);
-    EXPECT_EQ(GetCommandState(menu, kLearnMore), CommandState::kAbsent);
-    EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
-              CommandState::kEnabled);
-    // The "permissions page" item is in the submenu only if the feature is
-    // enabled.
-    EXPECT_EQ(GetCommandState(menu, kPermissionsPage), CommandState::kAbsent);
-    CommandState permission_page_state =
-        GetParam() ? CommandState::kEnabled : CommandState::kAbsent;
-    EXPECT_EQ(GetPageAccessCommandState(menu, kPermissionsPage),
-              permission_page_state);
+    if (is_feature_enabled) {
+      EXPECT_EQ(GetCommandState(menu, kPermissionsPage),
+                CommandState::kEnabled);
+      EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
+                CommandState::kAbsent);
+    } else {
+      EXPECT_EQ(GetCommandState(menu, kPermissionsPage), CommandState::kAbsent);
+      EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
+                CommandState::kEnabled);
+    }
   }
 
   // User site settings are only taken into account for site access computations
@@ -2022,21 +2023,19 @@
                                    ExtensionContextMenuModel::PINNED, nullptr,
                                    true, ContextMenuSource::kToolbarAction);
 
-    if (GetParam()) {
-      // Verify "block all extensions" item is
-      // visible and disabled, and the "learn more" and "permissions page" item
-      // are in the context menu.
+    if (is_feature_enabled) {
+      // Verify "block all extensions" item is visible and disabled, and
+      // "permissions page" is enabled in the context menu. "learn more" is
+      // never visible.
       EXPECT_EQ(GetCommandState(menu, kGrantAllExtensions),
                 CommandState::kAbsent);
       EXPECT_EQ(GetCommandState(menu, kBlockAllExtensions),
                 CommandState::kDisabled);
       EXPECT_EQ(GetCommandState(menu, kPageAccessSubmenu),
                 CommandState::kAbsent);
-      EXPECT_EQ(GetCommandState(menu, kLearnMore), CommandState::kEnabled);
-      EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
-                CommandState::kAbsent);
       EXPECT_EQ(GetCommandState(menu, kPermissionsPage),
                 CommandState::kEnabled);
+      EXPECT_EQ(GetCommandState(menu, kLearnMore), CommandState::kAbsent);
       EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
                 CommandState::kAbsent);
     } else {
@@ -2093,8 +2092,7 @@
     return;
   }
 
-  EXPECT_EQ(GetPageAccessCommandState(menu, kPermissionsPage),
-            CommandState::kEnabled);
+  EXPECT_EQ(GetCommandState(menu, kPermissionsPage), CommandState::kEnabled);
   menu.ExecuteCommand(kPermissionsPage, 0);
 
   EXPECT_EQ(browser->tab_strip_model()->count(), 2);
@@ -2131,6 +2129,7 @@
 
 TEST_P(ExtensionContextMenuModelWithUserHostControlsAndPermittedSitesTest,
        PageAccessItemsVisibilityBasedOnSiteSettings) {
+  bool is_feature_enabled = GetParam();
   InitializeEmptyExtensionService();
 
   const Extension* extension =
@@ -2143,8 +2142,7 @@
 
   {
     // By default, the site permission is set to "customize by extension".
-    // Verify page access submenu is visible and enabled, and the "learn more"
-    // item is in in the submenu.
+    // Verify "page access" submenu item is visible and enabled.
     ExtensionContextMenuModel menu(extension, GetBrowser(),
                                    ExtensionContextMenuModel::PINNED, nullptr,
                                    true, ContextMenuSource::kToolbarAction);
@@ -2154,16 +2152,16 @@
               CommandState::kAbsent);
     EXPECT_EQ(GetCommandState(menu, kPageAccessSubmenu),
               CommandState::kEnabled);
-    EXPECT_EQ(GetCommandState(menu, kLearnMore), CommandState::kAbsent);
-    EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
-              CommandState::kEnabled);
-    // The "permissions page" item is in the submenu only if the feature is
-    // enabled.
-    EXPECT_EQ(GetCommandState(menu, kPermissionsPage), CommandState::kAbsent);
-    CommandState permission_page_state =
-        GetParam() ? CommandState::kEnabled : CommandState::kAbsent;
-    EXPECT_EQ(GetPageAccessCommandState(menu, kPermissionsPage),
-              permission_page_state);
+    if (is_feature_enabled) {
+      EXPECT_EQ(GetCommandState(menu, kPermissionsPage),
+                CommandState::kEnabled);
+      EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
+                CommandState::kAbsent);
+    } else {
+      EXPECT_EQ(GetCommandState(menu, kPermissionsPage), CommandState::kAbsent);
+      EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
+                CommandState::kEnabled);
+    }
   }
 
   // User site settings are only taken into account for site access computations
@@ -2182,20 +2180,19 @@
                                    ExtensionContextMenuModel::PINNED, nullptr,
                                    true, ContextMenuSource::kToolbarAction);
 
-    if (GetParam()) {
-      // Verify "grant all extensions" item is visible and disabled, and the
-      // "learn more" and "permissions page" item are in the context menu.
+    if (is_feature_enabled) {
+      // Verify "grant all extensions" item is visible and disabled, and
+      // "permissions page" is enabled in the context menu. "learn more" is
+      // never visible.
       EXPECT_EQ(GetCommandState(menu, kGrantAllExtensions),
                 CommandState::kDisabled);
       EXPECT_EQ(GetCommandState(menu, kBlockAllExtensions),
                 CommandState::kAbsent);
       EXPECT_EQ(GetCommandState(menu, kPageAccessSubmenu),
                 CommandState::kAbsent);
-      EXPECT_EQ(GetCommandState(menu, kLearnMore), CommandState::kEnabled);
-      EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
-                CommandState::kAbsent);
       EXPECT_EQ(GetCommandState(menu, kPermissionsPage),
                 CommandState::kEnabled);
+      EXPECT_EQ(GetCommandState(menu, kLearnMore), CommandState::kAbsent);
       EXPECT_EQ(GetPageAccessCommandState(menu, kLearnMore),
                 CommandState::kAbsent);
     } else {
diff --git a/chrome/browser/extensions/extension_garbage_collector.cc b/chrome/browser/extensions/extension_garbage_collector.cc
index 1909886f..dfb0277 100644
--- a/chrome/browser/extensions/extension_garbage_collector.cc
+++ b/chrome/browser/extensions/extension_garbage_collector.cc
@@ -27,6 +27,7 @@
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/install_tracker.h"
 #include "chrome/browser/extensions/pending_extension_manager.h"
+#include "chrome/browser/profiles/profile.h"
 #include "components/crx_file/id_util.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
@@ -37,6 +38,7 @@
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extension_util.h"
 #include "extensions/common/extension.h"
+#include "extensions/common/extension_features.h"
 #include "extensions/common/file_util.h"
 
 namespace extensions {
@@ -105,6 +107,28 @@
   }
 }
 
+// Deletes uninstalled extensions in the unpacked directory.
+// Installed unpacked extensions are not saved in the same directory structure
+// as packed extensions. For example they have no version subdirs and their root
+// folders are not named with the extension's ID, so we can't use the same logic
+// as packed extensions when deleting them. Note: This is meant to only handle
+// unpacked .zip installs and should not be called for an `extension_directory`
+// outside the profile directory because if `extension_directory` is not in
+// `installed_extension_dirs` we'll delete it. Currently there's some certainty
+// that `extension_directory` will not be outside the profile directory.
+void CheckUnpackedExtensionDirectory(
+    const base::FilePath& extension_directory,
+    const ExtensionPathsMultimap& installed_extension_dirs) {
+  // Check to see if the extension is installed and don't proceed if it is.
+  for (auto const& [_, installed_extension_dir] : installed_extension_dirs) {
+    if (extension_directory == installed_extension_dir) {
+      return;
+    }
+  }
+
+  base::DeletePathRecursively(extension_directory);
+}
+
 }  // namespace
 
 ExtensionGarbageCollector::ExtensionGarbageCollector(
@@ -147,9 +171,8 @@
 // static
 void ExtensionGarbageCollector::GarbageCollectExtensionsOnFileThread(
     const base::FilePath& install_directory,
-    const ExtensionPathsMultimap& extension_paths) {
-  DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-
+    const ExtensionPathsMultimap& extension_paths,
+    bool unpacked) {
   // Nothing to clean up if it doesn't exist.
   if (!base::DirectoryExists(install_directory))
     return;
@@ -161,7 +184,8 @@
   for (base::FilePath extension_path = enumerator.Next();
        !extension_path.empty();
        extension_path = enumerator.Next()) {
-    CheckExtensionDirectory(extension_path, extension_paths);
+    unpacked ? CheckUnpackedExtensionDirectory(extension_path, extension_paths)
+             : CheckExtensionDirectory(extension_path, extension_paths);
   }
 }
 
@@ -186,6 +210,12 @@
     return;
   }
 
+  // TODO(crbug.com/1378775): Since the GC recursively deletes, insert a check
+  // so that we can't attempt to delete outside the profile directory. The
+  // problem is that in extension_garbage_collector_unittest.cc the directory
+  // containing the extension installs is not a direct subdir of the profile
+  // directory whereas this is true in production. So we can't do a simple check
+  // like that to ensure we're inside the profile directory.
   ExtensionPrefs::ExtensionsInfo extensions_info =
       extension_prefs->GetInstalledExtensionsInfo();
   std::multimap<std::string, base::FilePath> extension_paths;
@@ -203,9 +233,20 @@
   ExtensionService* service =
       ExtensionSystem::Get(context_)->extension_service();
   if (!GetExtensionFileTaskRunner()->PostTask(
-          FROM_HERE,
-          base::BindOnce(&GarbageCollectExtensionsOnFileThread,
-                         service->install_directory(), extension_paths))) {
+          FROM_HERE, base::BindOnce(&GarbageCollectExtensionsOnFileThread,
+                                    service->install_directory(),
+                                    extension_paths, /*unpacked=*/false))) {
+    NOTREACHED();
+  }
+
+  if (!base::FeatureList::IsEnabled(
+          extensions_features::kExtensionsZipFileInstalledInProfileDir)) {
+    return;
+  }
+  if (!GetExtensionFileTaskRunner()->PostTask(
+          FROM_HERE, base::BindOnce(&GarbageCollectExtensionsOnFileThread,
+                                    service->unpacked_install_directory(),
+                                    extension_paths, /*unpacked=*/true))) {
     NOTREACHED();
   }
 }
diff --git a/chrome/browser/extensions/extension_garbage_collector.h b/chrome/browser/extensions/extension_garbage_collector.h
index c8b64e8..2934d297 100644
--- a/chrome/browser/extensions/extension_garbage_collector.h
+++ b/chrome/browser/extensions/extension_garbage_collector.h
@@ -78,7 +78,8 @@
 
   static void GarbageCollectExtensionsOnFileThread(
       const base::FilePath& install_directory,
-      const std::multimap<std::string, base::FilePath>& extension_paths);
+      const std::multimap<std::string, base::FilePath>& extension_paths,
+      bool unpacked);
 
   // The BrowserContext associated with the GarbageCollector.
   raw_ptr<content::BrowserContext> context_;
diff --git a/chrome/browser/extensions/extension_garbage_collector_chromeos.cc b/chrome/browser/extensions/extension_garbage_collector_chromeos.cc
index f54c6aa..f9589336 100644
--- a/chrome/browser/extensions/extension_garbage_collector_chromeos.cc
+++ b/chrome/browser/extensions/extension_garbage_collector_chromeos.cc
@@ -82,8 +82,10 @@
             FROM_HERE,
             base::BindOnce(
                 &GarbageCollectExtensionsOnFileThread,
-                ExtensionAssetsManagerChromeOS::GetSharedInstallDir(),
-                paths))) {
+                ExtensionAssetsManagerChromeOS::GetSharedInstallDir(), paths,
+                // No need to process unpacked because shared extensions can't
+                // be unpacked.
+                /*unpacked=*/false))) {
       NOTREACHED();
     }
   }
diff --git a/chrome/browser/extensions/extension_garbage_collector_unittest.cc b/chrome/browser/extensions/extension_garbage_collector_unittest.cc
index e93ff582..4fc772c 100644
--- a/chrome/browser/extensions/extension_garbage_collector_unittest.cc
+++ b/chrome/browser/extensions/extension_garbage_collector_unittest.cc
@@ -20,6 +20,7 @@
 #include "content/public/test/test_utils.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/pref_names.h"
+#include "extensions/common/extension_features.h"
 #include "ppapi/buildflags/buildflags.h"
 
 #if BUILDFLAG(ENABLE_PLUGINS)
@@ -45,10 +46,14 @@
     // Wait for GarbageCollectExtensions task to complete.
     content::RunAllTasksUntilIdle();
   }
+
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 // Test that partially deleted extensions are cleaned up during startup.
 TEST_F(ExtensionGarbageCollectorUnitTest, CleanupOnStartup) {
+  feature_list_.InitAndDisableFeature(
+      extensions_features::kExtensionsZipFileInstalledInProfileDir);
   const std::string kExtensionId = "behllobkkfkfnphdnhnkndlbkcpglgmj";
 
   InitPluginService();
@@ -79,6 +84,83 @@
   ASSERT_FALSE(base::PathExists(extension_dir));
 }
 
+// TODO(crbug.com/1378775): The test extension good_juKvIh seems to error on
+// install with "Manifest file is missing or unreadable" despite the manifest
+// being valid. This test case is still valid because we're only checking if the
+// files get deleted. The files get copied to the install directory by the test
+// infra despite the installation failure. So we should probably fix this in the
+// future so that this test extension can be used in other tests.
+
+// Test that partially deleted unpacked extensions (e.g. from .zips) are cleaned
+// up during startup.
+TEST_F(ExtensionGarbageCollectorUnitTest,
+       CleanupUnpackedOnStartup_DeleteWhenNoLongerInstalled) {
+  feature_list_.InitAndEnableFeature(
+      extensions_features::kExtensionsZipFileInstalledInProfileDir);
+  const std::string kExtensionId = "lckcjklfapeiadkadngidmocpbkemckm";
+
+  InitPluginService();
+  InitializeGoodInstalledExtensionService();
+  base::FilePath zipped_extension_dir =
+      unpacked_install_dir().AppendASCII("good_juKvIh");
+  ASSERT_TRUE(base::PathExists(zipped_extension_dir));
+
+  // Simulate that the extensions was partially deleted (no longer considered
+  // installed) by clearing its pref.
+  {
+    ScopedDictPrefUpdate update(profile_->GetPrefs(), pref_names::kExtensions);
+    update->Remove(kExtensionId);
+  }
+
+  service_->Init();
+  GarbageCollectExtensions();
+
+  base::FileEnumerator dirs(unpacked_install_dir(),
+                            false,  // not recursive
+                            base::FileEnumerator::DIRECTORIES);
+
+  // We should have have zero extensions now.
+  EXPECT_TRUE(dirs.Next().empty());
+
+  // And unpacked extension dir should now be toast.
+  EXPECT_FALSE(base::PathExists(zipped_extension_dir));
+}
+
+TEST_F(ExtensionGarbageCollectorUnitTest,
+       CleanupUnpackedOnStartup_DoNotDeleteWhenStillInstalled) {
+  feature_list_.InitAndEnableFeature(
+      extensions_features::kExtensionsZipFileInstalledInProfileDir);
+  const std::string kExtensionId = "lckcjklfapeiadkadngidmocpbkemckm";
+
+  InitPluginService();
+  InitializeGoodInstalledExtensionService();
+  base::FilePath zipped_extension_dir =
+      unpacked_install_dir().AppendASCII("good_juKvIh");
+  ASSERT_TRUE(base::PathExists(zipped_extension_dir));
+
+  // Update the path of the installed extension to be accurate for the test.
+  {
+    ScopedDictPrefUpdate update(profile_->GetPrefs(), pref_names::kExtensions);
+    base::Value::Dict& update_dict = update.Get();
+    // An unpacked extension installed in the profile dir in production usually
+    // has it's full install path written to the "path" key, but since we don't
+    // know what the path is during the test (due to variation of test directory
+    // location) we need to manually set it during the test. The garbage
+    // collection checks this path to determine whether to delete the
+    // installation directory.
+    base::Value::Dict* extension_entry = update_dict.FindDict(kExtensionId);
+    ASSERT_TRUE(extension_entry);
+    extension_entry->Set("path",
+                         base::Value(zipped_extension_dir.MaybeAsASCII()));
+  }
+
+  service_->Init();
+  GarbageCollectExtensions();
+
+  // Unpacked extension dir should not be deleted.
+  EXPECT_TRUE(base::PathExists(zipped_extension_dir));
+}
+
 // Test that garbage collection doesn't delete anything while a crx is being
 // installed.
 TEST_F(ExtensionGarbageCollectorUnitTest, NoCleanupDuringInstall) {
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index ae453c6..dcc7318 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -76,6 +76,7 @@
 #include "chrome/common/url_constants.h"
 #include "components/crx_file/id_util.h"
 #include "components/favicon_base/favicon_url_parser.h"
+#include "components/supervised_user/core/common/buildflags.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
@@ -160,6 +161,21 @@
 // ExtensionUnpublishedAvailability policy default value.
 constexpr int kAllowUnpublishedExtensions = 0;
 
+// When uninstalling an extension determine if the extension's directory
+// should be deleted when uninstalling. Returns `true` iff extension is
+// unpacked and installed outside the unpacked extensions installations dir.
+// Example: packed extensions are always deleted. But unpacked extensions are
+// in a folder outside the profile dir are not deleted.
+bool SkipDeleteExtensionDir(const Extension& extension,
+                            const base::FilePath& profile_path) {
+  bool is_unpacked_location =
+      Manifest::IsUnpackedLocation(extension.location());
+  bool extension_dir_not_direct_subdir_of_unpacked_extensions_install_dir =
+      extension.path().DirName() !=
+      profile_path.AppendASCII(extensions::kUnpackedInstallDirectoryName);
+  return is_unpacked_location &&
+         extension_dir_not_direct_subdir_of_unpacked_extensions_install_dir;
+}
 }  // namespace
 
 // ExtensionService.
@@ -832,13 +848,25 @@
         base::BarrierClosure(num_tasks, std::move(done_callback));
   }
 
-  // Tell the backend to start deleting installed extensions on the file thread.
-  if (!is_unpacked_location) {
+  // Delete extensions in profile directory (from webstore, or from .crx), but
+  // do not delete unpacked in a folder outside the profile directory.
+  if (!SkipDeleteExtensionDir(*extension, profile_->GetPath())) {
+    // Extensions installed from webstore or .crx are versioned in subdirs so we
+    // delete the parent dir. Unpacked (installed from .zip rather than folder)
+    // are not versioned so we just delete the single installation directory.
+    base::FilePath deletion_dir =
+        is_unpacked_location ? extension->path() : extension->path().DirName();
+
+    // Tell the backend to start deleting installed extension on the file
+    // thread.
     if (!GetExtensionFileTaskRunner()->PostTaskAndReply(
             FROM_HERE,
             base::BindOnce(&ExtensionService::UninstallExtensionOnFileThread,
                            extension->id(), profile_->GetProfileUserName(),
-                           install_directory_, extension->path(),
+                           /*extensions_install_dir=*/
+                           is_unpacked_location ? unpacked_install_directory_
+                                                : install_directory_,
+                           /*extension_dir_to_delete=*/std::move(deletion_dir),
                            profile_->GetPath()),
             subtask_done_callback)) {
       NOTREACHED();
@@ -864,13 +892,14 @@
 void ExtensionService::UninstallExtensionOnFileThread(
     const std::string& id,
     const std::string& profile_user_name,
-    const base::FilePath& install_dir,
-    const base::FilePath& extension_path,
+    const base::FilePath& extensions_install_dir,
+    const base::FilePath& extension_dir_to_delete,
     const base::FilePath& profile_dir) {
   ExtensionAssetsManager* assets_manager =
       ExtensionAssetsManager::GetInstance();
-  assets_manager->UninstallExtension(id, profile_user_name, install_dir,
-                                     extension_path, profile_dir);
+  assets_manager->UninstallExtension(id, profile_user_name,
+                                     extensions_install_dir,
+                                     extension_dir_to_delete, profile_dir);
 }
 
 bool ExtensionService::IsExtensionEnabled(
diff --git a/chrome/browser/extensions/extension_service_test_base.cc b/chrome/browser/extensions/extension_service_test_base.cc
index 06baa8a..fcc0170 100644
--- a/chrome/browser/extensions/extension_service_test_base.cc
+++ b/chrome/browser/extensions/extension_service_test_base.cc
@@ -125,6 +125,32 @@
     }
   }
 
+  // Only perform cleanup and copying of unpacked extensions if the path exists
+  // for the test since this is less common than for packed extensions.
+  if (base::PathExists(params.unpacked_extensions_dir)) {
+    base::FilePath unpacked_extensions_install_dir =
+        profile_dir.AppendASCII(extensions::kUnpackedInstallDirectoryName);
+    if (!base::DeletePathRecursively(unpacked_extensions_install_dir)) {
+      LOG(ERROR) << "Failed to clean unpacked extensions directory";
+      return nullptr;
+    }
+    if (params.unpacked_extensions_dir.empty()) {
+      if (base::File::Error error = base::File::FILE_OK;
+          !base::CreateDirectoryAndGetError(unpacked_extensions_install_dir,
+                                            &error)) {
+        LOG(ERROR) << "Failed to create unpacked extensions directory: "
+                   << error;
+        return nullptr;
+      }
+    } else {
+      if (!base::CopyDirectory(params.unpacked_extensions_dir,
+                               unpacked_extensions_install_dir, true)) {
+        LOG(ERROR) << "Failed to copy unpacked extensions directory";
+        return nullptr;
+      }
+    }
+  }
+
   if (params.profile_is_supervised) {
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
     profile_builder.SetIsSupervisedProfile();
@@ -187,6 +213,8 @@
     return false;
   }
   extensions_dir = filepath.AppendASCII(extensions::kInstallDirectoryName);
+  unpacked_extensions_dir =
+      filepath.AppendASCII(extensions::kUnpackedInstallDirectoryName);
   return true;
 }
 
@@ -226,6 +254,8 @@
   profile_ = BuildTestingProfile(params, temp_dir_, policy_service_.get());
   extensions_install_dir_ =
       profile_->GetPath().AppendASCII(extensions::kInstallDirectoryName);
+  unpacked_install_dir_ = profile_->GetPath().AppendASCII(
+      extensions::kUnpackedInstallDirectoryName);
 
   CreateExtensionService(params);
   registry_ = ExtensionRegistry::Get(profile());
@@ -403,7 +433,8 @@
 
   service_ = system->CreateExtensionService(
       base::CommandLine::ForCurrentProcess(), extensions_install_dir_,
-      params.autoupdate_enabled, params.extensions_enabled);
+      unpacked_install_dir_, params.autoupdate_enabled,
+      params.extensions_enabled);
 
   service_->component_loader()->set_ignore_allowlist_for_testing(true);
 
diff --git a/chrome/browser/extensions/extension_service_test_base.h b/chrome/browser/extensions/extension_service_test_base.h
index 8e1c1d4..6e04679f 100644
--- a/chrome/browser/extensions/extension_service_test_base.h
+++ b/chrome/browser/extensions/extension_service_test_base.h
@@ -16,6 +16,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/common/chrome_constants.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
 #include "components/policy/core/common/policy_service.h"
@@ -68,9 +69,9 @@
     // If not, sync_preferences::TestingPrefServiceSyncable is used.
     absl::optional<std::string> prefs_content;
 
-    // If not empty, copies the directory to the profile's extension
-    // directory.
+    // If not empty, copies both directories to the profile directory.
     base::FilePath extensions_dir;
+    base::FilePath unpacked_extensions_dir;
 
     bool autoupdate_enabled = false;
     bool extensions_enabled = true;
@@ -159,6 +160,9 @@
   const base::FilePath& extensions_install_dir() const {
     return extensions_install_dir_;
   }
+  const base::FilePath& unpacked_install_dir() const {
+    return unpacked_install_dir_;
+  }
   const base::FilePath& data_dir() const { return data_dir_; }
   const base::ScopedTempDir& temp_dir() const { return temp_dir_; }
   content::BrowserTaskEnvironment* task_environment() {
@@ -220,6 +224,8 @@
 
   // The directory into which extensions are installed.
   base::FilePath extensions_install_dir_;
+  // The directory into which unpacked extensions are installed.
+  base::FilePath unpacked_install_dir_;
 
   // chrome/test/data/extensions/
   base::FilePath data_dir_;
diff --git a/chrome/browser/extensions/extension_service_test_with_install.cc b/chrome/browser/extensions/extension_service_test_with_install.cc
index d7e39c97..cb4c919 100644
--- a/chrome/browser/extensions/extension_service_test_with_install.cc
+++ b/chrome/browser/extensions/extension_service_test_with_install.cc
@@ -330,10 +330,13 @@
 }
 
 void ExtensionServiceTestWithInstall::UninstallExtension(
-    const std::string& id) {
+    const std::string& id,
+    UninstallExtensionFileDeleteType delete_type) {
   // Verify that the extension is installed.
-  ASSERT_TRUE(registry()->GetExtensionById(id, ExtensionRegistry::EVERYTHING));
-  base::FilePath extension_path = extensions_install_dir().AppendASCII(id);
+  const Extension* extension =
+      registry()->GetExtensionById(id, ExtensionRegistry::EVERYTHING);
+  ASSERT_TRUE(extension);
+  base::FilePath extension_path = base::FilePath(extension->path());
   EXPECT_TRUE(base::PathExists(extension_path));
   ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
   EXPECT_TRUE(prefs->GetInstalledExtensionInfo(id));
@@ -353,10 +356,19 @@
   // The extension should not be in the service anymore.
   EXPECT_FALSE(registry()->GetInstalledExtension(extension_id));
   EXPECT_FALSE(prefs->GetInstalledExtensionInfo(extension_id));
-  content::RunAllTasksUntilIdle();
+  task_environment()->RunUntilIdle();
 
-  // The directory should be gone.
-  EXPECT_FALSE(base::PathExists(extension_path));
+  switch (delete_type) {
+    case kDeleteAllVersions:
+      EXPECT_FALSE(base::PathExists(extension_path.DirName()));
+      break;
+    case kDeletePath:
+      EXPECT_FALSE(base::PathExists(extension_path));
+      break;
+    case kDoNotDelete:
+      EXPECT_TRUE(base::PathExists(extension_path));
+      break;
+  }
 }
 
 void ExtensionServiceTestWithInstall::TerminateExtension(
diff --git a/chrome/browser/extensions/extension_service_test_with_install.h b/chrome/browser/extensions/extension_service_test_with_install.h
index fcc3906..06b32362 100644
--- a/chrome/browser/extensions/extension_service_test_with_install.h
+++ b/chrome/browser/extensions/extension_service_test_with_install.h
@@ -124,7 +124,18 @@
                        const base::FilePath& in_path,
                        UpdateState expected_state);
 
-  void UninstallExtension(const std::string& id);
+  enum UninstallExtensionFileDeleteType {
+    kDeletePath,         // Delete the exact path of the extension install.
+    kDeleteAllVersions,  // Delete all version of the extension (e.g. delete the
+                         // root of the install folder).
+    kDoNotDelete,        // Do not delete any of the extension's files.
+  };
+
+  // Uninstalls extension with `id` and expects deletion of the extension's
+  // files according to `delete_type`.
+  void UninstallExtension(
+      const std::string& id,
+      UninstallExtensionFileDeleteType delete_type = kDeleteAllVersions);
 
   void TerminateExtension(const std::string& id);
 
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 04c9912..73b1c96 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -25,6 +25,7 @@
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/one_shot_event.h"
+#include "base/path_service.h"
 #include "base/ranges/algorithm.h"
 #include "base/run_loop.h"
 #include "base/strings/pattern.h"
@@ -47,6 +48,7 @@
 #include "chrome/browser/extensions/chrome_app_sorting.h"
 #include "chrome/browser/extensions/chrome_extension_cookies.h"
 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
+#include "chrome/browser/extensions/chrome_zipfile_installer.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_error_ui.h"
@@ -85,6 +87,7 @@
 #include "chrome/browser/ui/global_error/global_error_waiter.h"
 #include "chrome/browser/web_applications/preinstalled_app_install_features.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/common/pref_names.h"
@@ -116,6 +119,7 @@
 #include "extensions/browser/blocklist_state.h"
 #include "extensions/browser/disable_reason.h"
 #include "extensions/browser/extension_creator.h"
+#include "extensions/browser/extension_file_task_runner.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
@@ -131,6 +135,7 @@
 #include "extensions/browser/uninstall_reason.h"
 #include "extensions/browser/updater/extension_downloader_test_helper.h"
 #include "extensions/browser/updater/null_extension_cache.h"
+#include "extensions/browser/zipfile_installer.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/extension_features.h"
@@ -603,12 +608,14 @@
                               const Extension* extension,
                               UninstallReason reason) override {
     last_extension_uninstalled = extension->id();
+    last_extension_uninstalled_path = extension->path();
   }
 
   std::string last_extension_loaded;
   std::string last_extension_unloaded;
   std::string last_extension_installed;
   std::string last_extension_uninstalled;
+  base::FilePath last_extension_uninstalled_path;
 };
 
 class ExtensionLoadedObserver : public ExtensionRegistryObserver {
@@ -958,7 +965,7 @@
       registry()->enabled_extensions().GetByID(loaded_extensions()[0]->id()));
   EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
 
-  ValidatePrefKeyCount(3);
+  ValidatePrefKeyCount(4);
   ValidateIntegerPref(good0, "state", Extension::ENABLED);
   ValidateIntegerPref(good0, "location",
                       static_cast<int>(ManifestLocation::kInternal));
@@ -5175,26 +5182,156 @@
   EXPECT_EQ(0u, registry()->disabled_extensions().size());
 }
 
-TEST_F(ExtensionServiceTest, UninstallExtension) {
-  InitializeEmptyExtensionService();
-  InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
+// TODO(jlulejian): Reuse this in other places in this file.
+// Test class that sets up an empty extension service before the test starts.
+class ExtensionServiceWithEmptyServiceTest : public ExtensionServiceTest {
+ public:
+  void SetUp() override {
+    ExtensionServiceTest::SetUp();
+    InitializeEmptyExtensionService();
+  }
+};
+
+TEST_F(ExtensionServiceWithEmptyServiceTest, UninstallExtensionFromWebstore) {
+  const Extension* extension =
+      InstallCRXFromWebStore(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
+  EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
   EXPECT_EQ(1u, registry()->enabled_extensions().size());
+
   UninstallExtension(good_crx);
-  EXPECT_EQ(0u, registry()->enabled_extensions().size());
+  EXPECT_TRUE(registry()->enabled_extensions().empty());
   EXPECT_EQ(UnloadedExtensionReason::UNINSTALL, unloaded_reason());
 }
 
-TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
-  InitializeEmptyExtensionService();
+TEST_F(ExtensionServiceWithEmptyServiceTest, UninstallExtensionFromCrx) {
+  const Extension* extension =
+      InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
+  EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
+  EXPECT_EQ(1u, registry()->enabled_extensions().size());
+
+  UninstallExtension(good_crx);
+  EXPECT_TRUE(registry()->enabled_extensions().empty());
+  EXPECT_EQ(UnloadedExtensionReason::UNINSTALL, unloaded_reason());
+}
+
+TEST_F(ExtensionServiceWithEmptyServiceTest,
+       UninstallExtensionFromUnpackedFolder_DoNotDeleteExtensionFolder) {
+  TestExtensionDir test_dir;
+  test_dir.WriteManifest(
+      R"({
+           "name": "Good Extension",
+           "version": "0.1",
+           "manifest_version": 3
+         })");
+
+  ChromeTestExtensionLoader loader(testing_profile());
+  loader.set_pack_extension(false);
+  scoped_refptr<const Extension> extension =
+      loader.LoadExtension(test_dir.UnpackedPath());
+
+  EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
+  EXPECT_EQ(1u, registry()->enabled_extensions().size());
+
+  UninstallExtension(extension->id(), /*delete_type=*/kDoNotDelete);
+  EXPECT_TRUE(registry()->enabled_extensions().empty());
+  EXPECT_EQ(UnloadedExtensionReason::UNINSTALL, unloaded_reason());
+}
+
+// Test that allows testing the
+// extensions_features::kExtensionsZipFileInstalledInProfileDir feature for .zip
+// file installs.
+class ExtensionServiceZipUninstallProfileFeatureTest
+    : public ExtensionServiceWithEmptyServiceTest,
+      public testing::WithParamInterface<bool> {
+ public:
+  void SetUp() override {
+    ExtensionServiceWithEmptyServiceTest::SetUp();
+    const bool kFeatureEnabled = GetParam();
+    feature_list_.InitWithFeatureState(
+        extensions_features::kExtensionsZipFileInstalledInProfileDir,
+        kFeatureEnabled);
+    if (kFeatureEnabled) {
+      expected_extension_install_directory_ =
+          service()->unpacked_install_directory();
+    } else {
+      base::FilePath dir_temp;
+      ASSERT_TRUE(base::PathService::Get(base::DIR_TEMP, &dir_temp));
+      expected_extension_install_directory_ = dir_temp;
+    }
+  }
+
+ protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  base::FilePath expected_extension_install_directory_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    ExtensionServiceZipUninstallProfileFeatureTest,
+    // extensions_features::kExtensionsZipFileInstalledInProfileDir enabled.
+    testing::Bool(),
+    [](const testing::TestParamInfo<
+        ExtensionServiceZipUninstallProfileFeatureTest::ParamType>& info) {
+      return info.param ? "ProfileDir" : "TempDir";
+    });
+
+TEST_P(ExtensionServiceZipUninstallProfileFeatureTest,
+       UninstallExtensionFromZip) {
+  MockExtensionRegistryObserver observer;
+
+  // Install the extension from .zip.
+  base::FilePath original_path;
+  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &original_path));
+  original_path = original_path.AppendASCII("extensions")
+                      .AppendASCII("zipfile_installer")
+                      .AppendASCII("good.zip");
+  ASSERT_TRUE(base::PathExists(original_path)) << original_path.value();
+  scoped_refptr<ZipFileInstaller> zipfile_installer = ZipFileInstaller::Create(
+      GetExtensionFileTaskRunner(),
+      MakeRegisterInExtensionServiceCallback(service()));
+
+  registry()->AddObserver(&observer);
+
+  const bool kFeatureEnabled = GetParam();
+  if (kFeatureEnabled) {
+    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
+        FROM_HERE,
+        base::BindOnce(&ZipFileInstaller::InstallZipFileToUnpackedExtensionsDir,
+                       zipfile_installer, original_path,
+                       service()->unpacked_install_directory()));
+  } else {
+    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
+        FROM_HERE, base::BindOnce(&ZipFileInstaller::InstallZipFileToTempDir,
+                                  zipfile_installer, original_path));
+  }
+  task_environment()->RunUntilIdle();
+
+  std::string extension_id = std::string(observer.last_extension_installed);
+  EXPECT_EQ(observer.last_extension_installed, extension_id);
+  EXPECT_EQ(1u, registry()->enabled_extensions().size());
+
+  if (kFeatureEnabled) {
+    UninstallExtension(extension_id, /*delete_type=*/kDeletePath);
+
+  } else {
+    UninstallExtension(extension_id, /*delete_type=*/kDoNotDelete);
+  }
+  EXPECT_FALSE(registry()->enabled_extensions().Contains(
+      observer.last_extension_installed));
+  EXPECT_TRUE(registry()->enabled_extensions().empty());
+  EXPECT_EQ(observer.last_extension_uninstalled, extension_id);
+  EXPECT_EQ(UnloadedExtensionReason::UNINSTALL, unloaded_reason());
+  registry()->RemoveObserver(&observer);
+}
+
+TEST_F(ExtensionServiceWithEmptyServiceTest, UninstallTerminatedExtension) {
   InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
   TerminateExtension(good_crx);
   UninstallExtension(good_crx);
   EXPECT_EQ(UnloadedExtensionReason::TERMINATE, unloaded_reason());
 }
 
-TEST_F(ExtensionServiceTest, UninstallBlockedExtension) {
-  InitializeEmptyExtensionService();
-
+TEST_F(ExtensionServiceWithEmptyServiceTest, UninstallBlockedExtension) {
   MockExtensionRegistryObserver observer;
   registry()->AddObserver(&observer);
 
diff --git a/chrome/browser/extensions/policy_handlers.cc b/chrome/browser/extensions/policy_handlers.cc
index b31c965..b981246 100644
--- a/chrome/browser/extensions/policy_handlers.cc
+++ b/chrome/browser/extensions/policy_handlers.cc
@@ -50,6 +50,15 @@
   }
   return true;
 }
+
+// Returns true if URL is valid and uses one of the supported schemes.
+bool IsValidUpdateUrl(const std::string& update_url) {
+  GURL update_gurl(update_url);
+  if (!update_gurl.is_valid()) {
+    return false;
+  }
+  return update_gurl.SchemeIsHTTPOrHTTPS() || update_gurl.SchemeIsFile();
+}
 }  // namespace
 // ExtensionListPolicyHandler implementation -----------------------------------
 
@@ -143,15 +152,23 @@
       update_url = entry_string.substr(pos + 1);
     }
 
-    if (!crx_file::id_util::IdIsValid(extension_id) ||
-        !GURL(update_url).is_valid()) {
+    if (!crx_file::id_util::IdIsValid(extension_id)) {
       if (errors) {
-        errors->AddError(policy_name(), IDS_POLICY_INVALID_EXTENSION_ERROR,
+        errors->AddError(policy_name(), IDS_POLICY_INVALID_EXTENSION_ID_ERROR,
                          policy::PolicyErrorPath{index});
       }
       continue;
     }
 
+    // Check that url is valid and uses one of the supported schemes.
+    if (!IsValidUpdateUrl(update_url)) {
+      if (errors) {
+        errors->AddError(policy_name(), IDS_POLICY_INVALID_UPDATE_URL_ERROR,
+                         extension_id, policy::PolicyErrorPath{index});
+      }
+      continue;
+    }
+
     if (extension_dict) {
       ExternalPolicyLoader::AddExtension(*extension_dict, extension_id,
                                          update_url);
@@ -290,8 +307,9 @@
           invalid_keys.insert(extension_ids);
           continue;
         }
-        if (!GURL(*update_url).is_valid()) {
-          // Warns about an invalid update URL.
+
+        // Check that url is valid and uses one of the supported schemes.
+        if (!IsValidUpdateUrl(*update_url)) {
           if (errors) {
             errors->AddError(policy_name(), IDS_POLICY_INVALID_UPDATE_URL_ERROR,
                              extension_ids);
diff --git a/chrome/browser/extensions/zipfile_installer_unittest.cc b/chrome/browser/extensions/zipfile_installer_unittest.cc
index edde7b8..abd758e1d 100644
--- a/chrome/browser/extensions/zipfile_installer_unittest.cc
+++ b/chrome/browser/extensions/zipfile_installer_unittest.cc
@@ -21,6 +21,7 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/extensions/chrome_zipfile_installer.h"
 #include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_service_test_base.h"
 #include "chrome/browser/extensions/load_error_reporter.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/common/chrome_paths.h"
@@ -34,6 +35,7 @@
 #include "extensions/browser/extension_registry_observer.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
+#include "extensions/common/extension_features.h"
 #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -82,10 +84,12 @@
                             const Extension* extension,
                             bool is_update) override {
     last_extension_installed = extension->id();
+    last_extension_installed_path = extension->path();
     std::move(quit_closure).Run();
   }
 
   std::string last_extension_installed;
+  base::FilePath last_extension_installed_path;
   base::OnceClosure quit_closure;
 };
 
@@ -96,57 +100,44 @@
 
 }  // namespace
 
-class ZipFileInstallerTest : public testing::Test {
+// Assists with testing the non-installation location behavior of the installer.
+class ZipFileInstallerTest : public ExtensionServiceTestBase {
  public:
-  ZipFileInstallerTest()
-      : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {}
-
   void SetUp() override {
+    ExtensionServiceTestBase::SetUp();
+    InitializeEmptyExtensionService();
     extensions::LoadErrorReporter::Init(/*enable_noisy_errors=*/false);
-
     in_process_utility_thread_helper_ =
         std::make_unique<content::InProcessUtilityThreadHelper>();
     unzip::SetUnzipperLaunchOverrideForTesting(
         base::BindRepeating(&unzip::LaunchInProcessUnzipper));
-
-    // Create profile for extension service.
-    profile_ = std::make_unique<TestingProfile>();
-    TestExtensionSystem* system =
-        static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile_.get()));
-    extension_service_ = system->CreateExtensionService(
-        base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
-    ExtensionRegistry* registry(ExtensionRegistry::Get(profile_.get()));
-    registry->AddObserver(&observer_);
+    registry()->AddObserver(&observer_);
   }
 
   void TearDown() override {
+    registry()->RemoveObserver(&observer_);
+    ExtensionServiceTestBase::TearDown();
     // Need to destruct ZipFileInstaller before the message loop since
     // it posts a task to it.
     zipfile_installer_.reset();
-    ExtensionRegistry* registry(ExtensionRegistry::Get(profile_.get()));
-    registry->RemoveObserver(&observer_);
-    profile_.reset();
     unzip::SetUnzipperLaunchOverrideForTesting(base::NullCallback());
     base::RunLoop().RunUntilIdle();
   }
 
-  void RunInstaller(const std::string& zip_name, bool expect_error) {
-    base::FilePath original_path;
-    ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &original_path));
-    original_path = original_path.AppendASCII("extensions")
-                        .AppendASCII("zipfile_installer")
-                        .AppendASCII(zip_name);
-    ASSERT_TRUE(base::PathExists(original_path)) << original_path.value();
-    zipfile_installer_ = ZipFileInstaller::Create(
-        GetExtensionFileTaskRunner(),
-        MakeRegisterInExtensionServiceCallback(extension_service_));
+ protected:
+  scoped_refptr<ZipFileInstaller> zipfile_installer_;
 
-    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
-        FROM_HERE, base::BindOnce(&ZipFileInstaller::LoadFromZipFile,
-                                  zipfile_installer_, original_path));
-    observer_.WaitForInstall(expect_error);
-  }
+  std::unique_ptr<content::InProcessUtilityThreadHelper>
+      in_process_utility_thread_helper_;
+  MockExtensionRegistryObserver observer_;
 
+ private:
+  data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
+};
+
+// Assists with testing the zip file filtering behavior of ZipFileInstaller.
+class ZipFileInstallerFilterTest : public ZipFileInstallerTest {
+ protected:
   void RunZipFileFilterTest(
       const std::vector<UnzipFileFilterTestCase>& cases,
       base::RepeatingCallback<bool(const base::FilePath&)>& filter) {
@@ -157,44 +148,9 @@
           << "i: " << i << ", input: " << input.value();
     }
   }
-
- protected:
-  scoped_refptr<ZipFileInstaller> zipfile_installer_;
-
-  std::unique_ptr<TestingProfile> profile_;
-  raw_ptr<ExtensionService> extension_service_;
-
-  content::BrowserTaskEnvironment task_environment_;
-  std::unique_ptr<content::InProcessUtilityThreadHelper>
-      in_process_utility_thread_helper_;
-  MockExtensionRegistryObserver observer_;
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  ash::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
-  // ChromeOS needs a user manager to instantiate an extension service.
-  ash::ScopedTestUserManager test_user_manager_;
-#endif
-
- private:
-  data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
 };
 
-TEST_F(ZipFileInstallerTest, GoodZip) {
-  RunInstaller("good.zip", /*expect_error=*/false);
-}
-
-TEST_F(ZipFileInstallerTest, BadZip) {
-  // Manifestless archive.
-  RunInstaller("bad.zip", /*expect_error=*/true);
-}
-
-TEST_F(ZipFileInstallerTest, ZipWithPublicKey) {
-  RunInstaller("public_key.zip", /*expect_error=*/false);
-  const char kIdForPublicKey[] = "ikppjpenhoddphklkpdfdfdabbakkpal";
-  EXPECT_EQ(observer_.last_extension_installed, kIdForPublicKey);
-}
-
-TEST_F(ZipFileInstallerTest, NonTheme_FileExtractionFilter) {
+TEST_F(ZipFileInstallerFilterTest, NonTheme_FileExtractionFilter) {
   const std::vector<UnzipFileFilterTestCase> cases = {
       {FILE_PATH_LITERAL("foo"), true},
       {FILE_PATH_LITERAL("foo.nexe"), true},
@@ -209,7 +165,7 @@
   RunZipFileFilterTest(cases, filter);
 }
 
-TEST_F(ZipFileInstallerTest, Theme_FileExtractionFilter) {
+TEST_F(ZipFileInstallerFilterTest, Theme_FileExtractionFilter) {
   const std::vector<UnzipFileFilterTestCase> cases = {
       {FILE_PATH_LITERAL("image.jpg"), true},
       {FILE_PATH_LITERAL("IMAGE.JPEG"), true},
@@ -226,7 +182,7 @@
   RunZipFileFilterTest(cases, filter);
 }
 
-TEST_F(ZipFileInstallerTest, ManifestExtractionFilter) {
+TEST_F(ZipFileInstallerFilterTest, ManifestExtractionFilter) {
   const std::vector<UnzipFileFilterTestCase> cases = {
       {FILE_PATH_LITERAL("manifest.json"), true},
       {FILE_PATH_LITERAL("MANIFEST.JSON"), true},
@@ -239,4 +195,161 @@
   RunZipFileFilterTest(cases, filter);
 }
 
+class ZipFileInstallerLocationTest : public ZipFileInstallerTest,
+                                     public testing::WithParamInterface<bool> {
+ public:
+  void SetUp() override {
+    ZipFileInstallerTest::SetUp();
+    const bool kFeatureEnabled = GetParam();
+    feature_list_.InitWithFeatureState(
+        extensions_features::kExtensionsZipFileInstalledInProfileDir,
+        kFeatureEnabled);
+    if (kFeatureEnabled) {
+      expected_extension_install_directory_ =
+          service()->unpacked_install_directory();
+    } else {
+      base::FilePath dir_temp;
+      ASSERT_TRUE(base::PathService::Get(base::DIR_TEMP, &dir_temp));
+      expected_extension_install_directory_ = dir_temp;
+    }
+  }
+
+  // Install the .zip in the test directory with `zip_name` and `expect_error`
+  // if it should fail. The method installs the .zip differently based on
+  // whether `extensions_features::kExtensionsZipFileInstalledInProfileDir` is
+  // enabled. `unzip_dir_root` allows passing a custom installation path when
+  // that feature is enabled.
+  void RunInstaller(const std::string& zip_name,
+                    bool expect_error,
+                    base::FilePath unzip_dir_root = base::FilePath());
+
+ protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  base::FilePath expected_extension_install_directory_;
+};
+
+void ZipFileInstallerLocationTest::RunInstaller(const std::string& zip_name,
+                                                bool expect_error,
+                                                base::FilePath unzip_dir_root) {
+  base::FilePath original_zip_path;
+  ASSERT_TRUE(
+      base::PathService::Get(chrome::DIR_TEST_DATA, &original_zip_path));
+  original_zip_path = original_zip_path.AppendASCII("extensions")
+                          .AppendASCII("zipfile_installer")
+                          .AppendASCII(zip_name);
+  ASSERT_TRUE(base::PathExists(original_zip_path)) << original_zip_path.value();
+  zipfile_installer_ = ZipFileInstaller::Create(
+      GetExtensionFileTaskRunner(),
+      MakeRegisterInExtensionServiceCallback(service()));
+
+  if (GetParam()) {
+    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
+        FROM_HERE,
+        base::BindOnce(&ZipFileInstaller::InstallZipFileToUnpackedExtensionsDir,
+                       zipfile_installer_, original_zip_path,
+                       unzip_dir_root.empty()
+                           ? service()->unpacked_install_directory()
+                           : unzip_dir_root));
+  } else {
+    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
+        FROM_HERE, base::BindOnce(&ZipFileInstaller::InstallZipFileToTempDir,
+                                  zipfile_installer_, original_zip_path));
+  }
+  observer_.WaitForInstall(expect_error);
+  task_environment()->RunUntilIdle();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    ZipFileInstallerLocationTest,
+    // extensions_features::kExtensionsZipFileInstalledInProfileDir enabled.
+    testing::Bool(),
+    [](const testing::TestParamInfo<ZipFileInstallerLocationTest::ParamType>&
+           info) { return info.param ? "ProfileDir" : "TempDir"; });
+
+// Tests that a normal .zip is installed into the expected install path.
+TEST_P(ZipFileInstallerLocationTest, GoodZip) {
+  RunInstaller(/*zip_name=*/"good.zip",
+               /*expect_error=*/false);
+
+  // Expect extension install directory to be immediate subdir of expected
+  // temp install directory. E.g. /a/b/c/d == /a/b/c + /d.
+  EXPECT_EQ(observer_.last_extension_installed_path,
+            expected_extension_install_directory_.Append(
+                observer_.last_extension_installed_path.BaseName()));
+}
+
+TEST_P(ZipFileInstallerLocationTest, BadZip) {
+  // Manifestless archive.
+  RunInstaller(/*zip_name=*/"bad.zip",
+               /*expect_error=*/true);
+}
+
+// Tests installing the same .zip twice results in two separate install
+// directories.
+TEST_P(ZipFileInstallerLocationTest, MultipleSameZipInstallSeparately) {
+  RunInstaller(/*zip_name=*/"good.zip",
+               /*expect_error=*/false);
+
+  base::FilePath dir_temp;
+  base::PathService::Get(base::DIR_TEMP, &dir_temp);
+  base::FilePath first_install_path = observer_.last_extension_installed_path;
+  // Expect extension install directory to be immediate subdir of expected
+  // unpacked install directory. E.g. /a/b/c/d == /a/b/c + /d.
+  EXPECT_EQ(observer_.last_extension_installed_path,
+            expected_extension_install_directory_.Append(
+                observer_.last_extension_installed_path.BaseName()));
+
+  RunInstaller(/*zip_name=*/"good.zip",
+               /*expect_error=*/false);
+
+  base::FilePath second_install_path = observer_.last_extension_installed_path;
+  // Expect extension install directory to be immediate subdir of expected
+  // unpacked install directory. E.g. /a/b/c/d == /a/b/c + /d.
+  EXPECT_EQ(observer_.last_extension_installed_path,
+            expected_extension_install_directory_.Append(
+                observer_.last_extension_installed_path.BaseName()));
+
+  // Confirm that the two extensions are installed in two separate
+  // directories.
+  EXPECT_NE(first_install_path, second_install_path);
+}
+
+// Tests that we error when we cannot create the parent directory of where to
+// install the .zips to.
+TEST_P(ZipFileInstallerLocationTest, CannotCreateContainingDirectoryZip) {
+  // This test is only relevant to the new feature.
+  if (!GetParam()) {
+    return;
+  }
+
+  // TODO(crbug.com/1378775): Have this expect a specific error rather than just
+  // an error since other things can cause an error.
+  RunInstaller(
+      /*zip_name=*/"good.zip", /*expect_error=*/true, /*unzip_dir_root=*/
+#if !BUILDFLAG(IS_WIN)
+      base::FilePath(
+          FILE_PATH_LITERAL("/NonExistentDirectory/UnpackedExtensions"))
+#else
+      // Windows will create unexpected paths so we use explicitly disallowed
+      // characters in the Windows filesystem to ensure creating this directory
+      // fails.
+      base::FilePath(
+          FILE_PATH_LITERAL("|<IllegalWinDirName>|/UnpackedExtensions"))
+#endif  // !BUILDFLAG(IS_WIN)
+  );
+}
+
+// Tests that a .zip with a public key installs with the expected extension ID
+// and to the correct path.
+TEST_P(ZipFileInstallerLocationTest, ZipWithPublicKey) {
+  RunInstaller(/*zip_name=*/"public_key.zip",
+               /*expect_error=*/false);
+  const char kIdForPublicKey[] = "ikppjpenhoddphklkpdfdfdabbakkpal";
+  EXPECT_EQ(observer_.last_extension_installed, kIdForPublicKey);
+  EXPECT_EQ(observer_.last_extension_installed_path,
+            expected_extension_install_directory_.Append(
+                observer_.last_extension_installed_path.BaseName()));
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java
index 355035d2..4e60cda 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java
@@ -50,6 +50,7 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
+import org.chromium.components.browser_ui.widget.textbubble.TextBubble;
 import org.chromium.components.feature_engagement.FeatureConstants;
 import org.chromium.components.feature_engagement.Tracker;
 import org.chromium.components.feature_engagement.TriggerDetails;
@@ -174,10 +175,13 @@
                 mTabSupplier, new View(mActivity), mFeedLauncher, mDialogManager, mSnackbarManager);
         mEmptyTabObserver = mWebFeedFollowIntroController.getEmptyTabObserverForTesting();
         mWebFeedFollowIntroController.setClockForTesting(mClock);
+        // TextBubble is impossible to show in a junit.
+        TextBubble.setSkipShowCheckForTesting(true);
     }
 
     @After
     public void tearDown() {
+        TextBubble.setSkipShowCheckForTesting(false);
         TrackerFactory.setTrackerForTests(null);
     }
 
diff --git a/chrome/browser/feedback/show_feedback_page.cc b/chrome/browser/feedback/show_feedback_page.cc
index 454a844c..5198296 100644
--- a/chrome/browser/feedback/show_feedback_page.cc
+++ b/chrome/browser/feedback/show_feedback_page.cc
@@ -32,6 +32,7 @@
 #include "chrome/browser/ash/crosapi/browser_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h"
+#include "chromeos/components/kiosk/kiosk_utils.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #endif
@@ -221,9 +222,11 @@
     include_bluetooth_logs = IsFromUserInteraction(source);
     show_questionnaire = IsFromUserInteraction(source);
   }
-  if (base::FeatureList::IsEnabled(ash::features::kOsFeedback)) {
-    // TODO(crbug.com/1407646): Include autofill metadata into CrOS new feedback
-    // tool.
+  // Disable a new feedback tool for kiosk, because SWAs are disabled there.
+  if (!chromeos::IsKioskSession() &&
+      base::FeatureList::IsEnabled(ash::features::kOsFeedback)) {
+    // TODO(crbug.com/1407646): Include autofill metadata into CrOS new
+    // feedback tool.
     ash::SystemAppLaunchParams params{};
     params.url = BuildFeedbackUrl(
         extra_diagnostics, description_template, description_placeholder_text,
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 77e864aa..8a0408b 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1040,7 +1040,7 @@
   {
     "name": "chrome-refresh-2023",
     "owners":["chrome-views@google.com"],
-    "expiry_milestone": 115
+    "expiry_milestone": 120
   },
   {
     "name": "chrome-root-store-enabled",
@@ -1120,11 +1120,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "cmd-decoder-always-get-size-from-source-texture",
-    "owners": [ "blundell" ],
-    "expiry_milestone": 128
-  },
-  {
     "name": "colr-v1-fonts",
     "owners": [ "drott", "layout-dev@chromium.org" ],
     "expiry_milestone": 100
@@ -1460,7 +1455,7 @@
   {
     "name": "diagnostics-app-jelly",
     "owners": [
-      "//ash/webui/diagnostics_ui/OWNERS"
+      "//ash/webui/diagnostics_ui/OWNERS", "cros-peripherals@google.com"
     ],
     "expiry_milestone": 122
   },
@@ -2530,6 +2525,11 @@
     "expiry_milestone": 123
   },
   {
+    "name": "enable-follow-ui-update",
+    "owners": [ "sczs", "adamta", "guiperez" ],
+    "expiry_milestone": 123
+  },
+  {
     "name": "enable-force-dark",
     "owners": [ "beverloo", "pdr" ],
     "expiry_milestone": 123
@@ -2829,11 +2829,6 @@
     "expiry_milestone": 80
   },
   {
-    "name": "enable-log-controller-for-diagnostics-app",
-    "owners": [ "ashleydp", "jimmyxgong", "michaelcheco", "cros-peripherals@google.com" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "enable-logging-js-console-messages",
     "owners": [ "hazems" ],
     // Never expires because it is used by developers to enable logging JS
@@ -3825,11 +3820,6 @@
     "expiry_milestone": 115
   },
   {
-    "name": "fake-audio-capture-timestamps",
-    "owners": [ "henrika@google.com", "video-cmi-mpp@google.com" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "fast-checkout",
     "owners": [ "vizcay@google.com", "bwolfgang@google.com", "jkeitel@google.com" ],
     "expiry_milestone": 118
@@ -3970,12 +3960,12 @@
   {
     "name": "feed-boc-signin-interstitial",
     "owners": ["//chrome/android/feed/OWNERS", "birnie"],
-    "expiry_milestone": 115
+    "expiry_milestone": 118
   },
   {
     "name": "feed-bottom-sync-banner",
     "owners": ["//chrome/android/feed/OWNERS", "birnie"],
-    "expiry_milestone": 115
+    "expiry_milestone": 118
   },
   {
     "name": "feed-close-refresh",
@@ -4015,7 +4005,7 @@
   {
     "name": "feed-invisible-foreground-refresh-ios",
     "owners": ["//ios/chrome/browser/discover_feed/OWNERS", "edchin@google.com"],
-    "expiry_milestone": 115
+    "expiry_milestone": 118
   },
   {
     "name": "feed-loading-placeholder",
@@ -4227,11 +4217,6 @@
     "expiry_milestone": 95
   },
   {
-    "name": "full-restore-for-lacros",
-    "owners": [ "dominickn", "nancylingwang", "sammiequon", "xdai" ],
-    "expiry_milestone": 115
-  },
-  {
     "name": "fullscreen-popup-windows",
     "owners": [ "btriebw", "msw" ],
     "expiry_milestone": 120
@@ -4628,7 +4613,7 @@
   {
     "name": "ios-autofill-branding",
     "owners": [ "ginnyhuang@google.com", "bling-flags@google.com" ],
-    "expiry_milestone": 115
+    "expiry_milestone": 118
   },
   {
     "name": "ios-breadcrumbs",
@@ -6168,11 +6153,6 @@
     "expiry_milestone": 118
   },
   {
-    "name": "personalization-jelly",
-    "owners": ["assistive-eng@google.com" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "phone-hub-nudge",
     "owners": [
       "jennserrano@google.com",
@@ -7472,8 +7452,8 @@
   },
   {
     "name": "use-dmsaa-for-tiles",
-    "owners": [ "vasilyt" ],
-    "expiry_milestone": 115
+    "owners": [ "vasilyt", "vikassoni" ],
+    "expiry_milestone": 125
   },
   {
     "name": "use-dns-https-svcb-alpn",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index c8b0ea65..9140a7ae 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -6,6 +6,7 @@
 
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "components/supervised_user/core/common/buildflags.h"
 #include "flag_descriptions.h"
 #include "pdf/buildflags.h"
 
@@ -204,14 +205,6 @@
     "after 3 restarts. On the third restart, the flag will appear to be off "
     "but the effect is still active.";
 
-extern const char kCmdDecoderAlwaysGetSizeFromSourceTextureName[] =
-    "Controls whether the GLES2 validating decoder always gets size from the "
-    "source texture when copying textures";
-extern const char kCmdDecoderAlwaysGetSizeFromSourceTextureDescription[] =
-    "When enabled, the GLES2 validating decoder will obtain size from the "
-    "source texture rather than the GLImage when copying textures even if a "
-    "GLImage is present";
-
 const char kPrivacyIndicatorsName[] = "Enable Privacy Indicators";
 const char kPrivacyIndicatorsDescription[] =
     "While screen sharing or camera/microphone is being accessed, show a green "
@@ -1993,9 +1986,6 @@
 const char kCscName[] = "CSC";
 const char kCscDescription[] = "";
 
-const char kCscPinnedName[] = "CSC Pin State";
-const char kCscPinnedDescription[] = "";
-
 const char kLogJsConsoleMessagesName[] =
     "Log JS console messages in system logs";
 const char kLogJsConsoleMessagesDescription[] =
@@ -4863,12 +4853,6 @@
     "for endpoint specific, always-on processing in the Audio Processing Object"
     " (APO), driver, and hardware.";
 
-const char kFakeAudioCaptureTimestamps[] = "Fake audio capture timestamps";
-const char kFakeAudioCaptureTimestampsDescription[] =
-    "Emulates audio capture timestamps instead of using timestamps from the "
-    "actual audio device. Can be used as a temporary workaround in situations "
-    "where the selected audio device generates invalid timestamp sequences.";
-
 const char kRunVideoCaptureServiceInBrowserProcessName[] =
     "Run video capture service in browser";
 const char kRunVideoCaptureServiceInBrowserProcessDescription[] =
@@ -5073,11 +5057,6 @@
 const char kAlwaysEnableHdcpType0[] = "Type 0";
 const char kAlwaysEnableHdcpType1[] = "Type 1";
 
-const char kPersonalizationJellyName[] = "Jelly design for Personalization App";
-const char kPersonalizationJellyDescription[] =
-    "Feature to enable the Jelly design in Personalization App. Requires "
-    "jelly-colors flag to be enabled.";
-
 const char kAmbientModeThrottleAnimationName[] =
     "Throttle the frame rate of Lottie animations in ambient mode";
 const char kAmbientModeThrottleAnimationDescription[] =
@@ -5685,13 +5664,6 @@
     "Enable toggling of the keyboard backlight. By "
     "default, this flag is enabled.";
 
-const char kEnableLogControllerForDiagnosticsAppName[] =
-    "Enable DiagnosticsLogController for Diagnostics App";
-const char kEnableLogControllerForDiagnosticsAppDescription[] =
-    "Uses DiagnosticsLogController to manage the lifetime of Diagnostics App "
-    "logs.  Enables creation of combined diagnostics log after Diagnostics "
-    "App is closed.";
-
 const char kEnableNeuralPalmAdaptiveHoldName[] = "Palm Rejection Adaptive Hold";
 const char kEnableNeuralPalmAdaptiveHoldDescription[] =
     "Enable adaptive hold in palm rejection.  Not compatible with all devices.";
@@ -5977,10 +5949,6 @@
 const char kFrameThrottleFps25[] = "25 fps";
 const char kFrameThrottleFps30[] = "30 fps";
 
-const char kFullRestoreForLacrosName[] = "Full restore lacros support";
-const char kFullRestoreForLacrosDescription[] =
-    "ChromeOS full restore lacros support";
-
 const char kFuseBoxDebugName[] = "Debugging UI for ChromeOS FuseBox service";
 const char kFuseBoxDebugDescription[] =
     "Show additional debugging UI for ChromeOS FuseBox service.";
@@ -6650,14 +6618,14 @@
 const char kSmdsSupportDescription[] =
     "Feature to enable the consumer and enterprise support for provisioning "
     "eSIM profiles using Subscription Manager Discovery Service (SM-DS). This "
-    "flag is a no-op unless the smds-dbus-migration flag is enabled";
+    "flag is a no-op unless the smds-dbus-migration and "
+    "smds-support-euicc-upload flags are enabled.";
 
 const char kSmdsSupportEuiccUploadName[] = "SM-DS Support EUICC Upload";
 const char kSmdsSupportEuiccUploadDescription[] =
     "Feature to enable tracking when a policy-defined cellular network "
     "configured to use SM-DS has already been applied and an eSIM profile for "
-    "the network was installed. This flag is a no-op unless the smds-support "
-    "and smds-dbus-migration flags are enabled.";
+    "the network was installed.";
 
 const char kSmdsDbusMigrationName[] = "SM-DS DBus Migration";
 const char kSmdsDbusMigrationDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 98e71bf7..51fcad77 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -151,9 +151,6 @@
 extern const char kPasspointSettingsName[];
 extern const char kPasspointSettingsDescription[];
 
-extern const char kCmdDecoderAlwaysGetSizeFromSourceTextureName[];
-extern const char kCmdDecoderAlwaysGetSizeFromSourceTextureDescription[];
-
 extern const char kPrivacyIndicatorsName[];
 extern const char kPrivacyIndicatorsDescription[];
 
@@ -1110,9 +1107,6 @@
 extern const char kCscName[];
 extern const char kCscDescription[];
 
-extern const char kCscPinnedName[];
-extern const char kCscPinnedDescription[];
-
 extern const char kLensOnQuickActionSearchWidgetName[];
 extern const char kLensOnQuickActionSearchWidgetDescription[];
 
@@ -2788,9 +2782,6 @@
 extern const char kRawAudioCaptureName[];
 extern const char kRawAudioCaptureDescription[];
 
-extern const char kFakeAudioCaptureTimestamps[];
-extern const char kFakeAudioCaptureTimestampsDescription[];
-
 extern const char kRunVideoCaptureServiceInBrowserProcessName[];
 extern const char kRunVideoCaptureServiceInBrowserProcessDescription[];
 
@@ -3246,9 +3237,6 @@
 extern const char kEnableLibinputToHandleTouchpadName[];
 extern const char kEnableLibinputToHandleTouchpadDescription[];
 
-extern const char kEnableLogControllerForDiagnosticsAppName[];
-extern const char kEnableLogControllerForDiagnosticsAppDescription[];
-
 extern const char kEnableNeuralPalmAdaptiveHoldName[];
 extern const char kEnableNeuralPalmAdaptiveHoldDescription[];
 
@@ -3419,9 +3407,6 @@
 extern const char kFrameThrottleFps25[];
 extern const char kFrameThrottleFps30[];
 
-extern const char kFullRestoreForLacrosName[];
-extern const char kFullRestoreForLacrosDescription[];
-
 extern const char kFuseBoxDebugName[];
 extern const char kFuseBoxDebugDescription[];
 
@@ -3589,9 +3574,6 @@
 extern const char kPerformantSplitViewResizing[];
 extern const char kPerformantSplitViewResizingDescription[];
 
-extern const char kPersonalizationJellyName[];
-extern const char kPersonalizationJellyDescription[];
-
 extern const char kPhoneHubCallNotificationName[];
 extern const char kPhoneHubCallNotificationDescription[];
 
diff --git a/chrome/browser/infobars/infobars_browsertest.cc b/chrome/browser/infobars/infobars_browsertest.cc
index a100f8f..44a66db0 100644
--- a/chrome/browser/infobars/infobars_browsertest.cc
+++ b/chrome/browser/infobars/infobars_browsertest.cc
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string>
 #include <tuple>
 #include <utility>
 
 #include "base/command_line.h"
-#include "base/containers/flat_map.h"
+#include "base/containers/fixed_flat_map.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_helpers.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
@@ -37,6 +39,8 @@
 #include "chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_infobar.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -168,6 +172,7 @@
 
   // TestInfoBar:
   void ShowUi(const std::string& name) override;
+  bool VerifyUi() override;
 
  private:
   using IBD = infobars::InfoBarDelegate;
@@ -183,38 +188,41 @@
     return;
   }
 
-  const base::flat_map<std::string, IBD::InfoBarIdentifier> kIdentifiers = {
-    {"dev_tools", IBD::DEV_TOOLS_INFOBAR_DELEGATE},
-    {"extension_dev_tools", IBD::EXTENSION_DEV_TOOLS_INFOBAR_DELEGATE},
-    {"incognito_connectability",
-     IBD::INCOGNITO_CONNECTABILITY_INFOBAR_DELEGATE},
-    {"theme_installed", IBD::THEME_INSTALLED_INFOBAR_DELEGATE},
-    {"nacl", IBD::NACL_INFOBAR_DELEGATE},
-    {"file_access_disabled", IBD::FILE_ACCESS_DISABLED_INFOBAR_DELEGATE},
-    {"keystone_promotion", IBD::KEYSTONE_PROMOTION_INFOBAR_DELEGATE_MAC},
-    {"collected_cookies", IBD::COLLECTED_COOKIES_INFOBAR_DELEGATE},
-    {"installation_error", IBD::INSTALLATION_ERROR_INFOBAR_DELEGATE},
-    {"bad_flags", IBD::BAD_FLAGS_INFOBAR_DELEGATE},
-    {"default_browser", IBD::DEFAULT_BROWSER_INFOBAR_DELEGATE},
-    {"google_api_keys", IBD::GOOGLE_API_KEYS_INFOBAR_DELEGATE},
-    {"obsolete_system", IBD::OBSOLETE_SYSTEM_INFOBAR_DELEGATE},
-    {"page_info", IBD::PAGE_INFO_INFOBAR_DELEGATE},
-    {"translate", IBD::TRANSLATE_INFOBAR_DELEGATE_NON_AURA},
-    {"automation", IBD::AUTOMATION_INFOBAR_DELEGATE},
-    {"tab_sharing", IBD::TAB_SHARING_INFOBAR_DELEGATE},
+  constexpr auto kIdentifiers =
+      base::MakeFixedFlatMap<base::StringPiece, IBD::InfoBarIdentifier>({
+        {"dev_tools", IBD::DEV_TOOLS_INFOBAR_DELEGATE},
+            {"extension_dev_tools", IBD::EXTENSION_DEV_TOOLS_INFOBAR_DELEGATE},
+            {"incognito_connectability",
+             IBD::INCOGNITO_CONNECTABILITY_INFOBAR_DELEGATE},
+            {"theme_installed", IBD::THEME_INSTALLED_INFOBAR_DELEGATE},
+            {"nacl", IBD::NACL_INFOBAR_DELEGATE},
+            {"file_access_disabled",
+             IBD::FILE_ACCESS_DISABLED_INFOBAR_DELEGATE},
+            {"keystone_promotion",
+             IBD::KEYSTONE_PROMOTION_INFOBAR_DELEGATE_MAC},
+            {"collected_cookies", IBD::COLLECTED_COOKIES_INFOBAR_DELEGATE},
+            {"installation_error", IBD::INSTALLATION_ERROR_INFOBAR_DELEGATE},
+            {"bad_flags", IBD::BAD_FLAGS_INFOBAR_DELEGATE},
+            {"default_browser", IBD::DEFAULT_BROWSER_INFOBAR_DELEGATE},
+            {"google_api_keys", IBD::GOOGLE_API_KEYS_INFOBAR_DELEGATE},
+            {"obsolete_system", IBD::OBSOLETE_SYSTEM_INFOBAR_DELEGATE},
+            {"page_info", IBD::PAGE_INFO_INFOBAR_DELEGATE},
+            {"translate", IBD::TRANSLATE_INFOBAR_DELEGATE_NON_AURA},
+            {"automation", IBD::AUTOMATION_INFOBAR_DELEGATE},
+            {"tab_sharing", IBD::TAB_SHARING_INFOBAR_DELEGATE},
 
 #if BUILDFLAG(ENABLE_PLUGINS)
-    {"hung_plugin", IBD::HUNG_PLUGIN_INFOBAR_DELEGATE},
-    {"reload_plugin", IBD::RELOAD_PLUGIN_INFOBAR_DELEGATE},
-    {"plugin_observer", IBD::PLUGIN_OBSERVER_INFOBAR_DELEGATE},
+            {"hung_plugin", IBD::HUNG_PLUGIN_INFOBAR_DELEGATE},
+            {"reload_plugin", IBD::RELOAD_PLUGIN_INFOBAR_DELEGATE},
+            {"plugin_observer", IBD::PLUGIN_OBSERVER_INFOBAR_DELEGATE},
 #endif  // BUILDFLAG(ENABLE_PLUGINS)
-  };
-  auto id_entry = kIdentifiers.find(name);
+      });
+  const auto* const id_entry = kIdentifiers.find(name);
   if (id_entry == kIdentifiers.end()) {
     ADD_FAILURE() << "Unexpected infobar " << name;
     return;
   }
-  auto infobar_identifier = id_entry->second;
+  const auto infobar_identifier = id_entry->second;
   AddExpectedInfoBar(infobar_identifier);
   switch (infobar_identifier) {
     case IBD::DEV_TOOLS_INFOBAR_DELEGATE:
@@ -372,6 +380,16 @@
   }
 }
 
+bool InfoBarUiTest::VerifyUi() {
+  const auto* const test_info =
+      testing::UnitTest::GetInstance()->current_test_info();
+  return TestInfoBar::VerifyUi() &&
+         (VerifyPixelUi(BrowserView::GetBrowserViewForBrowser(browser())
+                            ->infobar_container(),
+                        test_info->test_case_name(),
+                        test_info->name()) != ui::test::ActionResult::kFailed);
+}
+
 IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_dev_tools) {
   ShowAndVerifyUi();
 }
diff --git a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
index fa430da0..e184f6b 100644
--- a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
+++ b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/feature_list.h"
+#include "base/unguessable_token.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
@@ -57,6 +58,7 @@
 #include "chromeos/crosapi/mojom/crosapi.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "chromeos/startup/browser_params_proxy.h"
+#include "chromeos/ui/clipboard_history/clipboard_history_util.h"
 #include "components/arc/common/intent_helper/arc_icon_cache_delegate.h"
 #include "extensions/common/features/feature_session_type.h"
 #include "services/device/public/cpp/geolocation/geolocation_manager.h"
@@ -269,6 +271,30 @@
                 crosapi::ViewsTextServicesContextMenuLacros>(menu_model,
                                                              textfield);
           }));
+
+  // Sets the implementation of clipboard history utility functions.
+  if (chromeos::features::IsClipboardHistoryRefreshEnabled()) {
+    chromeos::clipboard_history::SetQueryItemDescriptorsImpl(
+        base::BindRepeating([]() {
+          return crosapi::ClipboardHistoryLacros::Get()->cached_descriptors();
+        }));
+    chromeos::clipboard_history::SetPasteClipboardItemByIdImpl(
+        base::BindRepeating(
+            [](const base::UnguessableToken& id, int event_flags,
+               crosapi::mojom::ClipboardHistoryControllerShowSource source) {
+              if (auto* lacros_service = chromeos::LacrosService::Get();
+                  lacros_service &&
+                  lacros_service
+                      ->IsAvailable<crosapi::mojom::ClipboardHistory>() &&
+                  lacros_service->GetInterfaceVersion<
+                      crosapi::mojom::ClipboardHistory>() >=
+                      int{crosapi::mojom::ClipboardHistory::MethodMinVersions::
+                              kPasteClipboardItemByIdMinVersion}) {
+                lacros_service->GetRemote<crosapi::mojom::ClipboardHistory>()
+                    ->PasteClipboardItemById(id, event_flags, source);
+              }
+            }));
+  }
 }
 
 void ChromeBrowserMainExtraPartsLacros::PostMainMessageLoopRun() {
diff --git a/chrome/browser/lacros/clipboard_history_lacros.cc b/chrome/browser/lacros/clipboard_history_lacros.cc
index 2b9c256..18cd04a3 100644
--- a/chrome/browser/lacros/clipboard_history_lacros.cc
+++ b/chrome/browser/lacros/clipboard_history_lacros.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/lacros/clipboard_history_lacros.h"
 
+#include <utility>
+#include <vector>
+
 #include "base/functional/bind.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/crosapi/mojom/clipboard_history.mojom.h"
diff --git a/chrome/browser/lacros/clipboard_history_lacros.h b/chrome/browser/lacros/clipboard_history_lacros.h
index af18f7bc..4e0af40 100644
--- a/chrome/browser/lacros/clipboard_history_lacros.h
+++ b/chrome/browser/lacros/clipboard_history_lacros.h
@@ -10,6 +10,8 @@
 #include "chromeos/crosapi/mojom/clipboard_history.mojom.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 
+class ClipboardHistoryRefreshLacrosTest;
+
 namespace crosapi {
 
 // The Lacros implementation of `mojom::ClipboardHistoryClient`. A singleton
@@ -30,6 +32,8 @@
   }
 
  private:
+  friend ClipboardHistoryRefreshLacrosTest;
+
   // mojom::ClipboardHistoryClient:
   void SetClipboardHistoryItemDescriptors(
       std::vector<mojom::ClipboardHistoryItemDescriptorPtr> descriptor_ptrs)
diff --git a/chrome/browser/lacros/clipboard_history_lacros_browsertest.cc b/chrome/browser/lacros/clipboard_history_lacros_browsertest.cc
index ea0de66..6ac5c53 100644
--- a/chrome/browser/lacros/clipboard_history_lacros_browsertest.cc
+++ b/chrome/browser/lacros/clipboard_history_lacros_browsertest.cc
@@ -2,16 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/lacros/clipboard_history_lacros.h"
 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/crosapi/mojom/clipboard_history.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "content/public/test/browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/context_menu_data/edit_flags.h"
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
+#include "ui/strings/grit/ui_strings.h"
+#include "ui/views/controls/textfield/textfield.h"
+#include "ui/views/controls/textfield/textfield_test_api.h"
+#include "ui/views/widget/widget.h"
 
 class ClipboardHistoryRefreshLacrosTest
     : public InProcessBrowserTest,
@@ -42,6 +53,26 @@
     return lacros_service &&
            lacros_service->IsAvailable<crosapi::mojom::ClipboardHistory>();
   }
+
+  void WriteTextToClipboard(const std::u16string& text) {
+    ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste).WriteText(text);
+
+    // TODO(http://b/278916298): implement testing in an end-to-end way after
+    // http://b/283834862 is fixed.
+    if (chromeos::features::IsClipboardHistoryRefreshEnabled()) {
+      crosapi::ClipboardHistoryLacros* clipboard_history_lacros =
+          crosapi::ClipboardHistoryLacros::Get();
+      std::vector<crosapi::mojom::ClipboardHistoryItemDescriptor>&
+          cached_descriptors = clipboard_history_lacros->cached_descriptors_;
+      cached_descriptors.insert(
+          cached_descriptors.begin(),
+          crosapi::mojom::ClipboardHistoryItemDescriptor(
+              /*id=*/base::UnguessableToken::Create(),
+              /*display_format=*/
+              crosapi::mojom::ClipboardHistoryDisplayFormat::kText, text,
+              /*file_count=*/0));
+    }
+  }
 };
 
 INSTANTIATE_TEST_SUITE_P(All,
@@ -54,7 +85,7 @@
   // If the clipboard history interface is not available on this version of
   // ash-chrome, this test cannot meaningfully run.
   if (!IsInterfaceAvailable()) {
-    return;
+    GTEST_SKIP() << "Unsupported Ash version.";
   }
 
   content::ContextMenuParams params;
@@ -73,10 +104,80 @@
   EXPECT_FALSE(menu.IsItemEnabled(IDC_CONTENT_CLIPBOARD_HISTORY_MENU));
 
   // Populate the clipboard so that the menu can be shown.
-  ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste).WriteText(u"text");
+  WriteTextToClipboard(u"text");
 
   // When clipboard history is not empty, the Clipboard option should be
   // enabled.
   EXPECT_TRUE(menu.IsItemPresent(IDC_CONTENT_CLIPBOARD_HISTORY_MENU));
   EXPECT_TRUE(menu.IsItemEnabled(IDC_CONTENT_CLIPBOARD_HISTORY_MENU));
 }
+
+// Checks that the Lacros text services context menu clipboard history option is
+// 1. A command menu item if the clipboard history refresh feature is disabled;
+// 2. A submenu item if the clipboard history refresh feature is enabled.
+IN_PROC_BROWSER_TEST_P(ClipboardHistoryRefreshLacrosTest,
+                       MenuOptionOnTextServicesContextMenu) {
+  // If the clipboard history interface is not available on this version of
+  // ash-chrome, this test cannot meaningfully run.
+  if (!IsInterfaceAvailable()) {
+    GTEST_SKIP() << "Unsupported Ash version.";
+  }
+
+  // Create a textfield.
+  views::Widget::InitParams params;
+  params.bounds = gfx::Rect(200, 200);
+  params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
+  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  auto textfield_widget = std::make_unique<views::Widget>();
+  textfield_widget->Init(std::move(params));
+  views::Textfield* textfield =
+      textfield_widget->SetContentsView(std::make_unique<views::Textfield>());
+  textfield->SetAccessibleName(u"Textfield");
+  textfield_widget->Show();
+
+  views::TextfieldTestApi api(textfield);
+  api.UpdateContextMenu();
+
+  // Search the parent model and the command index of
+  // `IDS_APP_SHOW_CLIPBOARD_HISTORY`.
+  ui::MenuModel* target_command_parent_model = api.context_menu_contents();
+  size_t target_command_index = 0u;
+  ui::MenuModel::GetModelAndIndexForCommandId(IDS_APP_SHOW_CLIPBOARD_HISTORY,
+                                              &target_command_parent_model,
+                                              &target_command_index);
+  ASSERT_EQ(target_command_parent_model, api.context_menu_contents());
+  ASSERT_GT(target_command_index, 0u);
+
+  // Before having clipboard history item descriptors, the clipboard history
+  // menu option is disabled.
+  EXPECT_FALSE(target_command_parent_model->IsEnabledAt(target_command_index));
+
+  // Write some clipboard data then update the context menu.
+  WriteTextToClipboard(u"b");
+  WriteTextToClipboard(u"a");
+  api.UpdateContextMenu();
+  target_command_parent_model = api.context_menu_contents();
+
+  // The clipboard history menu option becomes enabled after writing data.
+  EXPECT_TRUE(target_command_parent_model->IsEnabledAt(target_command_index));
+
+  if (chromeos::features::IsClipboardHistoryRefreshEnabled()) {
+    // Because the refresh feature is enabled, the clipboard history menu item
+    // should be a submenu item.
+    EXPECT_EQ(target_command_parent_model->GetTypeAt(target_command_index),
+              ui::MenuModel::ItemType::TYPE_SUBMENU);
+
+    // Check the submenu model data.
+    ui::MenuModel* const submenu_model =
+        target_command_parent_model->GetSubmenuModelAt(target_command_index);
+    ASSERT_TRUE(submenu_model);
+    ASSERT_EQ(submenu_model->GetItemCount(), 2u);
+    EXPECT_EQ(submenu_model->GetLabelAt(0), u"a");
+    EXPECT_EQ(submenu_model->GetLabelAt(1), u"b");
+  } else {
+    // Because the refresh feature is disabled, the clipboard history menu item
+    // should be a command item.
+    EXPECT_EQ(target_command_parent_model->GetTypeAt(target_command_index),
+              ui::MenuModel::ItemType::TYPE_COMMAND);
+  }
+}
diff --git a/chrome/browser/lacros/views_text_services_context_menu_lacros.cc b/chrome/browser/lacros/views_text_services_context_menu_lacros.cc
index 6a4f95ce..7ef0b55 100644
--- a/chrome/browser/lacros/views_text_services_context_menu_lacros.cc
+++ b/chrome/browser/lacros/views_text_services_context_menu_lacros.cc
@@ -5,8 +5,11 @@
 #include "chrome/browser/lacros/views_text_services_context_menu_lacros.h"
 
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/lacros/clipboard_history_lacros.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/crosapi/mojom/clipboard_history.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
+#include "chromeos/ui/clipboard_history/clipboard_history_submenu_model.h"
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -49,8 +52,23 @@
     return;
 
   const size_t target_index = paste_index.value() + 1;
-  menu->InsertItemAt(target_index, IDS_APP_SHOW_CLIPBOARD_HISTORY,
-                     l10n_util::GetStringUTF16(IDS_APP_SHOW_CLIPBOARD_HISTORY));
+
+  // If the clipboard history refresh feature is enabled, insert a submenu of
+  // clipboard history descriptors; otherwise, insert a menu option to trigger
+  // the clipboard history menu.
+  if (chromeos::features::IsClipboardHistoryRefreshEnabled()) {
+    submenu_model_ = chromeos::clipboard_history::ClipboardHistorySubmenuModel::
+        CreateClipboardHistorySubmenuModel(
+            crosapi::mojom::ClipboardHistoryControllerShowSource::
+                kTextfieldContextMenu);
+    menu->InsertSubMenuWithStringIdAt(
+        target_index, IDS_APP_SHOW_CLIPBOARD_HISTORY,
+        IDS_APP_SHOW_CLIPBOARD_HISTORY, submenu_model_.get());
+  } else {
+    menu->InsertItemAt(
+        target_index, IDS_APP_SHOW_CLIPBOARD_HISTORY,
+        l10n_util::GetStringUTF16(IDS_APP_SHOW_CLIPBOARD_HISTORY));
+  }
 }
 
 ViewsTextServicesContextMenuLacros::~ViewsTextServicesContextMenuLacros() =
@@ -79,8 +97,12 @@
 bool ViewsTextServicesContextMenuLacros::IsCommandIdEnabled(
     int command_id) const {
   if (command_id == IDS_APP_SHOW_CLIPBOARD_HISTORY) {
+    // If the clipboard history refresh feature is enabled, enable the clipboard
+    // history command id if there are clipboard history item descriptors.
     return IsClipboardHistoryLacrosServiceAvailable() &&
-           !IsClipboardHistoryEmpty();
+           (chromeos::features::IsClipboardHistoryRefreshEnabled()
+                ? !ClipboardHistoryLacros::Get()->cached_descriptors().empty()
+                : !IsClipboardHistoryEmpty());
   }
 
   return ViewsTextServicesContextMenuBase::IsCommandIdEnabled(command_id);
diff --git a/chrome/browser/lacros/views_text_services_context_menu_lacros.h b/chrome/browser/lacros/views_text_services_context_menu_lacros.h
index 4342bc6b..9e41578 100644
--- a/chrome/browser/lacros/views_text_services_context_menu_lacros.h
+++ b/chrome/browser/lacros/views_text_services_context_menu_lacros.h
@@ -5,8 +5,14 @@
 #ifndef CHROME_BROWSER_LACROS_VIEWS_TEXT_SERVICES_CONTEXT_MENU_LACROS_H_
 #define CHROME_BROWSER_LACROS_VIEWS_TEXT_SERVICES_CONTEXT_MENU_LACROS_H_
 
+#include <memory>
+
 #include "ui/views/controls/views_text_services_context_menu_base.h"
 
+namespace chromeos::clipboard_history {
+class ClipboardHistorySubmenuModel;
+}  // namespace chromeos::clipboard_history
+
 namespace ui {
 class SimpleMenuModel;
 }  // namespace ui
@@ -38,6 +44,11 @@
   bool IsCommandIdEnabled(int command_id) const override;
   void ExecuteCommand(int command_id, int event_flags) override;
   bool SupportsCommand(int command_id) const override;
+
+  // A submenu model to contain clipboard history item descriptors. Used only if
+  // the clipboard history refresh feature is enabled.
+  std::unique_ptr<chromeos::clipboard_history::ClipboardHistorySubmenuModel>
+      submenu_model_;
 };
 
 }  // namespace crosapi
diff --git a/chrome/browser/lacros/web_app_provider_bridge_lacros.cc b/chrome/browser/lacros/web_app_provider_bridge_lacros.cc
index 4bb6844..43a09f3 100644
--- a/chrome/browser/lacros/web_app_provider_bridge_lacros.cc
+++ b/chrome/browser/lacros/web_app_provider_bridge_lacros.cc
@@ -3,15 +3,18 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/lacros/web_app_provider_bridge_lacros.h"
+
 #include "base/functional/bind.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/apps/app_service/webapk/webapk_utils.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/office_web_app/office_web_app.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/web_applications/commands/install_preloaded_verified_app_command.h"
 #include "chrome/browser/web_applications/locks/all_apps_lock.h"
 #include "chrome/browser/web_applications/locks/app_lock.h"
 #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
+#include "chrome/browser/web_applications/web_app_command_manager.h"
 #include "chrome/browser/web_applications/web_app_command_scheduler.h"
 #include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_id.h"
@@ -26,7 +29,7 @@
 #include "components/webapps/browser/installable/installable_metrics.h"
 #include "url/gurl.h"
 
-namespace crosapi {
+    namespace crosapi {
 
 WebAppProviderBridgeLacros::WebAppProviderBridgeLacros() {
   auto* service = chromeos::LacrosService::Get();
@@ -107,6 +110,16 @@
                      std::move(callback)));
 }
 
+void WebAppProviderBridgeLacros::InstallPreloadWebApp(
+    mojom::PreloadWebAppInstallInfoPtr preload_install_info,
+    InstallPreloadWebAppCallback callback) {
+  g_browser_process->profile_manager()->LoadProfileByPath(
+      ProfileManager::GetPrimaryUserProfilePath(),
+      /*incognito=*/false,
+      base::BindOnce(&WebAppProviderBridgeLacros::InstallPreloadWebAppImpl,
+                     std::move(preload_install_info), std::move(callback)));
+}
+
 // static
 void WebAppProviderBridgeLacros::WebAppInstalledInArcImpl(
     mojom::ArcWebAppInstallInfoPtr arc_install_info,
@@ -208,4 +221,24 @@
       }).Then(std::move(callback)));
 }
 
+// static
+void WebAppProviderBridgeLacros::InstallPreloadWebAppImpl(
+    mojom::PreloadWebAppInstallInfoPtr preload_install_info,
+    InstallPreloadWebAppCallback callback, Profile * profile) {
+  CHECK(profile);
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
+
+  // TODO(b/284053861) Move allowlist into InstallPreloadedVerifiedAppCommand.
+  base::flat_set<std::string> host_allowlist = {
+      "meltingpot.googleusercontent.com", "127.0.0.1" /*FOR TESTING*/};
+
+  provider->command_manager().ScheduleCommand(
+      std::make_unique<web_app::InstallPreloadedVerifiedAppCommand>(
+          webapps::WebappInstallSource::PRELOADED_OEM,
+          preload_install_info->document_url,
+          preload_install_info->manifest_url, preload_install_info->manifest,
+          preload_install_info->expected_app_id, std::move(host_allowlist),
+          std::move(callback)));
+}
+
 }  // namespace crosapi
diff --git a/chrome/browser/lacros/web_app_provider_bridge_lacros.h b/chrome/browser/lacros/web_app_provider_bridge_lacros.h
index ce9180b62..e4bd138 100644
--- a/chrome/browser/lacros/web_app_provider_bridge_lacros.h
+++ b/chrome/browser/lacros/web_app_provider_bridge_lacros.h
@@ -39,6 +39,9 @@
   void GetSubAppIds(const web_app::AppId& app_id,
                     GetSubAppIdsCallback callback) override;
   void GetSubAppToParentMap(GetSubAppToParentMapCallback callback) override;
+  void InstallPreloadWebApp(
+      mojom::PreloadWebAppInstallInfoPtr preload_install_info,
+      InstallPreloadWebAppCallback callback) override;
 
  private:
   static void WebAppInstalledInArcImpl(
@@ -65,6 +68,10 @@
                                Profile* profile);
   static void GetSubAppToParentMapImpl(GetSubAppToParentMapCallback callback,
                                        Profile* profile);
+  static void InstallPreloadWebAppImpl(
+      mojom::PreloadWebAppInstallInfoPtr preload_install_info,
+      InstallPreloadWebAppCallback callback,
+      Profile* profile);
 
   mojo::Receiver<mojom::WebAppProviderBridge> receiver_{this};
 };
diff --git a/chrome/browser/lifetime/application_lifetime_chromeos.cc b/chrome/browser/lifetime/application_lifetime_chromeos.cc
index fe9a88f..ba74fd8b 100644
--- a/chrome/browser/lifetime/application_lifetime_chromeos.cc
+++ b/chrome/browser/lifetime/application_lifetime_chromeos.cc
@@ -5,13 +5,17 @@
 #include "chrome/browser/lifetime/application_lifetime_chromeos.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 
+#include "ash/constants/ash_pref_names.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/trace_event/trace_event.h"
 #include "base/values.h"
 #include "chrome/browser/ash/boot_times_recorder.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/lifetime/application_lifetime_chromeos.h"
 #include "chrome/browser/lifetime/termination_notification.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/ash/components/dbus/dbus_thread_manager.h"
 #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
@@ -22,6 +26,7 @@
 #include "components/language/core/browser/pref_names.h"
 #include "components/language/core/common/locale_util.h"
 #include "components/prefs/pref_service.h"
+#include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_thread.h"
 
 namespace chrome {
@@ -44,12 +49,61 @@
 // Whether Chrome should send stop request to a session manager.
 bool g_send_stop_request_to_session_manager = false;
 
+void ReportSessionUMAMetrics() {
+  // GetProfileByUser() will crash in tests if profile_manager() from
+  // g_browser_process is not initialized.
+  if (!user_manager::UserManager::IsInitialized() ||
+      !g_browser_process->profile_manager()) {
+    return;
+  }
+
+  const user_manager::User* primary_user =
+      user_manager::UserManager::Get()->GetPrimaryUser();
+  if (!primary_user) {
+    return;
+  }
+
+  Profile* profile = ash::ProfileHelper::Get()->GetProfileByUser(primary_user);
+  // Could be nullptr in tests.
+  if (!profile) {
+    return;
+  }
+
+  PrefService* prefs = profile->GetPrefs();
+  if (!prefs) {
+    return;
+  }
+
+  base::Time session_start_time =
+      prefs->GetTime(ash::prefs::kAshLoginSessionStartedTime);
+  if (!session_start_time.is_null()) {
+    base::TimeDelta duration = base::Time::Now() - session_start_time;
+    // Use CustomCounts histogram instead of CustomTimes because the latter
+    // allows 24 days maximum (data size limit) but we need 1 month.
+    if (prefs->GetBoolean(ash::prefs::kAshLoginSessionStartedIsFirstSession)) {
+      // Report 1 minute ... 30 days in minutes.
+      base::UmaHistogramCustomCounts("Ash.Login.TotalFirstSessionDuration",
+                                     duration.InMinutes(), 1,
+                                     base::Days(30) / base::Minutes(1), 100);
+    } else {
+      // Report 1 minute ... 30 days in minutes.
+      base::UmaHistogramCustomCounts("Ash.Login.TotalSessionDuration",
+                                     duration.InMinutes(), 1,
+                                     base::Days(30) / base::Minutes(1), 100);
+    }
+  }
+  prefs->ClearPref(ash::prefs::kAshLoginSessionStartedTime);
+  prefs->ClearPref(ash::prefs::kAshLoginSessionStartedIsFirstSession);
+}
+
 }  // namespace
 
 void AttemptUserExit() {
   VLOG(1) << "AttemptUserExit";
   ash::BootTimesRecorder::Get()->AddLogoutTimeMarker("LogoutStarted", false);
 
+  ReportSessionUMAMetrics();
+
   PrefService* state = g_browser_process->local_state();
   if (state) {
     ash::BootTimesRecorder::Get()->OnLogoutStarted(state);
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc
index f5c17fe1..1ae83de 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -110,6 +110,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/buildflags.h"
+#include "components/supervised_user/core/common/buildflags.h"
 #include "components/sync/service/passphrase_type_metrics_provider.h"
 #include "components/sync/service/sync_service.h"
 #include "components/sync_device_info/device_count_metrics_provider.h"
diff --git a/chrome/browser/nearby_sharing/OWNERS b/chrome/browser/nearby_sharing/OWNERS
index 81f28f2..f516980 100644
--- a/chrome/browser/nearby_sharing/OWNERS
+++ b/chrome/browser/nearby_sharing/OWNERS
@@ -2,3 +2,4 @@
 hansberry@chromium.org
 hansenmichael@google.com
 pushi@google.com
+cclem@google.com
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
index 9af2c753..4771326 100644
--- a/chrome/browser/net/system_network_context_manager.cc
+++ b/chrome/browser/net/system_network_context_manager.cc
@@ -795,7 +795,7 @@
 
   // If a custom proxy for IP protection is specified by either command line
   // switch or Finch experiment flag, set the proxy rules
-  if (command_line.HasSwitch(::switches::kIPAnonymizationProxyServer) ||
+  if (command_line.HasSwitch(network::switches::kIPAnonymizationProxyServer) ||
       base::FeatureList::IsEnabled(net::features::kEnableIpProtectionProxy)) {
     auto proxy_config = network::mojom::CustomProxyConfig::New();
     proxy_config->rules.type =
@@ -803,9 +803,9 @@
 
     // Command line input takes precedence over flag configuration
     std::string ip_protection_proxy_server =
-        command_line.HasSwitch(::switches::kIPAnonymizationProxyServer)
+        command_line.HasSwitch(network::switches::kIPAnonymizationProxyServer)
             ? command_line.GetSwitchValueASCII(
-                  ::switches::kIPAnonymizationProxyServer)
+                  network::switches::kIPAnonymizationProxyServer)
             : net::features::kIpPrivacyProxyServer.Get();
 
     proxy_config->rules.ParseFromString(ip_protection_proxy_server);
@@ -813,9 +813,9 @@
     // Get allowlist hosts, command line input takes precedence over flag
     // configuration
     std::string ip_protection_proxy_allow_list =
-        command_line.HasSwitch(::switches::kIPAnonymizationProxyServer)
+        command_line.HasSwitch(network::switches::kIPAnonymizationProxyServer)
             ? command_line.GetSwitchValueASCII(
-                  ::switches::kIPAnonymizationProxyAllowList)
+                  network::switches::kIPAnonymizationProxyAllowList)
             : net::features::kIpPrivacyProxyAllowlist.Get();
 
     proxy_config->rules.reverse_bypass = true;
@@ -828,7 +828,7 @@
     proxy_config->connect_tunnel_headers.SetHeader(
         kIPAnonymizationProxyPassword,
         command_line.GetSwitchValueASCII(
-            ::switches::kIPAnonymizationProxyPassword));
+            network::switches::kIPAnonymizationProxyPassword));
 
     // Set initial custom proxy configuration
     network_context_params->initial_custom_proxy_config =
diff --git a/chrome/browser/net/system_network_context_manager_browsertest.cc b/chrome/browser/net/system_network_context_manager_browsertest.cc
index 4dbc522..b856fc79 100644
--- a/chrome/browser/net/system_network_context_manager_browsertest.cc
+++ b/chrome/browser/net/system_network_context_manager_browsertest.cc
@@ -43,6 +43,7 @@
 #include "net/proxy_resolution/proxy_info.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/network_service_buildflags.h"
+#include "services/network/public/cpp/network_switches.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/network_service.mojom.h"
 #include "services/network/public/mojom/network_service_test.mojom.h"
@@ -219,13 +220,13 @@
   void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
     SystemNetworkContextManagerBrowsertest::SetUpDefaultCommandLine(
         command_line);
-    command_line->AppendSwitchASCII(switches::kIPAnonymizationProxyServer,
-                                    "testproxy:80");
     command_line->AppendSwitchASCII(
-        switches::kIPAnonymizationProxyAllowList,
+        network::switches::kIPAnonymizationProxyServer, "testproxy:80");
+    command_line->AppendSwitchASCII(
+        network::switches::kIPAnonymizationProxyAllowList,
         "a.test, foo.a.test, foo.test, b.test:1234");
-    command_line->AppendSwitchASCII(switches::kIPAnonymizationProxyPassword,
-                                    "value");
+    command_line->AppendSwitchASCII(
+        network::switches::kIPAnonymizationProxyPassword, "value");
   }
 };
 
diff --git a/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc b/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc
index 466419d..4e9cd1e 100644
--- a/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc
+++ b/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc
@@ -28,6 +28,7 @@
 #include "components/network_session_configurator/common/network_switches.h"
 #include "components/search/ntp_features.h"
 #include "content/public/browser/devtools_agent_host_client.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -189,17 +190,15 @@
                 const std::string& screenshot_name) {
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
     (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
-    if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-            "browser-ui-tests-verify-pixels")) {
-      return true;
+    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+            switches::kVerifyPixels)) {
+      views::ViewSkiaGoldPixelDiff pixel_diff;
+      pixel_diff.Init(screenshot_prefix);
+      return pixel_diff.CompareViewScreenshot(
+          screenshot_name, browser_view_->contents_web_view());
     }
-    views::ViewSkiaGoldPixelDiff pixel_diff;
-    pixel_diff.Init(screenshot_prefix);
-    return pixel_diff.CompareViewScreenshot(screenshot_name,
-                                            browser_view_->contents_web_view());
-#else
-    return true;
 #endif
+    return true;
   }
 
  protected:
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/largest_contentful_paint.html b/chrome/browser/page_load_metrics/integration_tests/data/largest_contentful_paint.html
index 60291c0..3b19523 100644
--- a/chrome/browser/page_load_metrics/integration_tests/data/largest_contentful_paint.html
+++ b/chrome/browser/page_load_metrics/integration_tests/data/largest_contentful_paint.html
@@ -72,21 +72,21 @@
     });
   };
 
-  // Adds the first image "green-16x16.png" to "content_div_1". We expect this
+  // Adds the first image "lcp-16x16.png" to "content_div_1". We expect this
   // operation to trigger a new LCP entry.
   const add_first_image = () => {
     let img = document.createElement("img");
     content_div_1.appendChild(img);
-    img.src = "images/green-16x16.png";
+    img.src = "images/lcp-16x16.png";
   };
 
-  // Adds another image that is larger than "green-16x16.png". We expect this
+  // Adds another image that is larger than "lcp-16x16.png". We expect this
   // operation to trigger a new LCP entry.
   const add_larger_image = () => {
     let new_img = document.createElement("img");
     content_div_2.appendChild(new_img);
-    new_img.src = "images/blue96x96.png";
-    new_img.id = "blue_image";
+    new_img.src = "images/lcp-96x96.png";
+    new_img.id = "larger_image";
   };
 
   // Adds the largest image. We expect this
@@ -94,15 +94,15 @@
   const add_largest_image = () => {
     let new_img = document.createElement("img");
     content_div_2.appendChild(new_img);
-    new_img.src = "images/green-256x256.png";
+    new_img.src = "images/lcp-256x256.png";
   };
 
   // Removes the image added by 'add_larger_image'. We expect this operation to
   // not trigger a new LCP entry.
   const remove_larger_image = () => {
-    const blue_image = document.getElementById("blue_image");
-    assert_not_equals(blue_image, null);
-    content_div_2.removeChild(blue_image);
+    const larger_image = document.getElementById("larger_image");
+    assert_not_equals(larger_image, null);
+    content_div_2.removeChild(larger_image);
   };
 
   const waitForAnimationFrames = frameCount => {
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/mouseover.html b/chrome/browser/page_load_metrics/integration_tests/data/mouseover.html
index 29f884c..5bcd59bd 100644
--- a/chrome/browser/page_load_metrics/integration_tests/data/mouseover.html
+++ b/chrome/browser/page_load_metrics/integration_tests/data/mouseover.html
@@ -1,5 +1,5 @@
 <body>
-<img src="/images/green-16x16.png" id=image>
+<img src="/images/lcp-16x16.png" id=image>
 <span id=span style="display: inline-block;width: 15px; height: 15px"></span>
 <script>
 const image = document.getElementById("image");
@@ -12,7 +12,7 @@
     } else {
       zoom = new Image();
     }
-    zoom.src=`/images/green-${size}.png`;
+    zoom.src=`/images/lcp-${size}.png`;
     document.body.appendChild(zoom);
   }
 };
@@ -21,7 +21,8 @@
     const div = document.createElement("div");
     const [width, height] = size.split("x");
     div.style = `background-image:
-      url(/images/green-${size}.png); width: ${width}px; height: ${height}px`;
+      url(/images/lcp-${size}.png);
+      width: ${width}px; height: ${height}px`;
     document.body.appendChild(div);
   }
 };
diff --git a/chrome/browser/page_load_metrics/integration_tests/jsdeps.gni b/chrome/browser/page_load_metrics/integration_tests/jsdeps.gni
index f47ec04..39e8530 100644
--- a/chrome/browser/page_load_metrics/integration_tests/jsdeps.gni
+++ b/chrome/browser/page_load_metrics/integration_tests/jsdeps.gni
@@ -14,6 +14,11 @@
   "//third_party/blink/web_tests/external/wpt/images/green-256x256.png",
   "//third_party/blink/web_tests/external/wpt/images/green-2x2.png",
   "//third_party/blink/web_tests/external/wpt/images/green.avif",
+  "//third_party/blink/web_tests/external/wpt/images/lcp-100x50.png",
+  "//third_party/blink/web_tests/external/wpt/images/lcp-16x16.png",
+  "//third_party/blink/web_tests/external/wpt/images/lcp-256x256.png",
+  "//third_party/blink/web_tests/external/wpt/images/lcp-2x2.png",
+  "//third_party/blink/web_tests/external/wpt/images/lcp-96x96.png",
   "//third_party/blink/web_tests/external/wpt/images/pattern.ogv",
   "//third_party/blink/web_tests/external/wpt/images/webp-animated.webp",
   "//third_party/blink/web_tests/external/wpt/layout-instability/main-frame.html",
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
index ba27324..95d2992 100644
--- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -109,11 +109,11 @@
   const std::string window_origin =
       EvalJs(web_contents(), "window.origin").ExtractString();
   const std::string image_1_url_expected =
-      base::StrCat({window_origin, "/images/green-16x16.png"});
+      base::StrCat({window_origin, "/images/lcp-16x16.png"});
   const std::string image_2_url_expected =
-      base::StrCat({window_origin, "/images/blue96x96.png"});
+      base::StrCat({window_origin, "/images/lcp-96x96.png"});
   const std::string image_3_url_expected =
-      base::StrCat({window_origin, "/images/green-256x256.png"});
+      base::StrCat({window_origin, "/images/lcp-256x256.png"});
   const std::string expected_url[3] = {
       image_1_url_expected, image_2_url_expected, image_3_url_expected};
 
@@ -1001,7 +1001,7 @@
   Load("/lcp_breakdown_timings.html");
 
   // Load an image.
-  const std::string url1 = "/images/green-16x16.png";
+  const std::string url1 = "/images/lcp-16x16.png";
   const std::string element_id1 = "image";
   EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
                    content::JsReplace("addImage($1, $2)", url1, element_id1))
@@ -1016,7 +1016,7 @@
   // The UKM recorded LCP should be that of the second image, which should be
   // larger than the LCP of first image.
 
-  const std::string url2 = "/images/green-256x256.png";
+  const std::string url2 = "/images/lcp-256x256.png";
   const std::string element_id2 = "larger_image";
 
   EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
diff --git a/chrome/browser/page_load_metrics/observers/histogram_suffixes.cc b/chrome/browser/page_load_metrics/observers/histogram_suffixes.cc
index 970e316..77bd04a 100644
--- a/chrome/browser/page_load_metrics/observers/histogram_suffixes.cc
+++ b/chrome/browser/page_load_metrics/observers/histogram_suffixes.cc
@@ -21,6 +21,8 @@
 const char kHistogramFirstPaintSuffix[] = "PaintTiming.NavigationToFirstPaint";
 const char kHistogramForegroundToFirstContentfulPaintSuffix[] =
     "PaintTiming.ForegroundToFirstContentfulPaint";
+const char kHistogramLargestContentfulPaintSuffix[] =
+    "PaintTiming.NavigationToLargestContentfulPaint";
 const char kHistogramLoadEventFiredBackgroundSuffix[] =
     "DocumentTiming.NavigationToLoadEventFired.Background";
 const char kHistogramLoadEventFiredSuffix[] =
diff --git a/chrome/browser/page_load_metrics/observers/histogram_suffixes.h b/chrome/browser/page_load_metrics/observers/histogram_suffixes.h
index f30e286a..1d0efd5 100644
--- a/chrome/browser/page_load_metrics/observers/histogram_suffixes.h
+++ b/chrome/browser/page_load_metrics/observers/histogram_suffixes.h
@@ -16,6 +16,7 @@
 extern const char kHistogramFirstMeaningfulPaintSuffix[];
 extern const char kHistogramFirstPaintSuffix[];
 extern const char kHistogramForegroundToFirstContentfulPaintSuffix[];
+extern const char kHistogramLargestContentfulPaintSuffix[];
 extern const char kHistogramLoadEventFiredBackgroundSuffix[];
 extern const char kHistogramLoadEventFiredSuffix[];
 extern const char kHistogramParseBlockedOnScriptLoadSuffix[];
diff --git a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.cc
index 2cff97d0..f03ede8 100644
--- a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.cc
@@ -24,18 +24,32 @@
 
 const char kHistogramPrefixMultiTabLoading[] =
     "PageLoad.Clients.MultiTabLoading.";
+const char kHistogramPrefixMultiTabLoading1OrMore[] =
+    "PageLoad.Clients.MultiTabLoading.1OrMore.";
 const char kHistogramPrefixMultiTabLoading2OrMore[] =
     "PageLoad.Clients.MultiTabLoading.2OrMore.";
 const char kHistogramPrefixMultiTabLoading5OrMore[] =
     "PageLoad.Clients.MultiTabLoading.5OrMore.";
+const char kHistogramPrefixMultiTabLoading0[] =
+    "PageLoad.Clients.MultiTabLoading.With_0_OtherLoading.";
+const char kHistogramPrefixMultiTabLoading1[] =
+    "PageLoad.Clients.MultiTabLoading.With_1_OtherLoading.";
+const char kHistogramPrefixMultiTabLoading2[] =
+    "PageLoad.Clients.MultiTabLoading.With_2_OtherLoading.";
+const char kHistogramPrefixMultiTabLoading3[] =
+    "PageLoad.Clients.MultiTabLoading.With_3_OtherLoading.";
+const char kHistogramPrefixMultiTabLoading4[] =
+    "PageLoad.Clients.MultiTabLoading.With_4_OtherLoading.";
+const char kHistogramPrefixMultiTabLoading5[] =
+    "PageLoad.Clients.MultiTabLoading.With_5_OtherLoading.";
 
 }  // namespace internal
 
 MultiTabLoadingPageLoadMetricsObserver::
-    MultiTabLoadingPageLoadMetricsObserver() {}
+    MultiTabLoadingPageLoadMetricsObserver() = default;
 
 MultiTabLoadingPageLoadMetricsObserver::
-    ~MultiTabLoadingPageLoadMetricsObserver() {}
+    ~MultiTabLoadingPageLoadMetricsObserver() = default;
 
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 MultiTabLoadingPageLoadMetricsObserver::OnStart(
@@ -44,8 +58,7 @@
     bool started_in_foreground) {
   num_loading_tabs_when_started_ =
       NumberOfTabsWithInflightLoad(navigation_handle);
-  return num_loading_tabs_when_started_ > 0 ? CONTINUE_OBSERVING
-                                            : STOP_OBSERVING;
+  return CONTINUE_OBSERVING;
 }
 
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
@@ -64,24 +77,28 @@
   return STOP_OBSERVING;
 }
 
-#define RECORD_HISTOGRAMS(suffix, sample)                                      \
-  do {                                                                         \
-    base::TimeDelta sample_value(sample);                                      \
-    PAGE_LOAD_HISTOGRAM(                                                       \
-        std::string(internal::kHistogramPrefixMultiTabLoading).append(suffix), \
-        sample_value);                                                         \
-    if (num_loading_tabs_when_started_ >= 2) {                                 \
-      PAGE_LOAD_HISTOGRAM(                                                     \
-          std::string(internal::kHistogramPrefixMultiTabLoading2OrMore)        \
-              .append(suffix),                                                 \
-          sample_value);                                                       \
-    }                                                                          \
-    if (num_loading_tabs_when_started_ >= 5) {                                 \
-      PAGE_LOAD_HISTOGRAM(                                                     \
-          std::string(internal::kHistogramPrefixMultiTabLoading5OrMore)        \
-              .append(suffix),                                                 \
-          sample_value);                                                       \
-    }                                                                          \
+#define RECORD_HISTOGRAM(condition, name)                                   \
+  if (condition) {                                                          \
+    PAGE_LOAD_HISTOGRAM(                                                    \
+        std::string(internal::kHistogramPrefix##name).append(suffix_value), \
+        sample_value);                                                      \
+  }
+
+#define RECORD_HISTOGRAMS(suffix, sample)            \
+  do {                                               \
+    int n = num_loading_tabs_when_started_;          \
+    const char* suffix_value = suffix;               \
+    base::TimeDelta sample_value(sample);            \
+    RECORD_HISTOGRAM(n >= 1, MultiTabLoading)        \
+    RECORD_HISTOGRAM(n >= 1, MultiTabLoading1OrMore) \
+    RECORD_HISTOGRAM(n >= 2, MultiTabLoading2OrMore) \
+    RECORD_HISTOGRAM(n >= 5, MultiTabLoading5OrMore) \
+    RECORD_HISTOGRAM(n == 0, MultiTabLoading0)       \
+    RECORD_HISTOGRAM(n == 1, MultiTabLoading1)       \
+    RECORD_HISTOGRAM(n == 2, MultiTabLoading2)       \
+    RECORD_HISTOGRAM(n == 3, MultiTabLoading3)       \
+    RECORD_HISTOGRAM(n == 4, MultiTabLoading4)       \
+    RECORD_HISTOGRAM(n == 5, MultiTabLoading5)       \
   } while (false)
 
 void MultiTabLoadingPageLoadMetricsObserver::OnFirstContentfulPaintInPage(
@@ -138,6 +155,34 @@
   }
 }
 
+void MultiTabLoadingPageLoadMetricsObserver::OnComplete(
+    const page_load_metrics::mojom::PageLoadTiming& timing) {
+  RecordTimingHistograms();
+}
+
+page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+MultiTabLoadingPageLoadMetricsObserver::FlushMetricsOnAppEnterBackground(
+    const page_load_metrics::mojom::PageLoadTiming& timing) {
+  // This follows UmaPageLoadMetricsObserver.
+  if (GetDelegate().DidCommit()) {
+    RecordTimingHistograms();
+  }
+  return STOP_OBSERVING;
+}
+
+void MultiTabLoadingPageLoadMetricsObserver::RecordTimingHistograms() {
+  const page_load_metrics::ContentfulPaintTimingInfo& largest_contentful_paint =
+      GetDelegate()
+          .GetLargestContentfulPaintHandler()
+          .MergeMainFrameAndSubframes();
+  if (largest_contentful_paint.ContainsValidTime() &&
+      WasStartedInForegroundOptionalEventInForeground(
+          largest_contentful_paint.Time(), GetDelegate())) {
+    RECORD_HISTOGRAMS(internal::kHistogramLargestContentfulPaintSuffix,
+                      largest_contentful_paint.Time().value());
+  }
+}
+
 #if BUILDFLAG(IS_ANDROID)
 
 int MultiTabLoadingPageLoadMetricsObserver::NumberOfTabsWithInflightLoad(
diff --git a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.h
index 835dc44..aee834e9 100644
--- a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.h
@@ -15,8 +15,15 @@
 
 // Exposed for tests.
 extern const char kHistogramPrefixMultiTabLoading[];
+extern const char kHistogramPrefixMultiTabLoading1OrMore[];
 extern const char kHistogramPrefixMultiTabLoading2OrMore[];
 extern const char kHistogramPrefixMultiTabLoading5OrMore[];
+extern const char kHistogramPrefixMultiTabLoading0[];
+extern const char kHistogramPrefixMultiTabLoading1[];
+extern const char kHistogramPrefixMultiTabLoading2[];
+extern const char kHistogramPrefixMultiTabLoading3[];
+extern const char kHistogramPrefixMultiTabLoading4[];
+extern const char kHistogramPrefixMultiTabLoading5[];
 
 }  // namespace internal
 
@@ -61,6 +68,13 @@
       content::NavigationHandle* navigation_handle);
 
  private:
+  void OnComplete(
+      const page_load_metrics::mojom::PageLoadTiming& timing) override;
+  page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+  FlushMetricsOnAppEnterBackground(
+      const page_load_metrics::mojom::PageLoadTiming& timing) override;
+  void RecordTimingHistograms();
+
   int num_loading_tabs_when_started_;
 };
 
diff --git a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_unittest.cc
index 2045c15..9b39771 100644
--- a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "chrome/browser/page_load_metrics/observers/histogram_suffixes.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
+#include "components/page_load_metrics/browser/observers/core/uma_page_load_metrics_observer.h"
 #include "components/page_load_metrics/browser/page_load_tracker.h"
 #include "components/page_load_metrics/common/test/page_load_metrics_test_util.h"
 #include "content/public/browser/web_contents.h"
@@ -23,7 +24,7 @@
   explicit TestMultiTabLoadingPageLoadMetricsObserver(
       int number_of_tabs_with_inflight_load)
       : number_of_tabs_with_inflight_load_(number_of_tabs_with_inflight_load) {}
-  ~TestMultiTabLoadingPageLoadMetricsObserver() override {}
+  ~TestMultiTabLoadingPageLoadMetricsObserver() override = default;
 
  private:
   int NumberOfTabsWithInflightLoad(
@@ -51,6 +52,10 @@
     timing.parse_timing->parse_start = base::Milliseconds(300);
     timing.paint_timing->first_contentful_paint = base::Milliseconds(300);
     timing.paint_timing->first_meaningful_paint = base::Milliseconds(700);
+    timing.paint_timing->largest_contentful_paint->largest_text_paint =
+        base::Milliseconds(800);
+    timing.paint_timing->largest_contentful_paint->largest_text_paint_size =
+        100u;
     timing.document_timing->dom_content_loaded_event_start =
         base::Milliseconds(600);
     timing.document_timing->load_event_start = base::Milliseconds(1000);
@@ -69,6 +74,9 @@
     }
 
     tester()->SimulateTimingUpdate(timing);
+
+    // Navigate to about:blank to force histogram recording.
+    NavigateAndCommit(GURL("about:blank"));
   }
 
  protected:
@@ -79,12 +87,22 @@
   }
 
   void ValidateHistograms(const char* suffix,
-                          base::HistogramBase::Count expected_base,
+                          base::HistogramBase::Count expected_1_or_more,
                           base::HistogramBase::Count expected_2_or_more,
-                          base::HistogramBase::Count expected_5_or_more) {
+                          base::HistogramBase::Count expected_5_or_more,
+                          base::HistogramBase::Count expected_0,
+                          base::HistogramBase::Count expected_1,
+                          base::HistogramBase::Count expected_2,
+                          base::HistogramBase::Count expected_3,
+                          base::HistogramBase::Count expected_4,
+                          base::HistogramBase::Count expected_5) {
     tester()->histogram_tester().ExpectTotalCount(
         std::string(internal::kHistogramPrefixMultiTabLoading).append(suffix),
-        expected_base);
+        expected_1_or_more);
+    tester()->histogram_tester().ExpectTotalCount(
+        std::string(internal::kHistogramPrefixMultiTabLoading1OrMore)
+            .append(suffix),
+        expected_1_or_more);
     tester()->histogram_tester().ExpectTotalCount(
         std::string(internal::kHistogramPrefixMultiTabLoading2OrMore)
             .append(suffix),
@@ -93,6 +111,24 @@
         std::string(internal::kHistogramPrefixMultiTabLoading5OrMore)
             .append(suffix),
         expected_5_or_more);
+    tester()->histogram_tester().ExpectTotalCount(
+        std::string(internal::kHistogramPrefixMultiTabLoading0).append(suffix),
+        expected_0);
+    tester()->histogram_tester().ExpectTotalCount(
+        std::string(internal::kHistogramPrefixMultiTabLoading1).append(suffix),
+        expected_1);
+    tester()->histogram_tester().ExpectTotalCount(
+        std::string(internal::kHistogramPrefixMultiTabLoading2).append(suffix),
+        expected_2);
+    tester()->histogram_tester().ExpectTotalCount(
+        std::string(internal::kHistogramPrefixMultiTabLoading3).append(suffix),
+        expected_3);
+    tester()->histogram_tester().ExpectTotalCount(
+        std::string(internal::kHistogramPrefixMultiTabLoading4).append(suffix),
+        expected_4);
+    tester()->histogram_tester().ExpectTotalCount(
+        std::string(internal::kHistogramPrefixMultiTabLoading5).append(suffix),
+        expected_5);
   }
 
  private:
@@ -102,79 +138,224 @@
 TEST_F(MultiTabLoadingPageLoadMetricsObserverTest, SingleTabLoading) {
   SimulatePageLoad(0, Foreground);
 
-  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix, 0, 0, 0);
+  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/1,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLargestContentfulPaintSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/1,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
   ValidateHistograms(internal::kHistogramForegroundToFirstContentfulPaintSuffix,
-                     0, 0, 0);
-  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix, 0, 0, 0);
-  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix, 0, 0,
-                     0);
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/1,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/1,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
   ValidateHistograms(
-      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix, 0, 0, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix, 0, 0, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix, 0, 0,
-                     0);
+      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix,
+      /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+      /*expected_5_or_more=*/0, /*expected_0=*/0, /*expected_1=*/0,
+      /*expected_2=*/0, /*expected_3=*/0, /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/1,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
 }
 
 TEST_F(MultiTabLoadingPageLoadMetricsObserverTest, MultiTabLoading1) {
   SimulatePageLoad(1, Foreground);
 
-  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix, 1, 0, 0);
+  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/1, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLargestContentfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/1, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
   ValidateHistograms(internal::kHistogramForegroundToFirstContentfulPaintSuffix,
-                     0, 0, 0);
-  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix, 1, 0, 0);
-  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix, 1, 0,
-                     0);
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/1, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/1, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
   ValidateHistograms(
-      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix, 0, 0, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix, 1, 0, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix, 0, 0,
-                     0);
+      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix,
+      /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+      /*expected_5_or_more=*/0, /*expected_0=*/0, /*expected_1=*/0,
+      /*expected_2=*/0, /*expected_3=*/0, /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/1, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
 }
 
 TEST_F(MultiTabLoadingPageLoadMetricsObserverTest, MultiTabLoading2) {
   SimulatePageLoad(2, Foreground);
 
-  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix, 1, 1, 0);
+  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/1, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLargestContentfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/0,
+                     /*expected_0=*/0, /*expected_1=*/0, /*expected_2=*/1,
+                     /*expected_3=*/0, /*expected_4=*/0, /*expected_5=*/0);
   ValidateHistograms(internal::kHistogramForegroundToFirstContentfulPaintSuffix,
-                     0, 0, 0);
-  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix, 1, 1, 0);
-  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix, 1, 1,
-                     0);
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/1, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/1, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
   ValidateHistograms(
-      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix, 0, 0, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix, 1, 1, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix, 0, 0,
-                     0);
+      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix,
+      /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+      /*expected_5_or_more=*/0, /*expected_0=*/0, /*expected_1=*/0,
+      /*expected_2=*/0, /*expected_3=*/0, /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/1, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
 }
 
 TEST_F(MultiTabLoadingPageLoadMetricsObserverTest, MultiTabLoading5) {
   SimulatePageLoad(5, Foreground);
 
-  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix, 1, 1, 1);
+  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/1, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/1);
+  ValidateHistograms(internal::kHistogramLargestContentfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/1,
+                     /*expected_0=*/0, /*expected_1=*/0, /*expected_2=*/0,
+                     /*expected_3=*/0, /*expected_4=*/0, /*expected_5=*/1);
   ValidateHistograms(internal::kHistogramForegroundToFirstContentfulPaintSuffix,
-                     0, 0, 0);
-  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix, 1, 1, 1);
-  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix, 1, 1,
-                     1);
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/1, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/1);
+  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/1, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/1);
   ValidateHistograms(
-      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix, 0, 0, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix, 1, 1, 1);
-  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix, 0, 0,
-                     0);
+      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix,
+      /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+      /*expected_5_or_more=*/0, /*expected_0=*/0, /*expected_1=*/0,
+      /*expected_2=*/0, /*expected_3=*/0, /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/1,
+                     /*expected_5_or_more=*/1, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/1);
+  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
 }
 
 TEST_F(MultiTabLoadingPageLoadMetricsObserverTest, MultiTabBackground) {
   SimulatePageLoad(1, Background);
 
-  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix, 0, 0, 0);
+  ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLargestContentfulPaintSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
   ValidateHistograms(internal::kHistogramForegroundToFirstContentfulPaintSuffix,
-                     1, 0, 0);
-  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix, 0, 0, 0);
-  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix, 0, 0,
-                     0);
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/1, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramDOMContentLoadedEventFiredSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
   ValidateHistograms(
-      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix, 1, 0, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix, 0, 0, 0);
-  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix, 1, 0,
-                     0);
+      internal::kHistogramDOMContentLoadedEventFiredBackgroundSuffix,
+      /*expected_1_or_more=*/1, /*expected_2_or_more=*/0,
+      /*expected_5_or_more=*/0, /*expected_0=*/0, /*expected_1=*/1,
+      /*expected_2=*/0, /*expected_3=*/0, /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredSuffix,
+                     /*expected_1_or_more=*/0, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/0, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
+  ValidateHistograms(internal::kHistogramLoadEventFiredBackgroundSuffix,
+                     /*expected_1_or_more=*/1, /*expected_2_or_more=*/0,
+                     /*expected_5_or_more=*/0, /*expected_0=*/0,
+                     /*expected_1=*/1, /*expected_2=*/0, /*expected_3=*/0,
+                     /*expected_4=*/0, /*expected_5=*/0);
 }
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
index d8c91b93..29d7fcc 100644
--- a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
+++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
@@ -52,10 +52,13 @@
 
 PasskeyCredential CreatePasskey(std::vector<uint8_t> cred_id,
                                 std::string username) {
-  return PasskeyCredential(PasskeyCredential::Source::kAndroidPhone,
-                           std::string(kRpId), std::move(cred_id),
-                           device::fido_parsing_utils::Materialize(kUserId),
-                           std::move(username));
+  return PasskeyCredential(
+      PasskeyCredential::Source::kAndroidPhone,
+      PasskeyCredential::RpId(std::string(kRpId)),
+      PasskeyCredential::CredentialId(std::move(cred_id)),
+      PasskeyCredential::UserId(
+          device::fido_parsing_utils::Materialize(kUserId)),
+      PasskeyCredential::Username(std::move(username)));
 }
 
 }  // namespace
diff --git a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier.cc b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier.cc
index 2a2f95764..a265cded 100644
--- a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier.cc
+++ b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier.cc
@@ -4,10 +4,25 @@
 
 #include "chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier.h"
 
+#include <utility>
+#include <vector>
+
+#include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "chrome/browser/ui/performance_controls/resource_usage_tab_helper.h"
+#include "components/performance_manager/public/features.h"
 #include "components/performance_manager/public/graph/process_node.h"
+#include "components/performance_manager/public/web_contents_proxy.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
 
 namespace performance_manager::user_tuning {
 
+namespace {
+using ProxyAndPmfKbVector = std::vector<std::pair<WebContentsProxy, uint64_t>>;
+}
+
 const int UserPerformanceTuningNotifier::kTabCountThresholdForPromo = 10;
 const int UserPerformanceTuningNotifier::kMemoryPercentThresholdForPromo = 70;
 
@@ -78,6 +93,37 @@
 
   previous_total_rss_ = total_rss;
 
+  if (base::FeatureList::IsEnabled(
+          performance_manager::features::kMemoryUsageInHovercards)) {
+    ProxyAndPmfKbVector proxies_and_pmf;
+    std::vector<const PageNode*> all_page_nodes = graph_->GetAllPageNodes();
+    proxies_and_pmf.reserve(all_page_nodes.size());
+
+    for (auto* page_node : all_page_nodes) {
+      proxies_and_pmf.emplace_back(page_node->GetContentsProxy(),
+                                   page_node->EstimatePrivateFootprintSize());
+    }
+
+    content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
+        ->PostTask(
+            FROM_HERE,
+            base::BindOnce(
+                [](ProxyAndPmfKbVector web_contents_memory_usage) {
+                  for (const auto& [contents_proxy, pmf] :
+                       web_contents_memory_usage) {
+                    content::WebContents* web_contents = contents_proxy.Get();
+                    if (web_contents) {
+                      ResourceUsageTabHelper* helper =
+                          ResourceUsageTabHelper::FromWebContents(web_contents);
+                      if (helper) {
+                        helper->SetMemoryUsageInBytes(pmf * 1024);
+                      }
+                    }
+                  }
+                },
+                std::move(proxies_and_pmf)));
+  }
+
   receiver_->NotifyMemoryMetricsRefreshed();
 }
 
diff --git a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier_unittest.cc b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier_unittest.cc
index e9e2261c..11703cc 100644
--- a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier_unittest.cc
+++ b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier_unittest.cc
@@ -4,7 +4,25 @@
 
 #include "chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier.h"
 
+#include <memory>
+#include <utility>
+#include "base/run_loop.h"
+#include "base/task/bind_post_task.h"
+#include "base/task/task_traits.h"
+#include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ui/performance_controls/resource_usage_tab_helper.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/performance_manager/public/features.h"
+#include "components/performance_manager/public/graph/graph.h"
+#include "components/performance_manager/public/performance_manager.h"
 #include "components/performance_manager/test_support/graph_test_harness.h"
+#include "components/performance_manager/test_support/test_harness_helper.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/navigation_simulator.h"
+#include "content/public/test/test_web_contents_factory.h"
+#include "url/gurl.h"
 
 namespace performance_manager::user_tuning {
 
@@ -115,4 +133,92 @@
   EXPECT_EQ(2, receiver_->memory_refreshed_count_);
 }
 
+class UserPerformanceTuningNotifierWithWebContentsTest
+    : public ChromeRenderViewHostTestHarness {
+ public:
+  class TestReceiverWithCallback
+      : public UserPerformanceTuningNotifier::Receiver {
+   public:
+    ~TestReceiverWithCallback() override = default;
+
+    void NotifyTabCountThresholdReached() override {}
+
+    void NotifyMemoryThresholdReached() override {}
+
+    void NotifyMemoryMetricsRefreshed() override {
+      if (metrics_refreshed_callback_) {
+        content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
+            ->PostTask(FROM_HERE, std::move(metrics_refreshed_callback_));
+      }
+    }
+
+    void SetMemoryMetricsRefreshedCallback(
+        base::OnceClosure metrics_refreshed_callback) {
+      metrics_refreshed_callback_ = std::move(metrics_refreshed_callback);
+    }
+
+    base::OnceClosure metrics_refreshed_callback_;
+  };
+
+  void SetUp() override {
+    ChromeRenderViewHostTestHarness::SetUp();
+    pm_helper_.SetUp();
+
+    base::RunLoop run_loop;
+    auto receiver = std::make_unique<TestReceiverWithCallback>();
+    receiver_ = receiver.get();
+    PerformanceManager::CallOnGraph(
+        FROM_HERE, base::BindLambdaForTesting([&](Graph* graph) {
+          graph->PassToGraph(std::make_unique<ProcessMetricsDecorator>());
+          auto notifier = std::make_unique<UserPerformanceTuningNotifier>(
+              std::move(receiver), /*memory_theshold_kb=*/10,
+              /*tab_count_threshold=*/2);
+          graph->PassToGraph(std::move(notifier));
+          run_loop.Quit();
+        }));
+    run_loop.Run();
+  }
+
+  void TearDown() override {
+    pm_helper_.TearDown();
+    ChromeRenderViewHostTestHarness::TearDown();
+  }
+
+  PerformanceManagerTestHarnessHelper pm_helper_;
+  raw_ptr<TestReceiverWithCallback> receiver_;
+};
+
+TEST_F(UserPerformanceTuningNotifierWithWebContentsTest,
+       TestWritingMemoryUsageToTabHelper) {
+  // Enable memory usage in hovercards
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      performance_manager::features::kMemoryUsageInHovercards);
+
+  // Set the memory metrics refreshed callback ahead of navigation.
+  base::RunLoop run_loop;
+  receiver_->SetMemoryMetricsRefreshedCallback(run_loop.QuitClosure());
+
+  // Trigger a navigation so frames are set up.
+  SetContents(CreateTestWebContents());
+  ResourceUsageTabHelper::CreateForWebContents(web_contents());
+  content::NavigationSimulator::NavigateAndCommitFromBrowser(
+      web_contents(), GURL("https://www.example.com/"));
+
+  // Set active memory usage on the frame and process memory metrics.
+  PerformanceManager::CallOnGraph(
+      FROM_HERE, base::BindLambdaForTesting([&](Graph* graph) {
+        for (const FrameNode* node : graph->GetAllFrameNodes()) {
+          FrameNodeImpl::FromNode(node)->SetPrivateFootprintKbEstimate(11);
+        }
+        SystemNodeImpl::FromNode(graph->GetSystemNode())
+            ->OnProcessMemoryMetricsAvailable();
+      }));
+  run_loop.Run();
+
+  // Memory usage should be written to the tab helper.
+  auto* tab_helper = ResourceUsageTabHelper::FromWebContents(web_contents());
+  EXPECT_EQ(tab_helper->GetMemoryUsageInBytes(), 11u * 1024);
+}
+
 }  // namespace performance_manager::user_tuning
diff --git a/chrome/browser/policy/test/developer_tools_policy_browsertest.cc b/chrome/browser/policy/test/developer_tools_policy_browsertest.cc
index 53d06435..6d0978185 100644
--- a/chrome/browser/policy/test/developer_tools_policy_browsertest.cc
+++ b/chrome/browser/policy/test/developer_tools_policy_browsertest.cc
@@ -203,14 +203,11 @@
       DevToolsWindow::GetInstanceForInspectedWebContents(contents);
   EXPECT_TRUE(devtools_window);
 
-  // Disable devtools via policy.
-  PolicyMap policies;
-  policies.Set(key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::Value(2 /* DeveloperToolsDisallowed */), nullptr);
   content::WebContentsDestroyedWatcher close_observer(
       DevToolsWindowTesting::Get(devtools_window)->main_web_contents());
-  UpdateProviderPolicy(policies);
+  // Disable devtools via policy.
+  UpdateProviderPolicy(
+      MakeDeveloperToolsAvailabilityMap(2 /* DeveloperToolsDisallowed */));
   // wait for devtools close
   close_observer.Wait();
   // The existing devtools window should have closed.
@@ -260,11 +257,8 @@
   // DeveloperToolsAvailability policy.
 
   // Disable devtools via policy.
-  PolicyMap policies;
-  policies.Set(key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::Value(2 /* DeveloperToolsDisallowed */), nullptr);
-  UpdateProviderPolicy(policies);
+  UpdateProviderPolicy(
+      MakeDeveloperToolsAvailabilityMap(2 /* DeveloperToolsDisallowed */));
   // Verify that it's not possible to ViewSource.
   EXPECT_FALSE(chrome::ExecuteCommand(browser(), IDC_VIEW_SOURCE));
 }
@@ -315,11 +309,8 @@
                                              true);
 
   // Disable devtools via policy.
-  PolicyMap policies;
-  policies.Set(key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::Value(2 /*DeveloperToolsDisallowed*/), nullptr);
-  UpdateProviderPolicy(policies);
+  UpdateProviderPolicy(
+      MakeDeveloperToolsAvailabilityMap(2 /* DeveloperToolsDisallowed */));
 
   // Expect devcontrols to be hidden now...
   WaitForExtensionsDevModeControlsVisibility(contents, dev_controls_accessor_js,
diff --git a/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java b/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java
index dceb043..ffdddf6 100644
--- a/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java
+++ b/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java
@@ -113,6 +113,7 @@
 
     @Test
     @MediumTest
+    @DisabledTest(message = "https://crbug.com/1446002")
     public void testNavigateToTabSwitcher_WhenClickingDelete() throws IOException {
         openQuickDeleteDialog();
         onViewWaiting(withId(R.id.positive_button)).perform(click());
@@ -124,6 +125,7 @@
     @Test
     @MediumTest
     @Feature({"RenderTest"})
+    @DisabledTest(message = "https://crbug.com/1446002")
     public void testSnackbarShown_WhenClickingDelete() throws IOException {
         openQuickDeleteDialog();
         onViewWaiting(withId(R.id.positive_button)).perform(click());
diff --git a/chrome/browser/resources/bluetooth_internals/BUILD.gn b/chrome/browser/resources/bluetooth_internals/BUILD.gn
index d92cf35..58cb85c 100644
--- a/chrome/browser/resources/bluetooth_internals/BUILD.gn
+++ b/chrome/browser/resources/bluetooth_internals/BUILD.gn
@@ -2,137 +2,65 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//tools/grit/grit_rule.gni")
-import("//tools/polymer/html_to_wrapper.gni")
-import("//tools/typescript/ts_library.gni")
-import("//ui/webui/resources/tools/generate_grd.gni")
+import("//ui/webui/resources/tools/build_webui.gni")
 
-bluetooth_grd_prefix = "bluetooth_internals"
-resources_grd_file = "$target_gen_dir/resources.grd"
+build_webui("build") {
+  grd_prefix = "bluetooth_internals"
 
-html_files = [
-  "characteristic_list_item.html",
-  "descriptor_list_item.html",
-  "device_table.html",
-  "expandable_list.html",
-  "expandable_list_item.html",
-  "object_fieldset.html",
-  "service_list_item.html",
-  "snackbar.html",
-  "value_control.html",
-]
+  static_files = [
+    "bluetooth_internals.css",
+    "bluetooth_internals.html",
+    "menu.svg",
+  ]
 
-# Files generated by html_to_wrapper
-html_wrapper_files = []
-foreach(f, html_files) {
-  html_wrapper_files += [ f + ".ts" ]
-}
+  # TODO(crbug.com/1337318): Migrate to TypeScript.
+  web_component_files = [
+    "characteristic_list_item.js",
+    "descriptor_list_item.js",
+    "device_table.js",
+    "expandable_list.js",
+    "expandable_list_item.js",
+    "object_fieldset.js",
+    "service_list_item.js",
+    "snackbar.js",
+    "value_control.js",
+  ]
+  html_to_wrapper_template = "native"
 
-html_to_wrapper("html_wrapper_files") {
-  in_files = html_files
-  template = "native"
-}
+  non_web_component_files = [
+    "adapter_broker.js",
+    "adapter_page.js",
+    "characteristic_list.js",
+    "debug_log_page.js",
+    "descriptor_list.js",
+    "device_broker.js",
+    "device_collection.js",
+    "device_details_page.js",
+    "device_utils.js",
+    "devices_page.js",
+    "bluetooth_internals.js",
+    "main.js",
+    "page_manager.js",
+    "page.js",
+    "service_list.js",
+    "sidebar.js",
+  ]
 
-js_files = [
-  "adapter_broker.js",
-  "adapter_page.js",
-  "characteristic_list.js",
-  "characteristic_list_item.js",
-  "debug_log_page.js",
-  "descriptor_list.js",
-  "descriptor_list_item.js",
-  "device_broker.js",
-  "device_collection.js",
-  "device_details_page.js",
-  "device_table.js",
-  "device_utils.js",
-  "devices_page.js",
-  "expandable_list_item.js",
-  "expandable_list.js",
-  "bluetooth_internals.js",
-  "main.js",
-  "object_fieldset.js",
-  "page_manager.js",
-  "page.js",
-  "service_list.js",
-  "service_list_item.js",
-  "sidebar.js",
-  "snackbar.js",
-  "value_control.js",
-]
-
-mojom_files = [
-  "adapter.mojom-webui.ts",
-  "bluetooth_internals.mojom-webui.ts",
-  "device.mojom-webui.ts",
-  "uuid.mojom-webui.js",
-]
-
-copy("copy_mojom") {
-  deps = [
+  mojo_files_deps = [
     "//chrome/browser/ui/webui/bluetooth_internals:mojo_bindings_ts__generator",
     "//device/bluetooth/public/mojom:deprecated_experimental_interfaces_ts__generator",
     "//device/bluetooth/public/mojom:mojom_js__generator",
   ]
-  sources = [
+  mojo_files = [
     "$root_gen_dir/chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals.mojom-webui.ts",
     "$root_gen_dir/device/bluetooth/public/mojom/adapter.mojom-webui.ts",
     "$root_gen_dir/device/bluetooth/public/mojom/device.mojom-webui.ts",
     "$root_gen_dir/mojom-webui/device/bluetooth/public/mojom/uuid.mojom-webui.js",
   ]
-  outputs = [ "$target_gen_dir/{{source_file_part}}" ]
-}
 
-copy("copy_files") {
-  sources = js_files
-  outputs = [ "${target_gen_dir}/{{source_file_part}}" ]
-}
-
-# TODO(crbug.com/1337318): This page should be converted to TypeScript but this
-# will be a lot of work. Passing the JavaScript files through the TypeScript
-# compiler will provide basic static checks (e.g. syntax) without validating
-# types.
-ts_library("build_ts") {
-  root_dir = target_gen_dir
-  out_dir = "$target_gen_dir/tsc"
-  in_files = js_files + html_wrapper_files + mojom_files
-  deps = [
+  ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ]
+  ts_deps = [
     "//ui/webui/resources/js:build_ts",
     "//ui/webui/resources/mojo:build_ts",
   ]
-  extra_deps = [
-    ":copy_files",
-    ":copy_mojom",
-    ":html_wrapper_files",
-  ]
-}
-
-grit("resources") {
-  enable_input_discovery_for_gn_analyze = false
-  source = resources_grd_file
-
-  deps = [ ":build_grd" ]
-
-  outputs = [
-    "grit/bluetooth_internals_resources.h",
-    "grit/bluetooth_internals_resources_map.h",
-    "grit/bluetooth_internals_resources_map.cc",
-    "bluetooth_internals_resources.pak",
-  ]
-  output_dir = "$root_gen_dir/chrome"
-}
-
-generate_grd("build_grd") {
-  grd_prefix = bluetooth_grd_prefix
-  out_grd = resources_grd_file
-  deps = [ ":build_ts" ]
-  input_files = [
-    "bluetooth_internals.css",
-    "bluetooth_internals.html",
-    "menu.svg",
-  ]
-  input_files_base_dir = rebase_path(".", "//")
-
-  manifest_files =
-      filter_include(get_target_outputs(":build_ts"), [ "*.manifest" ])
 }
diff --git a/chrome/browser/resources/chromeos/emulator/device_emulator_pages.html b/chrome/browser/resources/chromeos/emulator/device_emulator_pages.html
index 221ee82..44bf64c 100644
--- a/chrome/browser/resources/chromeos/emulator/device_emulator_pages.html
+++ b/chrome/browser/resources/chromeos/emulator/device_emulator_pages.html
@@ -53,7 +53,7 @@
         clear-label="clear"
         autofocus
         search-prompt="Search not working..."
-        on-cr-toolbar-menu-tap="onMenuButtonClick_"
+        on-cr-toolbar-menu-click="onMenuButtonClick_"
         menu-label="Device Emulator"
         role="banner"
         show-menu>
diff --git a/chrome/browser/resources/chromeos/login/cr_ui.js b/chrome/browser/resources/chromeos/login/cr_ui.js
index d1bdf03d..5953836 100644
--- a/chrome/browser/resources/chromeos/login/cr_ui.js
+++ b/chrome/browser/resources/chromeos/login/cr_ui.js
@@ -51,6 +51,8 @@
    * Does the initial transition to the OOBE flow after booting animation.
    */
   static triggerDown() {
+    // Notify that we are going to play initial animation in the WebUI.
+    document.dispatchEvent(new CustomEvent('about-to-shrink'));
     // Delay this call to reduce the load during animation.
     setTimeout(() => Oobe.getInstance().triggerDown(), 0);
   }
diff --git a/chrome/browser/resources/chromeos/login/lazy_load_screens.js b/chrome/browser/resources/chromeos/login/lazy_load_screens.js
index 7fa8555..1beb335 100644
--- a/chrome/browser/resources/chromeos/login/lazy_load_screens.js
+++ b/chrome/browser/resources/chromeos/login/lazy_load_screens.js
@@ -14,6 +14,16 @@
 const flowSpecificScreensList = isOobeFlow ? oobeScreensList : loginScreensList;
 const lazyLoadingEnabled = loadTimeData.getBoolean('isOobeLazyLoadingEnabled');
 
+const isOobeSimon = loadTimeData.getBoolean('isOobeSimonEnabled');
+const animationTransitionTime = 900;
+let aboutToShrink = false;
+if (isOobeSimon) {
+  document.addEventListener('about-to-shrink', () => {
+    aboutToShrink = true;
+  }, {once: true});
+}
+
+
 if (lazyLoadingEnabled) {
   addScreensAsync();
 } else {
@@ -37,6 +47,12 @@
  * main thread, the actual adding of the screens are done via scheduling tasks.
  */
 function addScreensAsync() {
+  // Optimization to make the shrink animation smooth.
+  if (aboutToShrink) {
+    aboutToShrink = false;
+    setTimeout(addScreensAsync, animationTransitionTime);
+    return;
+  }
   if (commonScreensList.length > 0) {
     const nextScreens = commonScreensList.pop();
     addScreensToMainContainer([nextScreens]);
diff --git a/chrome/browser/resources/chromeos/login/screens/oobe/auto_enrollment_check.html b/chrome/browser/resources/chromeos/login/screens/oobe/auto_enrollment_check.html
index fbf9dba..0dcbfb58 100644
--- a/chrome/browser/resources/chromeos/login/screens/oobe/auto_enrollment_check.html
+++ b/chrome/browser/resources/chromeos/login/screens/oobe/auto_enrollment_check.html
@@ -3,6 +3,6 @@
 Use of this source code is governed by a BSD-style license that can be
 found in the LICENSE file.
 -->
-<oobe-loading-dialog title-key="autoEnrollmentCheckMessage">
+<oobe-loading-dialog title-key="[[getLoadingTitle_()]]">
   <iron-icon slot="icon" icon="oobe-32:googleg"></iron-icon>
 </oobe-loading-dialog>
diff --git a/chrome/browser/resources/chromeos/login/screens/oobe/auto_enrollment_check.js b/chrome/browser/resources/chromeos/login/screens/oobe/auto_enrollment_check.js
index cccd2717..b174f1b 100644
--- a/chrome/browser/resources/chromeos/login/screens/oobe/auto_enrollment_check.js
+++ b/chrome/browser/resources/chromeos/login/screens/oobe/auto_enrollment_check.js
@@ -10,6 +10,7 @@
 import '../../components/dialogs/oobe_loading_dialog.js';
 
 import {afterNextRender, dom, flush, html, mixinBehaviors, Polymer, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 
 import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js';
 import {OobeDialogHostBehavior} from '../../components/behaviors/oobe_dialog_host_behavior.js';
@@ -26,6 +27,9 @@
     [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior],
     PolymerElement);
 
+/**
+ * @polymer
+ */
 class AutoEnrollmentCheckElement extends AutoEnrollmentCheckElementBase {
   static get is() {
     return 'auto-enrollment-check-element';
@@ -35,10 +39,31 @@
     return html`{__html_template__}`;
   }
 
+  static get properties() {
+    return {
+      /**
+       * Whether to show get device ready title.
+       */
+      isOobeSoftwareUpdateEnabled_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('isOobeSoftwareUpdateEnabled');
+        },
+      },
+    };
+  }
+
   ready() {
     super.ready();
     this.initializeLoginScreen('AutoEnrollmentCheckScreen');
   }
+
+  getLoadingTitle_() {
+    if (this.isOobeSoftwareUpdateEnabled_) {
+      return 'gettingDeviceReadyTitle';
+    }
+    return 'autoEnrollmentCheckMessage';
+  }
 }
 
 customElements.define(
diff --git a/chrome/browser/resources/chromeos/login/screens/oobe/quick_start.js b/chrome/browser/resources/chromeos/login/screens/oobe/quick_start.js
index 1780461a3..d68b3cb 100644
--- a/chrome/browser/resources/chromeos/login/screens/oobe/quick_start.js
+++ b/chrome/browser/resources/chromeos/login/screens/oobe/quick_start.js
@@ -80,6 +80,10 @@
         type: String,
         value: '',
       },
+      discoverableName_: {
+        type: String,
+        value: '',
+      },
     };
   }
 
@@ -90,11 +94,16 @@
     this.canvasSize_ = 0;
     this.password_ = '';
     this.ssid_ = '';
+    this.discoverableName_ = '';
   }
 
   get EXTERNAL_API() {
     return [
-      'setFigures', 'setQRCode', 'showConnectingToWifi', 'showConnectedToWifi',
+      'setFigures',
+      'setQRCode',
+      'showConnectingToWifi',
+      'showConnectedToWifi',
+      'setDiscoverableName',
     ];
   }
 
@@ -158,6 +167,10 @@
     }
   }
 
+  setDiscoverableName(discoverableName) {
+    this.discoverableName_ = discoverableName;
+  }
+
   getCanvasContext_() {
     return this.shadowRoot.querySelector('#qrCodeCanvas').getContext('2d');
   }
diff --git a/chrome/browser/resources/chromeos/login/screens/oobe/update.html b/chrome/browser/resources/chromeos/login/screens/oobe/update.html
index 3f5cdc5..83f66890 100644
--- a/chrome/browser/resources/chromeos/login/screens/oobe/update.html
+++ b/chrome/browser/resources/chromeos/login/screens/oobe/update.html
@@ -67,6 +67,10 @@
     </oobe-cr-lottie>
   </div>
 </oobe-adaptive-dialog>
+<oobe-loading-dialog for-step="checking-software"
+    title-key="gettingDeviceReadyTitle">
+  <iron-icon slot="icon" icon="oobe-32:googleg"></iron-icon>
+</oobe-loading-dialog>
 <oobe-adaptive-dialog footer-shrinkable id="update-in-progress-dialog"
     for-step="update" aria-live="polite">
   <iron-icon slot="icon" icon="oobe-32:googleg"></iron-icon>
diff --git a/chrome/browser/resources/chromeos/login/screens/oobe/update.js b/chrome/browser/resources/chromeos/login/screens/oobe/update.js
index 37dc07c4..f570895 100644
--- a/chrome/browser/resources/chromeos/login/screens/oobe/update.js
+++ b/chrome/browser/resources/chromeos/login/screens/oobe/update.js
@@ -20,6 +20,7 @@
 import '../../components/oobe_slide.js';
 
 import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 
 import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js';
 import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.js';
@@ -60,6 +61,7 @@
  */
 const UpdateUIState = {
   CHECKING: 'checking',
+  CHECKING_SOFTWARE: 'checking-software',
   UPDATE: 'update',
   RESTART: 'restart',
   REBOOT: 'reboot',
@@ -177,6 +179,17 @@
         type: Boolean,
         value: false,
       },
+
+      /**
+       * Whether to show the loading UI different for
+       * checking update stage
+       */
+      isOobeSoftwareUpdateEnabled_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('isOobeSoftwareUpdateEnabled');
+        },
+      },
     };
   }
 
@@ -185,7 +198,11 @@
   }
 
   defaultUIStep() {
-    return UpdateUIState.CHECKING;
+    if (this.isOobeSoftwareUpdateEnabled_) {
+      return UpdateUIState.CHECKING_SOFTWARE;
+    } else {
+      return UpdateUIState.CHECKING;
+    }
   }
 
   get UI_STEPS() {
@@ -257,7 +274,11 @@
    * @param {UpdateUIState} value Current update state.
    */
   setUpdateState(value) {
-    this.setUIStep(value);
+    if (value === 'checking' && this.isOobeSoftwareUpdateEnabled_) {
+      this.setUIStep(UpdateUIState.CHECKING_SOFTWARE);
+    } else {
+      this.setUIStep(value);
+    }
   }
 
   /**
diff --git a/chrome/browser/resources/extensions/manager.html b/chrome/browser/resources/extensions/manager.html
index ee189122..c243b4fd 100644
--- a/chrome/browser/resources/extensions/manager.html
+++ b/chrome/browser/resources/extensions/manager.html
@@ -26,7 +26,7 @@
     can-load-unpacked="[[canLoadUnpacked]]"
     is-child-account="[[isChildAccount_]]"
     dev-mode-controlled-by-policy="[[devModeControlledByPolicy]]"
-    delegate="[[delegate]]" on-cr-toolbar-menu-tap="onMenuButtonClick_"
+    delegate="[[delegate]]" on-cr-toolbar-menu-click="onMenuButtonClick_"
     on-search-changed="onFilterChanged_"
     extensions="[[extensions_]]"
 <if expr="chromeos_ash">
diff --git a/chrome/browser/resources/history/app.ts b/chrome/browser/resources/history/app.ts
index 40a73cb..945c55e1 100644
--- a/chrome/browser/resources/history/app.ts
+++ b/chrome/browser/resources/history/app.ts
@@ -285,7 +285,7 @@
   override ready() {
     super.ready();
 
-    this.addEventListener('cr-toolbar-menu-tap', this.onCrToolbarMenuClick_);
+    this.addEventListener('cr-toolbar-menu-click', this.onCrToolbarMenuClick_);
     this.addEventListener('delete-selected', this.deleteSelected);
     this.addEventListener('history-checkbox-select', this.checkboxSelected);
     this.addEventListener('history-close-drawer', this.closeDrawer_);
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.ts b/chrome/browser/resources/nearby_share/nearby_discovery_page.ts
index 6754780..b4aad096 100644
--- a/chrome/browser/resources/nearby_share/nearby_discovery_page.ts
+++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.ts
@@ -20,6 +20,7 @@
 import {ConfirmationManagerInterface, DiscoveryObserverReceiver, PayloadPreview, SelectShareTargetResult, ShareTarget, ShareTargetListenerCallbackRouter, StartDiscoveryResult, TransferUpdateListenerPendingReceiver} from '/shared/nearby_share.mojom-webui.js';
 import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
 import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {UnguessableToken} from 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-webui.js';
 import {ArraySelector, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
@@ -112,6 +113,26 @@
       },
 
       /**
+       * A list of all discovered nearby self-share targets.
+       * Used only if isSelfShareEnabled is true, otherwise only |shareTargets_|
+       * is used.
+       */
+      selfShareTargets_: {
+        type: Array,
+        value: () => [],
+      },
+
+      /**
+       * A list of all discovered nearby non-self-share targets.
+       * Used only if isSelfShareEnabled is true, otherwise only |shareTargets_|
+       * is used.
+       */
+      nonSelfShareTargets_: {
+        type: Array,
+        value: () => [],
+      },
+
+      /**
        * Header text for error. The error section is not displayed if this is
        * falsey.
        */
@@ -135,6 +156,17 @@
         type: Boolean,
         value: false,
       },
+      /**
+       * Return true if the Nearby Share Self Share feature flag is enabled.
+       */
+      isSelfShareEnabled: {
+        type: Boolean,
+        readOnly: true,
+        value() {
+          return loadTimeData.valueExists('isSelfShareEnabled') &&
+              loadTimeData.getBoolean('isSelfShareEnabled');
+        },
+      },
     };
   }
 
@@ -142,8 +174,11 @@
   confirmationManager: ConfirmationManagerInterface|null;
   transferUpdateListener: TransferUpdateListenerPendingReceiver|null;
   selectedShareTarget: ShareTarget|null;
+  isSelfShareEnabled: boolean;
 
   private shareTargets_: ShareTarget[];
+  private selfShareTargets_: ShareTarget[];
+  private nonSelfShareTargets_: ShareTarget[];
   private errorTitle_: string|null;
   private errorDescription_: string|null;
   private isDarkModeActive_: boolean;
@@ -285,6 +320,8 @@
       this.shareTargetMap_.clear();
     }
     this.shareTargets_ = [];
+    this.selfShareTargets_ = [];
+    this.nonSelfShareTargets_ = [];
   }
 
   /**
@@ -369,7 +406,18 @@
     const shareTargetId = tokenToString(shareTarget.id);
     assert(this.shareTargetMap_);
     if (!this.shareTargetMap_.has(shareTargetId)) {
-      this.push('shareTargets_', shareTarget);
+      if (this.isSelfShareEnabled) {
+        if (shareTarget.forSelfShare) {
+          this.push('selfShareTargets_', shareTarget);
+        } else {
+          this.push('nonSelfShareTargets_', shareTarget);
+        }
+        this.shareTargets_ =
+            this.selfShareTargets_.concat(this.nonSelfShareTargets_);
+      } else {
+        this.push('shareTargets_', shareTarget);
+      }
+
     } else {
       const index = this.shareTargets_.findIndex(
           (target) => tokensEqual(target.id, shareTarget.id));
@@ -381,10 +429,28 @@
   }
 
   private onShareTargetLost_(shareTarget: ShareTarget) {
-    const index = this.shareTargets_.findIndex(
+    // Remove target from `shareTargets_`.
+    const shareTargetsIdx = this.shareTargets_.findIndex(
         (target) => tokensEqual(target.id, shareTarget.id));
-    assert(index !== -1);
-    this.splice('shareTargets_', index, 1);
+    assert(shareTargetsIdx !== -1);
+    this.splice('shareTargets_', shareTargetsIdx, 1);
+
+    if (this.isSelfShareEnabled) {
+      if (shareTarget.forSelfShare) {
+        // Remove target from `selfShareTargets_`.
+        const index = this.selfShareTargets_.findIndex(
+            (target) => tokensEqual(target.id, shareTarget.id));
+        assert(index !== -1);
+        this.splice('selfShareTargets_', index, 1);
+      } else {
+        // Remove target from `nonSelfShareTargets_`.
+        const index = this.nonSelfShareTargets_.findIndex(
+            (target) => tokensEqual(target.id, shareTarget.id));
+        assert(index !== -1);
+        this.splice('nonSelfShareTargets_', index, 1);
+      }
+    }
+
     assert(this.shareTargetMap_);
     this.shareTargetMap_.delete(tokenToString(shareTarget.id));
     this.updateSelectedShareTarget_(shareTarget.id, /*shareTarget=*/ null);
diff --git a/chrome/browser/resources/new_tab_page/app.html b/chrome/browser/resources/new_tab_page/app.html
index 93ae4f9..cec47620 100644
--- a/chrome/browser/resources/new_tab_page/app.html
+++ b/chrome/browser/resources/new_tab_page/app.html
@@ -59,6 +59,11 @@
     width: 100%;
   }
 
+  #oneGoogleBarScrim[fixed] {
+    /* Prevent scrim from bouncing when overscrolling. */
+    position: fixed;
+  }
+
   #oneGoogleBar {
     height: 100%;
     position: absolute;
@@ -334,7 +339,8 @@
         --ntp-logo-color: [[rgbaOrInherit_(logoColor_)]];">
   <template is="dom-if" if="[[lazyRender_]]">
     <template is="dom-if" if="[[oneGoogleBarEnabled_]]">
-      <div id="oneGoogleBarScrim" hidden$="[[!showOneGoogleBarScrim_]]"></div>
+      <div id="oneGoogleBarScrim" hidden$="[[!showOneGoogleBarScrim_]]"
+          fixed$="[[scrolledToTop_]]"></div>
       <ntp-iframe id="oneGoogleBar" src="[[oneGoogleBarIframePath_]]"
           hidden$="[[!oneGoogleBarLoaded_]]"
           allow="camera [[oneGoogleBarIframeOrigin_]]; display-capture [[oneGoogleBarIframeOrigin_]]"> <!-- presubmit: ignore-long-line -->
diff --git a/chrome/browser/resources/new_tab_page/app.ts b/chrome/browser/resources/new_tab_page/app.ts
index cabeb33..e0f11261 100644
--- a/chrome/browser/resources/new_tab_page/app.ts
+++ b/chrome/browser/resources/new_tab_page/app.ts
@@ -314,6 +314,11 @@
        * to show up immediately on load.
        */
       lazyRender_: Boolean,
+
+      scrolledToTop_: {
+        type: Boolean,
+        value: document.documentElement.scrollTop <= 0,
+      },
     };
   }
 
@@ -354,6 +359,7 @@
   private promoAndModulesLoaded_: boolean;
   private removeScrim_: boolean;
   private lazyRender_: boolean;
+  private scrolledToTop_: boolean;
 
   private callbackRouter_: PageCallbackRouter;
   private pageHandler_: PageHandlerRemote;
@@ -436,6 +442,9 @@
     this.eventTracker_.add(window, 'keydown', this.onWindowKeydown_.bind(this));
     this.eventTracker_.add(
         window, 'click', this.onWindowClick_.bind(this), /*capture=*/ true);
+    this.eventTracker_.add(document, 'scroll', () => {
+      this.scrolledToTop_ = document.documentElement.scrollTop <= 0;
+    });
     if (this.shouldPrintPerformance_) {
       // It is possible that the background image has already loaded by now.
       // If it has, we request it to re-send the load time so that we can
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/suggest_tile.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/suggest_tile.html
index c2b3244..2a6420f 100644
--- a/chrome/browser/resources/new_tab_page/modules/history_clusters/suggest_tile.html
+++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/suggest_tile.html
@@ -13,6 +13,15 @@
     text-decoration: none;
   }
 
+  a:hover {
+    background: var(--color-sys-state-hover-dim-blend-protection);
+  }
+
+  a:active,
+  :host-context(.focus-outline-visible) a:focus {
+    background-color: var(--color-new-tab-page-active-background);
+  }
+
   :host-context(.focus-outline-visible) :focus,
   :focus-visible {
     box-shadow: var(--ntp-focus-shadow);
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html
index 74f9f5a0..8299fe1 100644
--- a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html
+++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html
@@ -1,7 +1,5 @@
 <style include="history-clusters-shared-style">
   :host {
-    background:
-        var(--color-new-tab-page-history-clusters-module-item-background);
     border-radius: var(--ntp-module-item-border-radius);
     color: var(--color-new-tab-page-primary-foreground);
     display: inline-block;
@@ -23,11 +21,22 @@
   }
 
   #content {
+    background:
+        var(--color-new-tab-page-history-clusters-module-item-background);
     display: inline-block;
     height: 100%;
     width: 100%;
   }
 
+  #content:hover {
+    background: var(--color-sys-state-hover-dim-blend-protection);
+  }
+
+  #content:active,
+  :host-context(.focus-outline-visible) #content:focus {
+    background-color: var(--color-new-tab-page-active-background);
+  }
+
   :host([medium-format]) #content {
     display: flex;
     flex-direction: row;
diff --git a/chrome/browser/resources/password_manager/password_manager_app.ts b/chrome/browser/resources/password_manager/password_manager_app.ts
index 83d4a6a..c84bbe9 100644
--- a/chrome/browser/resources/password_manager/password_manager_app.ts
+++ b/chrome/browser/resources/password_manager/password_manager_app.ts
@@ -145,7 +145,7 @@
       this.$.drawerTemplate.if = true;
     });
 
-    this.addEventListener('cr-toolbar-menu-tap', this.onMenuButtonTap_);
+    this.addEventListener('cr-toolbar-menu-click', this.onMenuButtonClick_);
   }
 
   override currentRouteChanged(route: Route): void {
@@ -180,7 +180,7 @@
     }
   }
 
-  private onMenuButtonTap_() {
+  private onMenuButtonClick_() {
     this.$.drawer.toggle();
   }
 
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn
index 9db8ff98..005556ee 100644
--- a/chrome/browser/resources/settings/BUILD.gn
+++ b/chrome/browser/resources/settings/BUILD.gn
@@ -114,7 +114,9 @@
     "performance_page/battery_page.ts",
     "performance_page/performance_page.ts",
     "performance_page/tab_discard_exception_add_dialog.ts",
+    "performance_page/tab_discard_exception_add_input.ts",
     "performance_page/tab_discard_exception_edit_dialog.ts",
+    "performance_page/tab_discard_exception_edit_input.ts",
     "performance_page/tab_discard_exception_entry.ts",
     "performance_page/tab_discard_exception_list.ts",
     "people_page/people_page.ts",
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.html b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.html
index 37f69c3..e25fecd 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.html
+++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.html
@@ -107,13 +107,13 @@
   </iron-collapse>
 </template>
 <cr-link-row id="keyboardShortcutViewer" class="hr"
-    on-click="onShowKeyboardShortcutViewerTap"
+    on-click="onShowKeyboardShortcutViewerClick"
     label="$i18n{viewAndCustomizeKeyboardShortcut}"
     external
     deep-link-focus-id$="[[Setting.kKeyboardShortcuts]]">
 </cr-link-row>
 <cr-link-row id="showLanguagesInput"
-    class="hr" on-click="onShowInputSettingsTap"
+    class="hr" on-click="onShowInputSettingsClick"
     label="$i18n{keyboardShowInputSettings}"
     role-description="$i18n{subpageArrowRoleDescription}">
 </cr-link-row>
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.ts b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.ts
index d1196cb..4d5421f0 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.ts
+++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.ts
@@ -131,11 +131,11 @@
     this.attemptDeepLink();
   }
 
-  private onShowKeyboardShortcutViewerTap(): void {
+  private onShowKeyboardShortcutViewerClick(): void {
     this.browserProxy.showKeyboardShortcutViewer();
   }
 
-  private onShowInputSettingsTap(): void {
+  private onShowInputSettingsClick(): void {
     Router.getInstance().navigateTo(
         routes.OS_LANGUAGES_INPUT,
         /*dynamicParams=*/ undefined, /*removeSearch=*/ true);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.html b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.html
index 10d81b1..39454fe 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.html
+++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.html
@@ -35,7 +35,7 @@
     </settings-toggle-button>
   </template>
   <cr-link-row id="remapKeyboardKeys"
-      class="hr bottom-divider" on-click="onRemapKeyboardKeysTap"
+      class="hr bottom-divider" on-click="onRemapKeyboardKeysClick"
       aria-describedby="keyboardName"
       label="$i18n{remapKeyboardKeysRowLabel}"
       sub-label$="[[remapKeyboardKeysSublabel]]"
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.ts b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.ts
index ce89283..9d1a757 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.ts
+++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.ts
@@ -213,7 +213,7 @@
             'remapKeyboardKeysRowSubLabel', numRemappedModifierKeys);
   }
 
-  private onRemapKeyboardKeysTap(): void {
+  private onRemapKeyboardKeysClick(): void {
     const url = new URLSearchParams(
         'keyboardId=' + encodeURIComponent(this.keyboard.id));
 
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_subpage.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_subpage.html
index 4cc2f56..272045f 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_subpage.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_subpage.html
@@ -78,12 +78,12 @@
     <template is="dom-repeat" items="[[passpointSubscriptionsList_]]">
       <div class="list-item">
         <cr-link-row embedded label="[[getSubscriptionDisplayName_(item)]]"
-            on-click="onSubscriptionListItemTap_"
+            on-click="onSubscriptionListItemClick_"
             role-description="$i18n{subpageArrowRoleDescription}">
         </cr-link-row>
         <div class="separator"></div>
         <cr-icon-button class="icon-more-vert" tabindex$="[[tabindex]]"
-            on-click="onSubscriptionMenuButtonTap_"
+            on-click="onSubscriptionMenuButtonClick_"
             title="[[getSubscriptionMenuButtonTitle_(item)]]">
         </cr-icon-button>
       </div>
@@ -107,7 +107,7 @@
 </cr-action-menu>
 
 <cr-action-menu id="subscriptionDotsMenu" role-description="$i18n{menu}">
-  <button class="dropdown-item" on-click="onSubscriptionForgetTap_">
+  <button class="dropdown-item" on-click="onSubscriptionForgetClick_">
     $i18n{knownNetworksMenuForget}
   </button>
 </cr-action-menu>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_subpage.ts b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_subpage.ts
index feb4b22e..845f598 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_subpage.ts
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_subpage.ts
@@ -378,7 +378,7 @@
     event.stopPropagation();
   }
 
-  private onSubscriptionListItemTap_(
+  private onSubscriptionListItemClick_(
       event: DomRepeatEvent<PasspointSubscription>): void {
     const showPasspointEvent = new CustomEvent(
         'show-passpoint-detail',
@@ -394,7 +394,7 @@
     event.stopPropagation();
   }
 
-  private onSubscriptionMenuButtonTap_(
+  private onSubscriptionMenuButtonClick_(
       event: DomRepeatEvent<PasspointSubscription>): void {
     const button = event.target as HTMLButtonElement;
     this.selectedSubscriptionId_ = event.model.item.id;
@@ -409,7 +409,7 @@
         this.getSubscriptionDisplayName_(subscription));
   }
 
-  private async onSubscriptionForgetTap_(): Promise<void> {
+  private async onSubscriptionForgetClick_(): Promise<void> {
     this.$.subscriptionDotsMenu.close();
     this.selectedSubscriptionId_ = '';
     const response = await this.passpointService_.deletePasspointSubscription(
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/passpoint_subpage.html b/chrome/browser/resources/settings/chromeos/internet_page/passpoint_subpage.html
index 69329106..38ff457 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/passpoint_subpage.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/passpoint_subpage.html
@@ -9,7 +9,7 @@
       localized-string="$i18n{passpointHeadlineText}"
       link-url="$i18nRaw{wifiPasspointLearnMoreUrl}">
   </localized-link>
-  <cr-button id="removeButton" on-click="onForgetTap_">
+  <cr-button id="removeButton" on-click="onForgetClick_">
     $i18n{passpointRemoveButton}
   </cr-button>
 </div>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/passpoint_subpage.ts b/chrome/browser/resources/settings/chromeos/internet_page/passpoint_subpage.ts
index 3614547..f8884e88 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/passpoint_subpage.ts
+++ b/chrome/browser/resources/settings/chromeos/internet_page/passpoint_subpage.ts
@@ -190,7 +190,7 @@
         this.shadowRoot!.querySelector<HTMLDialogElement>('#removalDialog'));
   }
 
-  private onForgetTap_(): void {
+  private onForgetClick_(): void {
     this.showForgetDialog_ = true;
   }
 
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.ts b/chrome/browser/resources/settings/chromeos/lazy_load.ts
index b2ca7da..bd9ecd3 100644
--- a/chrome/browser/resources/settings/chromeos/lazy_load.ts
+++ b/chrome/browser/resources/settings/chromeos/lazy_load.ts
@@ -36,6 +36,7 @@
 import './os_a11y_page/text_to_speech_subpage.js';
 import './os_a11y_page/tts_voice_subpage.js';
 import './os_about_page/detailed_build_info_subpage.js';
+import './os_apps_page/app_management_page/app_detail_view.js';
 import './os_search_page/google_assistant_subpage.js';
 import './os_search_page/search_subpage.js';
 import './os_people_page/account_manager_subpage.js';
@@ -138,6 +139,7 @@
 export {SwitchAccessCommand} from './os_a11y_page/switch_access_constants.js';
 export {PdfOcrUserSelection, SettingsTextToSpeechSubpageElement} from './os_a11y_page/text_to_speech_subpage.js';
 export {SettingsTtsVoiceSubpageElement} from './os_a11y_page/tts_voice_subpage.js';
+export {AppManagementAppDetailViewElement} from './os_apps_page/app_management_page/app_detail_view.js';
 export {SettingsGoogleDriveSubpageElement} from './os_files_page/google_drive_subpage.js';
 export {SettingsOfficePageElement} from './os_files_page/office_page.js';
 export {OsSettingsFilesPageElement} from './os_files_page/os_files_page.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.html
index e028128..8a4f6f9 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.html
@@ -30,6 +30,14 @@
     max-width: 450px;
     overflow-wrap: break-word;
   }
+
+  #stickyKeysDisabledTooltip,
+  #focusHighlightDisabledTooltip {
+    --paper-tooltip-background: var(--cros-tooltip-background-color);
+    --paper-tooltip-border-radius: 4px;
+    --paper-tooltip-text-color: var(--cros-tooltip-label-color);
+    --paper-tooltip-padding: 8px;
+  }
 </style>
 
 <settings-toggle-button
@@ -97,18 +105,38 @@
 <settings-toggle-button
     id="stickyKeysToggle"
     class="hr"
-    pref="{{prefs.settings.a11y.sticky_keys_enabled}}"
+    pref="[[stickyKeysEnabledVirtualPref_]]"
+    no-set-pref
+    on-settings-boolean-control-change="updateStickyKeysEnabledVirtualPref_"
     label="$i18n{stickyKeysLabel}"
     sub-label="$i18n{stickyKeysDescription}"
+    disabled="[[prefs.settings.accessibility.value]]"
     deep-link-focus-id$="[[Setting.kStickyKeys]]">
+  <cr-tooltip-icon
+      id="stickyKeysDisabledTooltip"
+      hidden$="[[!prefs.settings.accessibility.value]]"
+      tooltip-text="$i18n{stickyKeysDisabledByChromevoxTooltip}"
+      icon-class="cr:info-outline"
+      slot="more-actions">
+  </cr-tooltip-icon>
 </settings-toggle-button>
 <settings-toggle-button
     id="focusHighlightToggle"
     class="hr"
-    pref="{{prefs.settings.a11y.focus_highlight}}"
+    pref="[[focusHighlightEnabledVirtualPref_]]"
+    no-set-pref
+    on-settings-boolean-control-change="updateFocusHighlightEnabledVirtualPref_"
     label="$i18n{focusHighlightLabel}"
     sub-label="$i18n{focusHighlightLabelSubtext}"
+    disabled="[[prefs.settings.accessibility.value]]"
     deep-link-focus-id$="[[Setting.kHighlightKeyboardFocus]]">
+  <cr-tooltip-icon
+      id="focusHighlightDisabledTooltip"
+      hidden$="[[!prefs.settings.accessibility.value]]"
+      tooltip-text="$i18n{focusHighlightDisabledByChromevoxTooltip}"
+      icon-class="cr:info-outline"
+      slot="more-actions">
+  </cr-tooltip-icon>
 </settings-toggle-button>
 <settings-toggle-button
     id="caretHighlightToggle"
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.ts
index 38c8375..1f1ab3c 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.ts
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.ts
@@ -13,6 +13,7 @@
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.html.js';
 import 'chrome://resources/cr_elements/cr_shared_vars.css.js';
+import 'chrome://resources/cr_elements/policy/cr_tooltip_icon.js';
 import '/shared/settings/controls/settings_slider.js';
 import '/shared/settings/controls/settings_toggle_button.js';
 import '../settings_shared.css.js';
@@ -115,6 +116,20 @@
           Setting.kEnableSwitchAccess,
         ]),
       },
+
+      focusHighlightEnabledVirtualPref_: {
+        type: Object,
+        computed: 'computeEnabledWithConflictingFeature_(' +
+            'prefs.settings.a11y.focus_highlight.value, ' +
+            'prefs.settings.accessibility.value)',
+      },
+
+      stickyKeysEnabledVirtualPref_: {
+        type: Object,
+        computed: 'computeEnabledWithConflictingFeature_(' +
+            'prefs.settings.a11y.sticky_keys_enabled.value, ' +
+            'prefs.settings.accessibility.value)',
+      },
     };
   }
 
@@ -124,9 +139,12 @@
   private dictationLocaleSubtitleOverride_: string;
   private dictationLocalesList_: LocaleInfo[];
   private isKioskModeActive_: boolean;
+  private focusHighlightEnabledPref_:
+      chrome.settingsPrivate.PrefObject<boolean>;
   private keyboardAndTextInputBrowserProxy_:
       KeyboardAndTextInputPageBrowserProxy;
   private route_: Route;
+  private stickyKeysEnabledPref_: chrome.settingsPrivate.PrefObject<boolean>;
   private showDictationLocaleMenu_: boolean;
   private useDictationLocaleSubtitleOverride_: boolean;
 
@@ -273,6 +291,44 @@
   private onChangeDictationLocalesDialogClosed_(): void {
     this.showDictationLocaleMenu_ = false;
   }
+
+  private computeEnabledWithConflictingFeature_(
+      prefValue: boolean, conflictingPrefValue: boolean):
+      chrome.settingsPrivate.PrefObject<boolean> {
+    return {
+      value: !conflictingPrefValue && prefValue,
+      type: chrome.settingsPrivate.PrefType.BOOLEAN,
+      key: '',
+    };
+  }
+
+  private updateFocusHighlightEnabledVirtualPref_(): void {
+    // Focus highlight is automatically disabled when ChromeVox is
+    // enabled, although the underlying pref is unchanged (allows
+    // for state restore if ChromeVox is later disabled).)
+    // Reflect the fact focus highlight isn't running by showing
+    // the toggle as off.
+    if (this.getPref<boolean>('settings.accessibility').value) {
+      return;
+    }
+    this.setPrefValue(
+        'settings.a11y.focus_highlight',
+        !this.getPref<boolean>('settings.a11y.focus_highlight').value);
+  }
+
+  private updateStickyKeysEnabledVirtualPref_(): void {
+    // Sticky keys is automatically disabled when ChromeVox is
+    // enabled, although the underlying pref is unchanged (allows
+    // for state restore if ChromeVox is later disabled).)
+    // Reflect the fact sticky keys isn't running by showing
+    // the toggle as off.
+    if (this.getPref<boolean>('settings.accessibility').value) {
+      return;
+    }
+    this.setPrefValue(
+        'settings.a11y.sticky_keys_enabled',
+        !this.getPref<boolean>('settings.a11y.sticky_keys_enabled').value);
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.ts b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.ts
index c91ba79..7bd9902 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.ts
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.ts
@@ -30,7 +30,7 @@
 const AppManagementAppDetailViewElementBase =
     AppManagementStoreMixin(RouteObserverMixin(PolymerElement));
 
-class AppManagementAppDetailViewElement extends
+export class AppManagementAppDetailViewElement extends
     AppManagementAppDetailViewElementBase {
   static get is() {
     return 'app-management-app-detail-view';
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.ts b/chrome/browser/resources/settings/chromeos/os_settings.ts
index 8538148..e729891 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.ts
+++ b/chrome/browser/resources/settings/chromeos/os_settings.ts
@@ -47,7 +47,6 @@
 import './os_files_page/google_drive_subpage.js';
 import './os_apps_page/android_apps_subpage.js';
 import './os_apps_page/app_notifications_page/app_notifications_subpage.js';
-import './os_apps_page/app_management_page/app_detail_view.js';
 import './os_apps_page/app_management_page/app_details_item.js';
 import './os_apps_page/app_management_page/app_item.js';
 import './os_apps_page/app_management_page/app_management_page.js';
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_dialog.html b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_dialog.html
index 605193a..c342009 100644
--- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_dialog.html
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_dialog.html
@@ -1,12 +1,9 @@
 <cr-dialog id="dialog" close-text="$i18n{close}" show-on-attach>
   <div slot="title">$i18n{addSiteTitle}</div>
   <div slot="body">
-    <cr-input id="input" label="$i18n{addSite}"
-        placeholder="example.com" value="{{rule}}"
-        on-input="validate" error-message="[[errorMessage]]"
-        invalid="[[inputInvalid]]" spellcheck="false" autofocus
-        aria-label$="$i18n{addSiteTitle}">
-    </cr-input>
+    <tab-discard-exception-add-input id="input" prefs="{{prefs}}"
+        submit-disabled="{{submitDisabled}}">
+    </tab-discard-exception-add-input>
   </div>
   <div slot="button-container">
     <cr-button id="cancelButton" class="cancel-button"
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_dialog.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_dialog.ts
index 47e0b506..f821c8c 100644
--- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_dialog.ts
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_dialog.ts
@@ -4,33 +4,28 @@
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
-import 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import './tab_discard_exception_add_input.js';
 
 import {PrefsMixin, PrefsMixinInterface} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js';
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
-import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {PerformanceBrowserProxy, PerformanceBrowserProxyImpl} from './performance_browser_proxy.js';
-import {HighEfficiencyModeExceptionListAction, PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_metrics_proxy.js';
 import {getTemplate} from './tab_discard_exception_add_dialog.html.js';
-import {TAB_DISCARD_EXCEPTIONS_PREF, TabDiscardExceptionValidationMixin, TabDiscardExceptionValidationMixinInterface} from './tab_discard_exception_validation_mixin.js';
+import {TabDiscardExceptionAddInputElement} from './tab_discard_exception_add_input.js';
 
 export interface TabDiscardExceptionAddDialogElement {
   $: {
     actionButton: CrButtonElement,
     cancelButton: CrButtonElement,
     dialog: CrDialogElement,
-    input: CrInputElement,
+    input: TabDiscardExceptionAddInputElement,
   };
 }
 
 type Constructor<T> = new (...args: any[]) => T;
-const TabDiscardExceptionAddDialogElementBase =
-    TabDiscardExceptionValidationMixin(PrefsMixin(PolymerElement)) as
-    Constructor<TabDiscardExceptionValidationMixinInterface&PrefsMixinInterface&
-                PolymerElement>;
+const TabDiscardExceptionAddDialogElementBase = PrefsMixin(PolymerElement) as
+    Constructor<PrefsMixinInterface&PolymerElement>;
 
 export class TabDiscardExceptionAddDialogElement extends
     TabDiscardExceptionAddDialogElementBase {
@@ -42,28 +37,13 @@
     return getTemplate();
   }
 
-  private browserProxy_: PerformanceBrowserProxy =
-      PerformanceBrowserProxyImpl.getInstance();
-  private metricsProxy_: PerformanceMetricsProxy =
-      PerformanceMetricsProxyImpl.getInstance();
-
   private onCancelClick_() {
     this.$.dialog.cancel();
   }
 
-  private async onSubmitClick_() {
+  private onSubmitClick_() {
     this.$.dialog.close();
-    const rule = this.rule.trim();
-    if (!await this.browserProxy_.validateTabDiscardExceptionRule(rule)) {
-      return;
-    }
-    this.appendPrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, rule);
-    this.dispatchEvent(new CustomEvent('add-exception', {
-      bubbles: true,
-      composed: true,
-    }));
-    this.metricsProxy_.recordExceptionListAction(
-        HighEfficiencyModeExceptionListAction.ADD);
+    this.$.input.submit();
   }
 }
 
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.html b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.html
new file mode 100644
index 0000000..6a45ab12
--- /dev/null
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.html
@@ -0,0 +1,5 @@
+<cr-input id="input" label="$i18n{addSite}" aria-label$="$i18n{addSiteTitle}"
+    placeholder="example.com" value="{{rule}}" on-input="validate"
+    error-message="[[errorMessage]]" invalid="[[inputInvalid]]"
+    spellcheck="false" autofocus>
+</cr-input>
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.ts
new file mode 100644
index 0000000..5012037
--- /dev/null
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.ts
@@ -0,0 +1,65 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js';
+
+import {PrefsMixin, PrefsMixinInterface} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js';
+import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import {ListPropertyUpdateMixin, ListPropertyUpdateMixinInterface} from 'chrome://resources/cr_elements/list_property_update_mixin.js';
+import {assert} from 'chrome://resources/js/assert_ts.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {HighEfficiencyModeExceptionListAction, PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_metrics_proxy.js';
+import {getTemplate} from './tab_discard_exception_add_input.html.js';
+import {TAB_DISCARD_EXCEPTIONS_PREF, TabDiscardExceptionValidationMixin, TabDiscardExceptionValidationMixinInterface} from './tab_discard_exception_validation_mixin.js';
+
+export interface TabDiscardExceptionAddInputElement {
+  $: {
+    input: CrInputElement,
+  };
+}
+
+type Constructor<T> = new (...args: any[]) => T;
+const TabDiscardExceptionAddInputElementBase =
+    TabDiscardExceptionValidationMixin(
+        ListPropertyUpdateMixin(PrefsMixin(PolymerElement))) as
+    Constructor<TabDiscardExceptionValidationMixinInterface&
+                ListPropertyUpdateMixinInterface&PrefsMixinInterface&
+                PolymerElement>;
+
+export class TabDiscardExceptionAddInputElement extends
+    TabDiscardExceptionAddInputElementBase {
+  static get is() {
+    return 'tab-discard-exception-add-input';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  private metricsProxy_: PerformanceMetricsProxy =
+      PerformanceMetricsProxyImpl.getInstance();
+
+  submit() {
+    assert(!this.submitDisabled);
+    const rule = this.rule.trim();
+    this.appendPrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, rule);
+    this.dispatchEvent(new CustomEvent('add-exception', {
+      bubbles: true,
+      composed: true,
+    }));
+    this.metricsProxy_.recordExceptionListAction(
+        HighEfficiencyModeExceptionListAction.ADD);
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'tab-discard-exception-add-input': TabDiscardExceptionAddInputElement;
+  }
+}
+
+customElements.define(
+    TabDiscardExceptionAddInputElement.is, TabDiscardExceptionAddInputElement);
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_dialog.html b/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_dialog.html
index 405e86b..5d2902a 100644
--- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_dialog.html
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_dialog.html
@@ -1,12 +1,10 @@
 <cr-dialog id="dialog" close-text="$i18n{close}" show-on-attach>
   <div slot="title">$i18n{editSiteTitle}</div>
   <div slot="body">
-    <cr-input id="input" label="$i18n{addSite}"
-        placeholder="example.com" value="{{rule}}"
-        on-input="validate" error-message="[[errorMessage]]"
-        invalid="[[inputInvalid]]" spellcheck="false" autofocus
-        aria-label$="$i18n{editSiteTitle}">
-    </cr-input>
+    <tab-discard-exception-edit-input id="input" prefs="{{prefs}}"
+        rule-to-edit="[[ruleToEdit]]"
+        submit-disabled="{{submitDisabled}}">
+    </tab-discard-exception-edit-input>
   </div>
   <div slot="button-container">
     <cr-button id="cancelButton" class="cancel-button"
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_dialog.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_dialog.ts
index 7fa2012c..68c1f83 100644
--- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_dialog.ts
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_dialog.ts
@@ -4,33 +4,28 @@
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
-import 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import './tab_discard_exception_edit_input.js';
 
 import {PrefsMixin, PrefsMixinInterface} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js';
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
-import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {PerformanceBrowserProxy, PerformanceBrowserProxyImpl} from './performance_browser_proxy.js';
-import {HighEfficiencyModeExceptionListAction, PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_metrics_proxy.js';
 import {getTemplate} from './tab_discard_exception_edit_dialog.html.js';
-import {TAB_DISCARD_EXCEPTIONS_PREF, TabDiscardExceptionValidationMixin, TabDiscardExceptionValidationMixinInterface} from './tab_discard_exception_validation_mixin.js';
+import {TabDiscardExceptionEditInputElement} from './tab_discard_exception_edit_input.js';
 
 export interface TabDiscardExceptionEditDialogElement {
   $: {
     actionButton: CrButtonElement,
     cancelButton: CrButtonElement,
     dialog: CrDialogElement,
-    input: CrInputElement,
+    input: TabDiscardExceptionEditInputElement,
   };
 }
 
 type Constructor<T> = new (...args: any[]) => T;
-const TabDiscardExceptionEditDialogElementBase =
-    TabDiscardExceptionValidationMixin(PrefsMixin(PolymerElement)) as
-    Constructor<TabDiscardExceptionValidationMixinInterface&PrefsMixinInterface&
-                PolymerElement>;
+const TabDiscardExceptionEditDialogElementBase = PrefsMixin(PolymerElement) as
+    Constructor<PrefsMixinInterface&PolymerElement>;
 
 export class TabDiscardExceptionEditDialogElement extends
     TabDiscardExceptionEditDialogElementBase {
@@ -48,43 +43,20 @@
     };
   }
 
-  private browserProxy_: PerformanceBrowserProxy =
-      PerformanceBrowserProxyImpl.getInstance();
-  private metricsProxy_: PerformanceMetricsProxy =
-      PerformanceMetricsProxyImpl.getInstance();
   private ruleToEdit: string;
 
-  override ready() {
-    super.ready();
-    this.rule = this.ruleToEdit;
-    this.submitDisabled = false;
-  }
-
   private onCancelClick_() {
     this.$.dialog.cancel();
   }
 
-  private async onSubmitClick_() {
+  private onSubmitClick_() {
     this.$.dialog.close();
-    const rule = this.rule.trim();
-    if (rule !== this.ruleToEdit) {
-      if (!await this.browserProxy_.validateTabDiscardExceptionRule(rule)) {
-        return;
-      }
-      if (this.getPref(TAB_DISCARD_EXCEPTIONS_PREF).value.includes(rule)) {
-        // delete instead of update, otherwise there would be a duplicate
-        this.deletePrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, this.ruleToEdit);
-      } else {
-        this.updatePrefListItem(
-            TAB_DISCARD_EXCEPTIONS_PREF, this.ruleToEdit, rule);
-      }
-    }
-    this.metricsProxy_.recordExceptionListAction(
-        HighEfficiencyModeExceptionListAction.EDIT);
+    this.$.input.submit();
   }
 
   setRuleToEditForTesting(rule: string) {
     this.ruleToEdit = rule;
+    this.$.input.setRuleToEditForTesting();
   }
 }
 
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_input.html b/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_input.html
new file mode 100644
index 0000000..b0283c2
--- /dev/null
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_input.html
@@ -0,0 +1,5 @@
+<cr-input id="input" label="$i18n{addSite}" aria-label$="$i18n{editSiteTitle}"
+    placeholder="example.com" value="{{rule}}" on-input="validate"
+    error-message="[[errorMessage]]" invalid="[[inputInvalid]]"
+    spellcheck="false" autofocus>
+</cr-input>
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_input.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_input.ts
new file mode 100644
index 0000000..80834f1
--- /dev/null
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_edit_input.ts
@@ -0,0 +1,92 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js';
+
+import {PrefsMixin, PrefsMixinInterface} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js';
+import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import {ListPropertyUpdateMixin, ListPropertyUpdateMixinInterface} from 'chrome://resources/cr_elements/list_property_update_mixin.js';
+import {assert} from 'chrome://resources/js/assert_ts.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {HighEfficiencyModeExceptionListAction, PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_metrics_proxy.js';
+import {getTemplate} from './tab_discard_exception_edit_input.html.js';
+import {TAB_DISCARD_EXCEPTIONS_PREF, TabDiscardExceptionValidationMixin, TabDiscardExceptionValidationMixinInterface} from './tab_discard_exception_validation_mixin.js';
+
+export interface TabDiscardExceptionEditInputElement {
+  $: {
+    input: CrInputElement,
+  };
+}
+
+type Constructor<T> = new (...args: any[]) => T;
+const TabDiscardExceptionEditInputElementBase =
+    TabDiscardExceptionValidationMixin(
+        ListPropertyUpdateMixin(PrefsMixin(PolymerElement))) as
+    Constructor<TabDiscardExceptionValidationMixinInterface&
+                ListPropertyUpdateMixinInterface&PrefsMixinInterface&
+                PolymerElement>;
+
+export class TabDiscardExceptionEditInputElement extends
+    TabDiscardExceptionEditInputElementBase {
+  static get is() {
+    return 'tab-discard-exception-edit-input';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      /**
+       * Represents the original rule that is being edited. When submit() is
+       * called, it will be replaced by rule in the exception list.
+       */
+      ruleToEdit: {type: String, value: ''},
+    };
+  }
+
+  private metricsProxy_: PerformanceMetricsProxy =
+      PerformanceMetricsProxyImpl.getInstance();
+
+  private ruleToEdit: string;
+
+  override ready() {
+    super.ready();
+    this.rule = this.ruleToEdit;
+    this.submitDisabled = false;
+  }
+
+  submit() {
+    assert(!this.submitDisabled);
+    const rule = this.rule.trim();
+    if (rule !== this.ruleToEdit) {
+      if (this.getPref(TAB_DISCARD_EXCEPTIONS_PREF).value.includes(rule)) {
+        // delete instead of update, otherwise there would be a duplicate
+        this.deletePrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, this.ruleToEdit);
+      } else {
+        this.updatePrefListItem(
+            TAB_DISCARD_EXCEPTIONS_PREF, this.ruleToEdit, rule);
+      }
+    }
+    this.metricsProxy_.recordExceptionListAction(
+        HighEfficiencyModeExceptionListAction.EDIT);
+  }
+
+  setRuleToEditForTesting() {
+    this.rule = this.ruleToEdit;
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'tab-discard-exception-edit-input': TabDiscardExceptionEditInputElement;
+  }
+}
+
+customElements.define(
+    TabDiscardExceptionEditInputElement.is,
+    TabDiscardExceptionEditInputElement);
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_validation_mixin.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_validation_mixin.ts
index 6acf88f..e3a5bfe2 100644
--- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_validation_mixin.ts
+++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_validation_mixin.ts
@@ -27,7 +27,7 @@
             errorMessage: {type: String, value: ''},
             inputInvalid: {type: Boolean, value: false},
             rule: String,
-            submitDisabled: {type: Boolean, value: true},
+            submitDisabled: {type: Boolean, value: true, notify: true},
           };
         }
 
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chrome/browser/resources/settings/settings_ui/settings_ui.html
index c8dcbca..2da5aba6 100644
--- a/chrome/browser/resources/settings/settings_ui/settings_ui.html
+++ b/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -82,7 +82,7 @@
         clear-label="$i18n{clearSearch}"
         autofocus
         search-prompt="$i18n{searchPrompt}"
-        on-cr-toolbar-menu-tap="onMenuButtonClick_"
+        on-cr-toolbar-menu-click="onMenuButtonClick_"
         spinner-active="[[toolbarSpinnerActive_]]"
         menu-label="$i18n{menuButtonLabel}"
         on-search-changed="onSearchChanged_"
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts b/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts
index c19a3dd1..1ceb1f2 100644
--- a/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts
+++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts
@@ -170,7 +170,7 @@
     }
     event.preventDefault();
     event.stopPropagation();
-    if (this.hasCheckbox) {
+    if (this.hasCheckbox && !this.checkboxDisabled) {
       // Clicking the row should trigger a checkbox click rather than a
       // standard row click.
       const checkbox =
diff --git a/chrome/browser/resources/side_panel/reading_list/app.html b/chrome/browser/resources/side_panel/reading_list/app.html
index 6a6ce4a..ae93d7d 100644
--- a/chrome/browser/resources/side_panel/reading_list/app.html
+++ b/chrome/browser/resources/side_panel/reading_list/app.html
@@ -1,4 +1,10 @@
-<style include="mwb-shared-style mwb-element-shared-style cr-hidden-style">
+<style include="mwb-element-shared-style cr-hidden-style sp-shared-style">
+  #content {
+    display: flex;
+    flex-direction: column;
+    height: 100vh;
+  }
+
   #header {
     align-items: center;
     color: var(--cr-primary-text-color);
@@ -29,13 +35,12 @@
   }
 
   #readingListList {
-    margin-block-start: 8px;
     max-height: none;
     overflow: auto;
   }
 
-  #currentPageActionButton {
-    margin: 16px 16px 0 16px;
+  :host-context([chrome-refresh-2023]) #readingListList {
+    padding-block-start: var(--sp-body-padding);
   }
 
   :host-context(html:not([chrome-refresh-2023])) #currentPageActionButton {
@@ -49,12 +54,6 @@
     transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1);
   }
 
-  sp-empty-state:not([hidden]) ~ #currentPageActionButton {
-    display: flex;
-    margin: 0 auto 16px auto;
-    width: fit-content;
-  }
-
   .mwb-list-item:focus-within {
     background-color: var(--mwb-list-item-hover-background-color);
   }
@@ -87,25 +86,9 @@
       heading="$i18n{emptyStateHeader}"
       body="[[getEmptyStateSubheaderText_()]]">
   </sp-empty-state>
-  <cr-button id="currentPageActionButton" class="floating-button"
-      aria-label="[[getCurrentPageActionButtonText_(
-          currentPageActionButtonState_)]]"
-      on-click="onCurrentPageActionButtonClick_"
-      disabled="[[getCurrentPageActionButtonDisabled_(
-          currentPageActionButtonState_)]]">
-    <iron-icon id="currentPageActionButtonIcon" aria-hidden="true"
-        slot="prefix-icon"
-        icon="[[getCurrentPageActionButtonIcon_(
-            currentPageActionButtonState_)]]">
-    </iron-icon>
-    <div id="currentPageActionButtonText" aria-hidden="true">
-      [[getCurrentPageActionButtonText_(currentPageActionButtonState_)]]
-    </div>
-  </cr-button>
-  <div id="readingListList">
-    <iron-selector id="selector" on-keydown="onItemKeyDown_"
-        attr-for-selected="data-url" selectable="reading-list-item">
-      <sp-heading hidden="[[!unreadItems_.length]]" compact hide-back-button>
+  <div id="readingListList" class="sp-scroller" on-keydown="onItemKeyDown_">
+    <div class="sp-card" hidden="[[!unreadItems_.length]]">
+      <sp-heading compact hide-back-button>
         <h2 slot="heading">$i18n{unreadHeader}</h2>
       </sp-heading>
       <template id="unreadItemsList" is="dom-repeat" items="[[unreadItems_]]">
@@ -114,9 +97,12 @@
             data="[[item]]" button-ripples="[[buttonRipples]]">
         </reading-list-item>
       </template>
-      <div class="hr" hidden$="[[!shouldShowHr_(unreadItems_, readItems_)]]">
-      </div>
-      <sp-heading compact hidden="[[!readItems_.length]]" hide-back-button>
+    </div>
+    <div class="hr sp-cards-separator"
+        hidden$="[[!shouldShowHr_(unreadItems_, readItems_)]]">
+    </div>
+    <div class="sp-card" hidden="[[!readItems_.length]]">
+      <sp-heading compact hide-back-button>
         <h2 slot="heading">$i18n{readHeader}</h2>
       </sp-heading>
       <template id="readItemsList" is="dom-repeat" items="[[readItems_]]">
@@ -125,6 +111,23 @@
             data="[[item]]" button-ripples="[[buttonRipples]]">
         </reading-list-item>
       </template>
-    </iron-selector>
+    </div>
   </div>
+  <sp-footer pinned="[[!isReadingListEmpty_(unreadItems_, readItems_)]]">
+    <cr-button id="currentPageActionButton" class="floating-button"
+        aria-label="[[getCurrentPageActionButtonText_(
+            currentPageActionButtonState_)]]"
+        on-click="onCurrentPageActionButtonClick_"
+        disabled="[[getCurrentPageActionButtonDisabled_(
+            currentPageActionButtonState_)]]">
+      <iron-icon id="currentPageActionButtonIcon" aria-hidden="true"
+          slot="prefix-icon"
+          icon="[[getCurrentPageActionButtonIcon_(
+              currentPageActionButtonState_)]]">
+      </iron-icon>
+      <div id="currentPageActionButtonText" aria-hidden="true">
+        [[getCurrentPageActionButtonText_(currentPageActionButtonState_)]]
+      </div>
+    </cr-button>
+  </sp-footer>
 </div>
diff --git a/chrome/browser/resources/side_panel/reading_list/app.ts b/chrome/browser/resources/side_panel/reading_list/app.ts
index f5dbc68..336b9718 100644
--- a/chrome/browser/resources/side_panel/reading_list/app.ts
+++ b/chrome/browser/resources/side_panel/reading_list/app.ts
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 
 import 'chrome://read-later.top-chrome/shared/sp_empty_state.js';
+import 'chrome://read-later.top-chrome/shared/sp_footer.js';
 import 'chrome://read-later.top-chrome/shared/sp_heading.js';
+import 'chrome://read-later.top-chrome/shared/sp_shared_style.css.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_hidden_style.css.js';
@@ -21,8 +23,8 @@
 import {EventTracker} from 'chrome://resources/js/event_tracker.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {listenOnce} from 'chrome://resources/js/util_ts.js';
-import {IronSelectorElement} from 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js';
-import {DomRepeat, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {IronSelectableBehavior} from 'chrome://resources/polymer/v3_0/iron-selector/iron-selectable.js';
+import {DomRepeat, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {getTemplate} from './app.html.js';
 import {CurrentPageActionButtonState, ReadLaterEntriesByStatus, ReadLaterEntry} from './reading_list.mojom-webui.js';
@@ -31,13 +33,15 @@
 
 const navigationKeys: Set<string> = new Set(['ArrowDown', 'ArrowUp']);
 
-const ReadingListAppElementBase = HelpBubbleMixin(PolymerElement) as
-    {new (): PolymerElement & HelpBubbleMixinInterface};
+const ReadingListAppElementBase = mixinBehaviors(
+                                      [IronSelectableBehavior],
+                                      HelpBubbleMixin(PolymerElement)) as {
+  new (): PolymerElement & HelpBubbleMixinInterface & IronSelectableBehavior,
+};
 
 export interface ReadingListAppElement {
   $: {
     readingListList: HTMLElement,
-    selector: IronSelectorElement,
     unreadItemsList: DomRepeat,
   };
 }
@@ -58,6 +62,12 @@
 
   static get properties() {
     return {
+      /** Property for IronSelectableBehavior */
+      attrForSelected: {
+        type: String,
+        value: 'data-url',
+      },
+
       unreadItems_: {
         type: Array,
         value: [],
@@ -161,6 +171,11 @@
         });
   }
 
+  /** Overridden from IronSelectableBehavior to allow nested items. */
+  override get items() {
+    return Array.from(this.shadowRoot!.querySelectorAll('reading-list-item'));
+  }
+
   /**
    * Fetches the latest reading list entries from the browser.
    */
@@ -279,12 +294,12 @@
     }
     switch (e.key) {
       case 'ArrowDown':
-        this.$.selector.selectNext();
-        (this.$.selector.selectedItem as ReadingListItemElement).focus();
+        this.selectNext();
+        (this.selectedItem as ReadingListItemElement).focus();
         break;
       case 'ArrowUp':
-        this.$.selector.selectPrevious();
-        (this.$.selector.selectedItem as ReadingListItemElement).focus();
+        this.selectPrevious();
+        (this.selectedItem as ReadingListItemElement).focus();
         break;
       default:
         assertNotReached();
@@ -294,8 +309,7 @@
   }
 
   private onItemFocus_(e: Event) {
-    this.$.selector.selected =
-        (e.currentTarget as ReadingListItemElement).dataset['url']!;
+    this.selected = (e.currentTarget as ReadingListItemElement).dataset['url']!;
   }
 
   private shouldShowHr_(): boolean {
diff --git a/chrome/browser/resources/side_panel/reading_list/reading_list.html b/chrome/browser/resources/side_panel/reading_list/reading_list.html
index eb07515..79a5fa17 100644
--- a/chrome/browser/resources/side_panel/reading_list/reading_list.html
+++ b/chrome/browser/resources/side_panel/reading_list/reading_list.html
@@ -15,6 +15,10 @@
       background-color: var(--mwb-background-color);
       margin: 0;
     }
+
+    html[chrome-refresh-2023] body {
+      background: var(--color-side-panel-content-background);
+    }
   </style>
 </head>
 <body>
diff --git a/chrome/browser/resources/suggest_internals/app.html b/chrome/browser/resources/suggest_internals/app.html
index d951571..9a56768 100644
--- a/chrome/browser/resources/suggest_internals/app.html
+++ b/chrome/browser/resources/suggest_internals/app.html
@@ -38,7 +38,7 @@
 </style>
 <cr-toolbar page-name="Suggest Debug Tool" search-prompt="Filter requests"
     clear-label="Clear filter" on-search-changed="onFilterChanged_"
-    always-show-logo show-search show-menu on-cr-toolbar-menu-tap="showOutputControls_">
+    always-show-logo show-search show-menu on-cr-toolbar-menu-click="showOutputControls_">
 </cr-toolbar>
 <cr-drawer id="drawer" heading="Output controls">
   <div slot="body">
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.html
index 0bdc173..98cfc83 100644
--- a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.html
+++ b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.html
@@ -1,6 +1,7 @@
 <link rel="stylesheet" href="../demo.css">
 <style include="cr-hidden-style cr-icons">
-  cr-input {
+  cr-input,
+  cr-textarea {
     max-width: 400px;
     width: 100%;
   }
@@ -95,11 +96,18 @@
       value="The value cannot be changed">
   </cr-input>
 
+  <cr-textarea
+      type="text"
+      label="Textarea"
+      value="{{textareaValue_}}">
+  </cr-textarea>
+
   <div>
     <div>Text input value: [[textValue_]]</div>
     <div>Search input value: [[searchValue_]]</div>
     <div>Email input value: [[emailValue_]]</div>
     <div>Number input value: [[numberValue_]]</div>
     <div>Pin input value: [[pinValue_]]</div>
+    <div>Textarea value: [[textareaValue_]]</div>
   </div>
 </div>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.ts
index 6018e498..f33535d 100644
--- a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.ts
+++ b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.ts
@@ -3,10 +3,11 @@
 // found in the LICENSE file.
 
 import '//resources/cr_elements/cr_button/cr_button.js';
-import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
-import '//resources/cr_elements/cr_input/cr_input.js';
-import '//resources/cr_elements/cr_icons.css.js';
 import '//resources/cr_elements/cr_hidden_style.css.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
+import '//resources/cr_elements/cr_icons.css.js';
+import '//resources/cr_elements/cr_input/cr_input.js';
+import '//resources/cr_elements/cr_textarea/cr_textarea.js';
 
 import {CrInputElement} from '//resources/cr_elements/cr_input/cr_input.js';
 import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -35,6 +36,7 @@
       pinValue_: String,
       searchValue_: String,
       textValue_: String,
+      textareaValue_: String,
     };
   }
 
@@ -43,6 +45,7 @@
   private pinValue_: string;
   private searchValue_: string;
   private textValue_: string;
+  private textareaValue_: string;
 
   private onClearSearchClick_() {
     this.searchValue_ = '';
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.html
index d95da8a..b0b9487 100644
--- a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.html
+++ b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.html
@@ -18,7 +18,7 @@
     always-show-logo="[[alwaysShowLogo_]]"
     show-menu="[[showMenu_]]"
     show-search="[[showSearch_]]"
-    on-cr-toolbar-menu-tap="onMenuTap_"
+    on-cr-toolbar-menu-click="onMenuClick_"
     on-search-changed="onSearchChanged_">
   <div hidden$="[[!showSlottedContent_]]">
     Slotted right-hand content
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.ts
index 8182511..50643c1a 100644
--- a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.ts
+++ b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.ts
@@ -47,7 +47,7 @@
   private showSearch_: boolean = true;
   private showSlottedContent_: boolean = false;
 
-  private onMenuTap_() {
+  private onMenuClick_() {
     this.push('log_', 'Menu tapped.');
   }
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
index 351766fb..9fdd40e 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -3755,6 +3755,8 @@
                            std::vector<GURL>(),  // server redirects
                            ReferrerChainEntry::UNDEFINED,
                            referrer_chain.Get(1));
+  // The is_url_removed_by_policy field should not be set on empty entry.
+  EXPECT_FALSE(referrer_chain.Get(1).has_is_url_removed_by_policy());
   VerifyReferrerChainEntry(
       redirect_url,                           // url
       GURL(),                                 // main_frame_url
diff --git a/chrome/browser/safe_browsing/tailored_security/OWNERS b/chrome/browser/safe_browsing/tailored_security/OWNERS
new file mode 100644
index 0000000..4fc117e
--- /dev/null
+++ b/chrome/browser/safe_browsing/tailored_security/OWNERS
@@ -0,0 +1 @@
+jacastro@chromium.org
diff --git a/chrome/browser/serial/chrome_serial_delegate.cc b/chrome/browser/serial/chrome_serial_delegate.cc
index a53030a..bde8c88e 100644
--- a/chrome/browser/serial/chrome_serial_delegate.cc
+++ b/chrome/browser/serial/chrome_serial_delegate.cc
@@ -31,10 +31,13 @@
 std::unique_ptr<content::SerialChooser> ChromeSerialDelegate::RunChooser(
     content::RenderFrameHost* frame,
     std::vector<blink::mojom::SerialPortFilterPtr> filters,
+    std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids,
     content::SerialChooser::Callback callback) {
   return std::make_unique<SerialChooser>(chrome::ShowDeviceChooserDialog(
       frame, std::make_unique<SerialChooserController>(
-                 frame, std::move(filters), std::move(callback))));
+                 frame, std::move(filters),
+                 std::move(allowed_bluetooth_service_class_ids),
+                 std::move(callback))));
 }
 
 bool ChromeSerialDelegate::CanRequestPortPermission(
diff --git a/chrome/browser/serial/chrome_serial_delegate.h b/chrome/browser/serial/chrome_serial_delegate.h
index a0cd1667..95e8f82 100644
--- a/chrome/browser/serial/chrome_serial_delegate.h
+++ b/chrome/browser/serial/chrome_serial_delegate.h
@@ -22,6 +22,7 @@
   std::unique_ptr<content::SerialChooser> RunChooser(
       content::RenderFrameHost* frame,
       std::vector<blink::mojom::SerialPortFilterPtr> filters,
+      std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids,
       content::SerialChooser::Callback callback) override;
   bool CanRequestPortPermission(content::RenderFrameHost* frame) override;
   bool HasPortPermission(content::RenderFrameHost* frame,
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
index b1def92..b2ee966 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
@@ -121,7 +121,6 @@
         mDeviceLockActivityLauncher = deviceLockActivityLauncher;
 
         mOrderedFirstPartyOptions = new ArrayList<>();
-        initializeFirstPartyOptionsInOrder();
     }
 
     /**
@@ -249,9 +248,10 @@
 
     /**
      * Creates all enabled {@link FirstPartyOption}s and adds them to {@code
-     * mOrderedFirstPartyOptions} in the order they should appear.
+     * mOrderedFirstPartyOptions} in the order they should appear. This has to be called by child
+     * classes before the provider can function
      */
-    private void initializeFirstPartyOptionsInOrder() {
+    protected void initializeFirstPartyOptionsInOrder() {
         // Only show a limited first party share selection for automotive
         if (BuildInfo.getInstance().isAutomotive) {
             mOrderedFirstPartyOptions.add(createCopyLinkFirstPartyOption());
@@ -260,7 +260,6 @@
             return;
         }
         if (usePolishedActionOrderedList()) {
-            mOrderedFirstPartyOptions.add(createCopyLinkFirstPartyOption());
             maybeAddCopyFirstPartyOption();
             maybeAddLongScreenshotFirstPartyOption();
             maybeAddPrintFirstPartyOption();
@@ -272,7 +271,6 @@
             maybeAddLongScreenshotFirstPartyOption();
             // Always show the copy link option as some entries does not offer the change for copy
             // (e.g. feed card)
-            mOrderedFirstPartyOptions.add(createCopyLinkFirstPartyOption());
             maybeAddCopyFirstPartyOption();
             maybeAddSendTabToSelfFirstPartyOption();
             maybeAddQrCodeFirstPartyOption();
@@ -326,8 +324,9 @@
     }
 
     protected void maybeAddCopyFirstPartyOption() {
+        mOrderedFirstPartyOptions.add(createCopyLinkFirstPartyOption());
         mOrderedFirstPartyOptions.add(createCopyGifFirstPartyOption());
-        mOrderedFirstPartyOptions.add(createCopyImageFirstPartyOption());
+        mOrderedFirstPartyOptions.add(createCopyImageFirstPartyOption(true));
         mOrderedFirstPartyOptions.add(createCopyFirstPartyOption());
         mOrderedFirstPartyOptions.add(createCopyTextFirstPartyOption());
     }
@@ -375,19 +374,27 @@
                 .build();
     }
 
-    private FirstPartyOption createCopyImageFirstPartyOption() {
-        return new FirstPartyOptionBuilder(ContentType.IMAGE, ContentType.IMAGE_AND_LINK)
-                .setIcon(R.drawable.ic_content_copy_black, R.string.sharing_copy_image)
-                .setFeatureNameForMetrics(USER_ACTION_COPY_IMAGE_SELECTED)
-                .setDetailedContentTypesToDisableFor(DetailedContentType.GIF)
-                .setOnClickCallback((view) -> {
-                    Uri imageUri = mShareParams.getImageUriToShare();
-                    if (imageUri != null) {
-                        Clipboard.getInstance().setImageUri(imageUri);
-                        Toast.makeText(mActivity, R.string.image_copied, Toast.LENGTH_SHORT).show();
-                    }
-                })
-                .build();
+    /**
+     * @param excludeGif Whether exclude the GIF copy from copy image action.
+     * @return The copy first party option.
+     */
+    protected FirstPartyOption createCopyImageFirstPartyOption(boolean excludeGif) {
+        FirstPartyOptionBuilder builder =
+                new FirstPartyOptionBuilder(ContentType.IMAGE, ContentType.IMAGE_AND_LINK)
+                        .setIcon(R.drawable.ic_content_copy_black, R.string.sharing_copy_image)
+                        .setFeatureNameForMetrics(USER_ACTION_COPY_IMAGE_SELECTED)
+                        .setOnClickCallback((view) -> {
+                            Uri imageUri = mShareParams.getImageUriToShare();
+                            if (imageUri != null) {
+                                Clipboard.getInstance().setImageUri(imageUri);
+                                Toast.makeText(mActivity, R.string.image_copied, Toast.LENGTH_SHORT)
+                                        .show();
+                            }
+                        });
+        if (excludeGif) {
+            builder.setDetailedContentTypesToDisableFor(DetailedContentType.GIF);
+        }
+        return builder.build();
     }
 
     private FirstPartyOption createCopyFirstPartyOption() {
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeShareExtras.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeShareExtras.java
index b634ad2..2798013 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeShareExtras.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeShareExtras.java
@@ -21,7 +21,8 @@
 public class ChromeShareExtras {
     @IntDef({DetailedContentType.NOT_SPECIFIED, DetailedContentType.IMAGE, DetailedContentType.GIF,
             DetailedContentType.HIGHLIGHTED_TEXT, DetailedContentType.SCREENSHOT,
-            DetailedContentType.WEB_NOTES, DetailedContentType.LIGHTWEIGHT_REACTION})
+            DetailedContentType.WEB_NOTES, DetailedContentType.LIGHTWEIGHT_REACTION,
+            DetailedContentType.WEB_SHARE})
     public @interface DetailedContentType {
         int NOT_SPECIFIED = 0;
         int IMAGE = 1;
@@ -30,6 +31,7 @@
         int SCREENSHOT = 4;
         int WEB_NOTES = 5;
         int LIGHTWEIGHT_REACTION = 6;
+        int WEB_SHARE = 7;
     }
 
     /**
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidCustomActionProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidCustomActionProvider.java
index 58dcb9e..c738abc4 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidCustomActionProvider.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidCustomActionProvider.java
@@ -47,6 +47,7 @@
             "SharingHubAndroid.AndroidShareHighlightText.WithLink";
     private static final String USER_ACTION_SHARE_HIGHLIGHT_TEXT_WITHOUT_LINK =
             "SharingHubAndroid.AndroidShareHighlightText.WithoutLink";
+
     private static final String USER_ACTION_LONG_SCREENSHOT_NO_EDITOR_SELECTED =
             "SharingHubAndroid.LongScreenshotSelected.NoEditor";
     private static final Integer MAX_ACTION_SUPPORTED = 5;
@@ -90,6 +91,8 @@
                 deviceLockActivityLauncher);
         mChromeShareExtras = chromeShareExtras;
         mLinkToTextCoordinator = linkToTextCoordinator;
+
+        initializeFirstPartyOptionsInOrder();
         initCustomActions(shareParams, chromeShareExtras, isMultiWindow);
     }
 
@@ -118,6 +121,7 @@
 
         // getLinkToTextSuccessful is only populated when an link is generated for share.
         if (mShareParams.getLinkToTextSuccessful() != null && mShareParams.getLinkToTextSuccessful()
+                && mChromeShareExtras != null
                 && mChromeShareExtras.getDetailedContentType()
                         == ChromeShareExtras.DetailedContentType.HIGHLIGHTED_TEXT) {
             FirstPartyOption option = TextUtils.isEmpty(mShareParams.getUrl())
@@ -175,6 +179,15 @@
     @Override
     protected void maybeAddDownloadImageFirstPartyOption() {}
 
+    @Override
+    protected void maybeAddCopyFirstPartyOption() {
+        // For Android's share sheet, only use copy image
+        if (mChromeShareExtras != null
+                && mChromeShareExtras.getDetailedContentType() == DetailedContentType.WEB_SHARE) {
+            mOrderedFirstPartyOptions.add(createCopyImageFirstPartyOption(false));
+        }
+    }
+
     private FirstPartyOption createShareHighlightTextWithLink() {
         return new FirstPartyOptionBuilder(ContentType.HIGHLIGHTED_TEXT)
                 .setIcon(R.drawable.link, R.string.sharing_include_link)
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java
index 4acdda8..3c411b31 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java
@@ -147,7 +147,8 @@
         }
 
         // If an URL is not provided along with the image, use the content URL if it is provided.
-        if (chromeShareExtras.isImage() && params.getUrl().isEmpty()) {
+        if (chromeShareExtras.isImage() && params.getUrl().isEmpty()
+                && (chromeShareExtras.getDetailedContentType() != DetailedContentType.WEB_SHARE)) {
             params.setUrl(chromeShareExtras.getContentUrl().getSpec());
         }
 
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
index cef8c1f..81ed6b6 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
@@ -96,6 +96,8 @@
         mImageEditorModuleProvider = imageEditorModuleProvider;
         mLinkGenerationStatusForMetrics = linkGenerationStatusForMetrics;
         mLinkToggleMetricsDetails = linkToggleMetricsDetails;
+
+        initializeFirstPartyOptionsInOrder();
     }
 
     /**
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
index d6351f0..41de372 100644
--- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
+++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
@@ -84,6 +84,7 @@
 import org.chromium.components.prefs.PrefService;
 import org.chromium.components.user_prefs.UserPrefsJni;
 import org.chromium.ui.base.ActivityWindowAndroid;
+import org.chromium.ui.base.Clipboard;
 import org.chromium.ui.base.IntentRequestTracker;
 import org.chromium.ui.base.TestActivity;
 import org.chromium.ui.base.WindowAndroid;
@@ -216,7 +217,7 @@
         Assert.assertNotNull("Custom action is empty.",
                 intent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS));
 
-        assertCustomActions(intent, R.string.sharing_copy_url, R.string.sharing_long_screenshot,
+        assertCustomActions(intent, R.string.sharing_long_screenshot,
                 R.string.print_share_activity_title, R.string.sharing_send_tab_to_self,
                 R.string.qr_code_share_icon_label);
     }
@@ -331,8 +332,8 @@
         mController.showShareSheet(params, chromeShareExtras, 1L);
 
         Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
-        assertCustomActions(intent, R.string.sharing_copy_image, R.string.sharing_send_tab_to_self,
-                R.string.qr_code_share_icon_label);
+        assertCustomActions(
+                intent, R.string.sharing_send_tab_to_self, R.string.qr_code_share_icon_label);
     }
 
     @Test
@@ -415,7 +416,7 @@
                 "\"highlight\"\n " + JUnitTestGURLs.TEXT_FRAGMENT_URL,
                 shareIntent.getStringExtra(Intent.EXTRA_TEXT));
 
-        assertCustomActions(chooserIntent, R.string.sharing_copy, R.string.sharing_send_tab_to_self,
+        assertCustomActions(chooserIntent, R.string.sharing_send_tab_to_self,
                 R.string.qr_code_share_icon_label);
 
         // Toggle the modify action again, link is removed from text.
@@ -425,7 +426,7 @@
         Assert.assertEquals("Text being shared is different.", "highlight",
                 shareIntent2.getStringExtra(Intent.EXTRA_TEXT));
 
-        assertCustomActions(chooserIntent2, R.string.sharing_copy_text);
+        assertCustomActions(chooserIntent2);
 
         // Toggle the modify action again, link is reattached with the text.
         runModifyActionFromChooserIntent(chooserIntent2);
@@ -467,8 +468,7 @@
                 shareIntent.getStringExtra(Intent.EXTRA_TEXT));
         Assert.assertNull("Modify action should be null when generating link to text failed.",
                 chooserIntent.getParcelableExtra(INTENT_EXTRA_CHOOSER_MODIFY_SHARE_ACTION));
-
-        assertCustomActions(chooserIntent, R.string.sharing_copy_text);
+        assertCustomActions(chooserIntent);
     }
 
     @Test
@@ -492,8 +492,8 @@
         mController.showShareSheet(params, chromeShareExtras, 1L);
 
         Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
-        assertCustomActions(intent, R.string.sharing_copy_image, R.string.sharing_send_tab_to_self,
-                R.string.qr_code_share_icon_label);
+        assertCustomActions(
+                intent, R.string.sharing_send_tab_to_self, R.string.qr_code_share_icon_label);
         chooseCustomAction(intent, R.string.qr_code_share_icon_label);
 
         Assert.assertEquals("Image source URL should be used for QR Code.",
@@ -521,8 +521,60 @@
 
         // No download option here.
         Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
+        assertCustomActions(
+                intent, R.string.sharing_send_tab_to_self, R.string.qr_code_share_icon_label);
+    }
+
+    @Test
+    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    public void webShareImageLink() throws CanceledException {
+        Uri testImageUri = Uri.parse("content://test.image.uri/image.png");
+        ShareParams params = new ShareParams.Builder(mWindow, "title", JUnitTestGURLs.EXAMPLE_URL)
+                                     .setText("text")
+                                     .setBypassFixingDomDistillerUrl(true)
+                                     .setSingleImageUri(testImageUri)
+                                     .setFileContentType("image/png")
+                                     .build();
+        ChromeShareExtras chromeShareExtras =
+                new ChromeShareExtras.Builder()
+                        .setDetailedContentType(DetailedContentType.WEB_SHARE)
+                        .build();
+        mController.showShareSheet(params, chromeShareExtras, 1L);
+        Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
         assertCustomActions(intent, R.string.sharing_copy_image, R.string.sharing_send_tab_to_self,
                 R.string.qr_code_share_icon_label);
+
+        Intent shareIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+        Assert.assertEquals("Sharing text should be the URL.", JUnitTestGURLs.EXAMPLE_URL,
+                shareIntent.getStringExtra(Intent.EXTRA_TEXT));
+
+        // Attempt to do the copy image action.
+        // TODO(crbug/1448355): Set up a real temp image and verify the URI is correct.
+        chooseCustomAction(intent, R.string.sharing_copy_image);
+        Assert.assertTrue("Clipboard cannot paste.", Clipboard.getInstance().canPaste());
+    }
+
+    @Test
+    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    public void webShareImageOnly() {
+        Uri testImageUri = Uri.parse("content://test.image.uri");
+        ShareParams params = new ShareParams.Builder(mWindow, "title", "")
+                                     .setText("text")
+                                     .setBypassFixingDomDistillerUrl(true)
+                                     .setSingleImageUri(testImageUri)
+                                     .setFileContentType("image/png")
+                                     .build();
+        ChromeShareExtras chromeShareExtras =
+                new ChromeShareExtras.Builder()
+                        .setDetailedContentType(DetailedContentType.WEB_SHARE)
+                        .build();
+        mController.showShareSheet(params, chromeShareExtras, 1L);
+        Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
+        assertCustomActions(intent, R.string.sharing_copy_image, R.string.sharing_send_tab_to_self);
+
+        Intent shareIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+        Assert.assertNull(
+                "Sharing text should be empty.", shareIntent.getStringExtra(Intent.EXTRA_TEXT));
     }
 
     private void setFaviconToFetchForTest(Bitmap favicon) {
@@ -546,6 +598,12 @@
     private void assertCustomActions(Intent chooserIntent, Integer... expectedStringRes) {
         Parcelable[] actions =
                 chooserIntent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS);
+        if (expectedStringRes.length == 0) {
+            Assert.assertTrue(
+                    "No custom actions are expected.", actions == null || actions.length == 0);
+            return;
+        }
+
         StringBuilder actualStringBuilder = new StringBuilder();
         for (Parcelable action : actions) {
             String name = ((Bundle) action).getString(KEY_CHOOSER_ACTION_NAME);
diff --git a/chrome/browser/signin/chrome_signin_client_unittest.cc b/chrome/browser/signin/chrome_signin_client_unittest.cc
index 8e859b4..68525008 100644
--- a/chrome/browser/signin/chrome_signin_client_unittest.cc
+++ b/chrome/browser/signin/chrome_signin_client_unittest.cc
@@ -30,6 +30,7 @@
 #include "components/signin/public/base/signin_pref_names.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
+#include "components/supervised_user/core/common/buildflags.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/test/browser_task_environment.h"
 #include "services/network/test/test_network_connection_tracker.h"
diff --git a/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc b/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc
index 7ad54fb7..55898092 100644
--- a/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc
+++ b/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc
@@ -21,6 +21,7 @@
 #include "components/signin/core/browser/signin_header_helper.h"
 #include "components/signin/public/base/signin_pref_names.h"
 #include "components/signin/public/identity_manager/identity_test_utils.h"
+#include "components/supervised_user/core/common/buildflags.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/sync/prefs/chrome_syncable_prefs_database.cc b/chrome/browser/sync/prefs/chrome_syncable_prefs_database.cc
index 674346b..6f4b5ba 100644
--- a/chrome/browser/sync/prefs/chrome_syncable_prefs_database.cc
+++ b/chrome/browser/sync/prefs/chrome_syncable_prefs_database.cc
@@ -14,6 +14,7 @@
 #include "components/performance_manager/public/user_tuning/prefs.h"
 #include "components/privacy_sandbox/privacy_sandbox_prefs.h"
 #include "components/spellcheck/browser/pref_names.h"
+#include "components/supervised_user/core/common/buildflags.h"
 #include "components/translate/core/browser/translate_prefs.h"
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_pref_names.h"
diff --git a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc
index c458c4e..e0f77d7 100644
--- a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc
+++ b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc
@@ -69,10 +69,12 @@
 
   return PasskeyCredential(
       PasskeyCredential::Source::kAndroidPhone,
-      ConvertJavaStringToUTF8(Java_WebAuthnCredential_getRpId(env, credential)),
-      std::move(credential_id), std::move(user_id),
-      ConvertJavaStringToUTF8(
-          Java_WebAuthnCredential_getUsername(env, credential)));
+      PasskeyCredential::RpId(ConvertJavaStringToUTF8(
+          Java_WebAuthnCredential_getRpId(env, credential))),
+      PasskeyCredential::CredentialId(std::move(credential_id)),
+      PasskeyCredential::UserId(std::move(user_id)),
+      PasskeyCredential::Username(ConvertJavaStringToUTF8(
+          Java_WebAuthnCredential_getUsername(env, credential))));
 }
 
 }  // namespace
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc
index ee8d88d..e8de5115 100644
--- a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc
+++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc
@@ -701,9 +701,12 @@
   MockTouchToFillView* weak_view = mock_view.get();
   touch_to_fill_controller().set_view(std::move(mock_view));
 
-  PasskeyCredential credential(PasskeyCredential::Source::kAndroidPhone,
-                               "example.com", {1, 2, 3, 4}, {5, 6, 7, 8},
-                               "alice@example.com");
+  PasskeyCredential credential(
+      PasskeyCredential::Source::kAndroidPhone,
+      PasskeyCredential::RpId("example.com"),
+      PasskeyCredential::CredentialId({1, 2, 3, 4}),
+      PasskeyCredential::UserId({5, 6, 7, 8}),
+      PasskeyCredential::Username("alice@example.com"));
   std::vector<PasskeyCredential> credentials({credential});
 
   EXPECT_CALL(*weak_view,
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate_unittest.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate_unittest.cc
index f19d1bf6b..7e3f440b 100644
--- a/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate_unittest.cc
+++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate_unittest.cc
@@ -42,9 +42,11 @@
     std::vector<uint8_t> credential_id = kCredentialId1,
     std::vector<uint8_t> user_id = kUserId1,
     std::string username = kUserName1) {
-  return PasskeyCredential(PasskeyCredential::Source::kAndroidPhone, kRpId,
-                           std::move(credential_id), std::move(user_id),
-                           std::move(username));
+  return PasskeyCredential(
+      PasskeyCredential::Source::kAndroidPhone, PasskeyCredential::RpId(kRpId),
+      PasskeyCredential::CredentialId(std::move(credential_id)),
+      PasskeyCredential::UserId(std::move(user_id)),
+      PasskeyCredential::Username(std::move(username)));
 }
 
 class MockWebAuthnRequestDelegateAndroid
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index ddc2a5d..894b2ec 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -736,6 +736,7 @@
     "//printing/buildflags",
     "//rlz/buildflags",
     "//services/device/public/cpp:device_features",
+    "//services/device/public/cpp/bluetooth",
     "//services/device/public/cpp/geolocation",
     "//services/metrics/public/cpp:ukm_builders",
     "//services/network/public/mojom",
@@ -1213,6 +1214,8 @@
       "global_media_controls/cast_media_notification_producer.h",
       "global_media_controls/cast_media_session_controller.cc",
       "global_media_controls/cast_media_session_controller.h",
+      "global_media_controls/live_translate_combobox_model.cc",
+      "global_media_controls/live_translate_combobox_model.h",
       "global_media_controls/media_item_ui_device_selector_delegate.h",
       "global_media_controls/media_item_ui_metrics.cc",
       "global_media_controls/media_item_ui_metrics.h",
@@ -1361,6 +1364,8 @@
       "performance_controls/performance_controls_hats_service_factory.h",
       "performance_controls/performance_controls_metrics.cc",
       "performance_controls/performance_controls_metrics.h",
+      "performance_controls/resource_usage_tab_helper.cc",
+      "performance_controls/resource_usage_tab_helper.h",
       "permission_bubble/permission_prompt.h",
       "privacy_sandbox/privacy_sandbox_prompt.cc",
       "privacy_sandbox/privacy_sandbox_prompt.h",
@@ -4111,6 +4116,7 @@
 
     deps += [
       ":ui_arc",
+      "//base:base_arc",
       "//chrome/browser/apps/app_shim",
       "//chrome/browser/mac:keystone_glue",
       "//chrome/browser/updater:browser_updater_client",
diff --git a/chrome/browser/ui/android/context_menu_helper.cc b/chrome/browser/ui/android/context_menu_helper.cc
index fa6d13a..1f40182 100644
--- a/chrome/browser/ui/android/context_menu_helper.cc
+++ b/chrome/browser/ui/android/context_menu_helper.cc
@@ -50,7 +50,9 @@
   gfx::NativeView view = GetWebContents().GetNativeView();
   Java_ContextMenuHelper_showContextMenu(
       env, java_obj_,
-      context_menu::BuildJavaContextMenuParams(context_menu_params_),
+      context_menu::BuildJavaContextMenuParams(
+          context_menu_params_, render_frame_host.GetProcess()->GetID(),
+          render_frame_host.GetFrameToken().value()),
       render_frame_host.GetJavaRenderFrameHost(), view->GetContainerView(),
       view->content_offset() * view->GetDipScale());
 }
diff --git a/chrome/browser/ui/ash/ambient/managed_screensaver_browsertest.cc b/chrome/browser/ui/ash/ambient/managed_screensaver_browsertest.cc
index f7c27690..853c2652 100644
--- a/chrome/browser/ui/ash/ambient/managed_screensaver_browsertest.cc
+++ b/chrome/browser/ui/ash/ambient/managed_screensaver_browsertest.cc
@@ -15,28 +15,43 @@
 #include "base/command_line.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ash/login/lock/screen_locker_tester.h"
 #include "chrome/browser/ash/login/login_manager_test.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
+#include "chrome/browser/ash/login/test/user_policy_mixin.h"
 #include "chrome/browser/ash/ownership/owner_settings_service_ash_factory.h"
 #include "chrome/browser/ash/policy/core/device_policy_builder.h"
+#include "chrome/browser/ash/policy/core/user_policy_test_helper.h"
+#include "chrome/browser/ash/policy/test_support/embedded_policy_test_server_mixin.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h"
 #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
 #include "components/ownership/mock_owner_key_util.h"
 #include "components/policy/core/common/cloud/test/policy_builder.h"
 #include "components/policy/proto/cloud_policy.pb.h"
+#include "components/signin/public/identity_manager/identity_test_utils.h"
 #include "content/public/test/browser_test.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "url/gurl.h"
 
 namespace ash {
 
+const char kTestEmail[] = "test@example.com";
 const char kRedImageFileName[] = "chromeos/screensaver/red.jpg";
 const char kGreenImageFileName[] = "chromeos/screensaver/green.jpg";
 const char kBlueImageFileName[] = "chromeos/screensaver/blue.jpg";
 
+enum class TestType { LockScreen, LoginScreen };
+struct ManagedScreensaverBrowserTestCase {
+  std::string test_name;
+  TestType test_type;
+};
+
 class ManagedScreensaverBrowserTest : public LoginManagerTest {
  public:
   ManagedScreensaverBrowserTest()
@@ -45,7 +60,6 @@
     feature_list_.InitAndEnableFeature(
         ash::features::kAmbientModeManagedScreensaver);
     https_server_.AddDefaultHandlers(GetChromeTestDataDir());
-    login_manager_mixin_.AppendManagedUsers(1);
   }
   ~ManagedScreensaverBrowserTest() override = default;
 
@@ -74,6 +88,21 @@
     SetDevicePolicyScreenIdleTimeoutSeconds(0);
   }
 
+  void InitializeForLockScreen() {
+    const auto& users = login_manager_mixin_.users();
+    EXPECT_EQ(users.size(), 1u);
+    user_policy_mixin_.RequestPolicyUpdate();
+
+    LoginUser(test_account_id_);
+    screen_locker_ = std::make_unique<ScreenLockerTester>();
+    screen_locker_->Lock();
+    SetPolicyEnabled(true);
+
+    // Set intervals to zero so that we don't rely on time during testing
+    SetPolicyImageDisplayIntervalSeconds(0);
+    SetPolicyScreenIdleTimeoutSeconds(0);
+  }
+
   void SetUpCommandLine(base::CommandLine* command_line) override {
     LoginManagerTest::SetUpCommandLine(command_line);
     // Allow failing policy fetch so that we don't shutdown the profile on
@@ -96,10 +125,14 @@
     https_server_.StartAcceptingConnections();
   }
 
+  void TearDownOnMainThread() override {
+    screen_locker_.reset();
+    LoginManagerTest::TearDownOnMainThread();
+  }
+
   void SetDevicePolicyImages(const std::vector<std::string>& images) {
     if (images.empty()) {
       device_policy_.payload().Clear();
-      BuildDevicePolicyAndNotify();
       return;
     }
 
@@ -110,7 +143,6 @@
       mutable_images->add_device_screensaver_login_screen_images(
           https_server_.GetURL("/" + image_path).spec());
     }
-    BuildDevicePolicyAndNotify();
   }
 
   void SetDevicePolicyEnabled(bool enabled) {
@@ -121,7 +153,6 @@
     } else {
       device_policy_.payload().Clear();
     }
-    BuildDevicePolicyAndNotify();
   }
 
   void SetDevicePolicyImageDisplayIntervalSeconds(int64_t interval) {
@@ -129,18 +160,15 @@
         .mutable_device_screensaver_login_screen_image_display_interval_seconds()
         ->set_device_screensaver_login_screen_image_display_interval_seconds(
             interval);
-
-    BuildDevicePolicyAndNotify();
   }
 
   void SetDevicePolicyScreenIdleTimeoutSeconds(int64_t timeout) {
     device_policy_.payload()
         .mutable_device_screensaver_login_screen_idle_timeout_seconds()
         ->set_device_screensaver_login_screen_idle_timeout_seconds(timeout);
-    BuildDevicePolicyAndNotify();
   }
 
-  void BuildDevicePolicyAndNotify() {
+  void RefreshDevicePolicy() {
     device_policy_.Build();
     FakeSessionManagerClient::Get()->set_device_policy(
         device_policy_.GetBlob());
@@ -148,6 +176,64 @@
         /*success=*/true);
   }
 
+  void RefreshUserPolicy() {
+    Profile* profile =
+        ash::ProfileHelper::Get()->GetProfileByAccountId(test_account_id_);
+    user_policy_test_helper_.RefreshPolicyAndWait(profile);
+  }
+
+  // TODO(b:280809373): Remove mutable subproto1 once policies are released.
+  void SetPolicyImages(const std::vector<std::string>& images) {
+    user_policy_mixin_.RequestPolicyUpdate()
+        ->policy_payload()
+        ->mutable_subproto1()
+        ->mutable_screensaverlockscreenimages()
+        ->Clear();
+    // Policy update variable should be explicitly declared here, otherwise it
+    // might go out of scope immediately and cause multiple updates if we inline
+    // the call in the loop.
+    std::unique_ptr<ScopedUserPolicyUpdate> policy =
+        user_policy_mixin_.RequestPolicyUpdate();
+
+    auto* mutable_images = policy->policy_payload()
+                               ->mutable_subproto1()
+                               ->mutable_screensaverlockscreenimages();
+    for (const auto& image_path : images) {
+      mutable_images->mutable_value()->mutable_entries()->Add(
+          std::string(https_server_.GetURL("/" + image_path).spec()));
+    }
+  }
+
+  void SetPolicyEnabled(bool enabled) {
+    if (enabled) {
+      user_policy_mixin_.RequestPolicyUpdate()
+          ->policy_payload()
+          ->mutable_subproto1()
+          ->mutable_screensaverlockscreenenabled()
+          ->set_value(enabled);
+    } else {
+      user_policy_mixin_.RequestPolicyUpdate()->policy_payload()->Clear();
+    }
+  }
+
+  void SetPolicyImageDisplayIntervalSeconds(int64_t interval) {
+    std::unique_ptr<ScopedUserPolicyUpdate> policy =
+        user_policy_mixin_.RequestPolicyUpdate();
+    policy->policy_payload()
+        ->mutable_subproto1()
+        ->mutable_screensaverlockscreenimagedisplayintervalseconds()
+        ->set_value(interval);
+  }
+
+  void SetPolicyScreenIdleTimeoutSeconds(int64_t timeout) {
+    std::unique_ptr<ScopedUserPolicyUpdate> policy =
+        user_policy_mixin_.RequestPolicyUpdate();
+    policy->policy_payload()
+        ->mutable_subproto1()
+        ->mutable_screensaverlockscreenidletimeoutseconds()
+        ->set_value(timeout);
+  }
+
   views::View* GetContainerView() {
     auto* widget =
         Shell::GetPrimaryRootWindowController()->ambient_widget_for_testing();
@@ -162,37 +248,107 @@
   }
 
  protected:
+  const AccountId test_account_id_ =
+      AccountId::FromUserEmailGaiaId(kTestEmail,
+                                     signin::GetTestGaiaIdForEmail(kTestEmail));
+
+  const LoginManagerMixin::TestUserInfo managed_user_{test_account_id_};
+
+  EmbeddedPolicyTestServerMixin policy_server_mixin_{&mixin_host_};
+
+  UserPolicyMixin user_policy_mixin_{&mixin_host_, test_account_id_,
+                                     &policy_server_mixin_};
+
   std::unique_ptr<base::RunLoop> run_loop_;
+  std::unique_ptr<ScreenLockerTester> screen_locker_;
+
   base::test::ScopedFeatureList feature_list_;
   policy::DevicePolicyBuilder device_policy_;
+  policy::UserPolicyTestHelper user_policy_test_helper_{kTestEmail,
+                                                        &policy_server_mixin_};
   scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_;
 
   DeviceStateMixin device_state_{
       &mixin_host_, DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
   net::test_server::EmbeddedTestServer https_server_;
 
-  LoginManagerMixin login_manager_mixin_{&mixin_host_};
+  LoginManagerMixin login_manager_mixin_{&mixin_host_, {managed_user_}};
 };
 
-IN_PROC_BROWSER_TEST_F(ManagedScreensaverBrowserTest, BasicTest) {
-  InitializeForLoginScreen();
-  SetDevicePolicyImages(
-      {kRedImageFileName, kBlueImageFileName, kGreenImageFileName});
+class ManagedScreensaverBrowserTestForAnyScreen
+    : public ManagedScreensaverBrowserTest,
+      public ::testing::WithParamInterface<ManagedScreensaverBrowserTestCase> {
+ public:
+  void Init() {
+    ManagedScreensaverBrowserTestCase test_case = GetParam();
+    switch (test_case.test_type) {
+      case TestType::LockScreen:
+        ManagedScreensaverBrowserTest::InitializeForLockScreen();
+        // Call refresh policy manually to not have multiple refresh calls
+        // running at the same time.
+        RefreshUserPolicy();
+
+        return;
+      case TestType::LoginScreen:
+        ManagedScreensaverBrowserTest::InitializeForLoginScreen();
+        RefreshDevicePolicy();
+        return;
+    }
+    NOTREACHED();
+  }
+
+  void SetImages(const std::vector<std::string>& images) {
+    ManagedScreensaverBrowserTestCase test_case = GetParam();
+    switch (test_case.test_type) {
+      case TestType::LockScreen:
+        SetPolicyImages(images);
+        // Call refresh policy manually to not have multiple refresh calls
+        // running at the same time.
+        RefreshUserPolicy();
+        return;
+
+      case TestType::LoginScreen:
+        SetDevicePolicyImages(images);
+        RefreshDevicePolicy();
+        return;
+    }
+    NOTREACHED();
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ManagedScreensaverBrowserTestForAnyScreenTests,
+    ManagedScreensaverBrowserTestForAnyScreen,
+    ::testing::ValuesIn<ManagedScreensaverBrowserTestCase>({
+        {"LoginScreen", TestType::LoginScreen},
+        {"LockScreen", TestType::LockScreen},
+    }),
+    [](const ::testing::TestParamInfo<
+        ManagedScreensaverBrowserTestForAnyScreen::ParamType>& info) {
+      return info.param.test_name;
+    });
+
+IN_PROC_BROWSER_TEST_P(ManagedScreensaverBrowserTestForAnyScreen, BasicTest) {
+  Init();
+  SetImages({kRedImageFileName, kBlueImageFileName, kGreenImageFileName});
+  ui::ScopedAnimationDurationScaleMode test_duration_mode(
+      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
   run_loop_ = std::make_unique<base::RunLoop>();
   AutotestAmbientApi test_api;
   test_api.WaitForPhotoTransitionAnimationCompleted(
-      /*num_completions=*/3, /*timeout=*/base::Seconds(6),
+      /*num_completions=*/3, /*timeout=*/base::Seconds(3),
       /*on_complete=*/run_loop_->QuitClosure(),
       /*on_timeout=*/base::BindOnce([]() { NOTREACHED(); }));
   run_loop_->Run();
   ASSERT_NE(nullptr, GetContainerView());
 }
 
-IN_PROC_BROWSER_TEST_F(ManagedScreensaverBrowserTest,
+IN_PROC_BROWSER_TEST_P(ManagedScreensaverBrowserTestForAnyScreen,
                        OneImageDoesNotStartAmbientMode) {
-  InitializeForLoginScreen();
-  SetDevicePolicyImages({kRedImageFileName});
-
+  Init();
+  SetImages({kRedImageFileName});
+  ui::ScopedAnimationDurationScaleMode test_duration_mode(
+      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
   AutotestAmbientApi test_api;
   run_loop_ = std::make_unique<base::RunLoop>();
   test_api.WaitForPhotoTransitionAnimationCompleted(
diff --git a/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc b/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc
index 70f7a0b..e3d7a95 100644
--- a/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc
+++ b/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc
@@ -24,9 +24,9 @@
 namespace {
 
 // The total number of Ash accelerators.
-constexpr int kAshAcceleratorsTotalNum = 147;
+constexpr int kAshAcceleratorsTotalNum = 148;
 // The hash of Ash accelerators.
-constexpr char kAshAcceleratorsHash[] = "f8f6508d9e52f67719d38748be42b5bf";
+constexpr char kAshAcceleratorsHash[] = "f7a44d1ca086c9feb1910632c2691b1a";
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 // Internal builds add an extra accelerator for the Feedback app.
 // The total number of Chrome accelerators (available on Chrome OS).
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_target_button.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_target_button.cc
index 91ead5e..448ad7e 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_target_button.cc
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_target_button.cc
@@ -7,16 +7,14 @@
 #include <memory>
 
 #include "ash/public/cpp/ash_typography.h"
-#include "ash/style/ash_color_provider.h"
-#include "ash/style/dark_light_mode_controller_impl.h"
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/ash/sharesheet/sharesheet_constants.h"
 #include "chrome/browser/ui/color/chrome_color_id.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/models/image_model.h"
-#include "ui/chromeos/styles/cros_styles.h"
-#include "ui/color/color_id.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/paint_vector_icon.h"
@@ -75,9 +73,7 @@
 
   auto* label = label_view->AddChildView(std::make_unique<views::Label>(
       display_name, CONTEXT_SHARESHEET_BUBBLE_BODY, STYLE_SHARESHEET));
-  auto secondary_text_color = AshColorProvider::Get()->GetContentLayerColor(
-      AshColorProvider::ContentLayerType::kTextColorSecondary);
-  label->SetEnabledColor(secondary_text_color);
+  label->SetEnabledColorId(cros_tokens::kTextColorSecondary);
   SetLabelProperties(label);
 
   std::u16string accessible_name = display_name;
@@ -87,7 +83,7 @@
         label_view->AddChildView(std::make_unique<views::Label>(
             secondary_display_name, CONTEXT_SHARESHEET_BUBBLE_BODY_SECONDARY,
             STYLE_SHARESHEET));
-    secondary_label->SetEnabledColor(secondary_text_color);
+    secondary_label->SetEnabledColorId(cros_tokens::kTextColorSecondary);
     SetLabelProperties(secondary_label);
     accessible_name =
         base::StrCat({display_name, u" ", secondary_display_name});
@@ -112,19 +108,23 @@
 
   if (!vector_icon_)
     return;
-  auto* color_provider = ash::AshColorProvider::Get();
-  const auto icon_color = color_provider->GetContentLayerColor(
-      ash::AshColorProvider::ContentLayerType::kIconColorProminent);
+
+  // TODO(b/284175205): Convert this to an ImageModel after Jelly launches.
+  auto* color_provider = GetColorProvider();
+  SkColor icon_color = color_provider->GetColor(
+      chromeos::features::IsJellyEnabled()
+          ? static_cast<ui::ColorId>(cros_tokens::kCrosSysPrimary)
+          : cros_tokens::kIconColorProminent);
+  SkColor circle_color = color_provider->GetColor(
+      chromeos::features::IsJellyEnabled()
+          ? static_cast<ui::ColorId>(cros_tokens::kCrosSysPrimaryContainer)
+          : cros_tokens::kBgColorElevation1);
+
   gfx::ImageSkia icon = gfx::CreateVectorIcon(
       *vector_icon_, ::sharesheet::kIconSize / 2, icon_color);
   gfx::ImageSkia circle_icon =
       gfx::ImageSkiaOperations::CreateImageWithCircleBackground(
-          ::sharesheet::kIconSize / 2,
-          cros_styles::ResolveColor(
-              cros_styles::ColorName::kBgColorElevation1,
-              ash::DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(),
-              /*use_debug_colors=*/false),
-          icon);
+          ::sharesheet::kIconSize / 2, circle_color, icon);
 
   // TODO(crbug.com/1184414): Replace hard-coded values when shadow styles
   // are implemented.
diff --git a/chrome/browser/ui/ash/user_education/welcome_tour/welcome_tour_interactive_uitest.cc b/chrome/browser/ui/ash/user_education/welcome_tour/welcome_tour_interactive_uitest.cc
index ddddf82..5968ffb6 100644
--- a/chrome/browser/ui/ash/user_education/welcome_tour/welcome_tour_interactive_uitest.cc
+++ b/chrome/browser/ui/ash/user_education/welcome_tour/welcome_tour_interactive_uitest.cc
@@ -98,10 +98,13 @@
 IN_PROC_BROWSER_TEST_F(WelcomeTourInteractiveUiTest, WelcomeTour) {
   RunTestSequence(
       // Step 1: Shelf.
-      WaitForHelpBubble(),
-      CheckHelpBubbleBodyText(IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_BODY_TEXT),
-      CheckHelpBubbleDefaultButtonText(IDS_TUTORIAL_NEXT_BUTTON),
-      PressHelpBubbleDefaultButton(),
+      InMatchingViewInPrimaryRootWindowContext(
+          ash::kShelfViewElementId,
+          Steps(WaitForHelpBubble(),
+                CheckHelpBubbleBodyText(
+                    IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_BODY_TEXT),
+                CheckHelpBubbleDefaultButtonText(IDS_TUTORIAL_NEXT_BUTTON),
+                PressHelpBubbleDefaultButton())),
 
       // Step 2: Status area.
       InMatchingViewInPrimaryRootWindowContext(
@@ -119,10 +122,17 @@
                 CheckHelpBubbleBodyText(
                     IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_BODY_TEXT),
                 CheckHelpBubbleDefaultButtonText(IDS_TUTORIAL_NEXT_BUTTON),
+                PressHelpBubbleDefaultButton())),
+
+      // Step 4: Search box.
+      InAnyContext(
+          Steps(WaitForHelpBubble(),
+                CheckHelpBubbleBodyText(
+                    IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_BODY_TEXT),
+                CheckHelpBubbleDefaultButtonText(IDS_TUTORIAL_NEXT_BUTTON),
                 PressHelpBubbleDefaultButton()))
 
       // TODO(http://b:275616974): Implement after registering views.
-      // Step 4: Search box.
       // Step 5: Settings app.
       // Step 6: Explore app.
   );
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 3b037b4..30574ff 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -121,10 +121,6 @@
 
 using WebExposedIsolationLevel = content::WebExposedIsolationLevel;
 
-using content::NavigationController;
-using content::NavigationEntry;
-using content::WebContents;
-
 namespace chrome {
 
 namespace {
@@ -1179,7 +1175,8 @@
   command_updater_.UpdateCommandEnabled(IDC_USE_SYSTEM_TITLE_BAR,
                                         use_system_title_bar);
 #endif
-  command_updater_.UpdateCommandEnabled(IDC_OPEN_IN_PWA_WINDOW, true);
+  command_updater_.UpdateCommandEnabled(IDC_OPEN_IN_PWA_WINDOW,
+                                        web_app::CanPopOutWebApp(profile()));
 
   // Page-related commands
   command_updater_.UpdateCommandEnabled(IDC_MANAGE_PASSWORDS_FOR_PAGE, true);
@@ -1198,11 +1195,13 @@
   command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, CanOpenFile(browser_));
   UpdateCommandsForDevTools();
   command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager());
+  command_updater_.UpdateCommandEnabled(IDC_PROFILE_MENU_IN_APP_MENU, true);
   command_updater_.UpdateCommandEnabled(
       IDC_SHOW_HISTORY, (!guest_session && !profile()->IsSystemProfile()));
   command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
   command_updater_.UpdateCommandEnabled(IDC_FIND_AND_EDIT_MENU, true);
-  command_updater_.UpdateCommandEnabled(IDC_PROFILE_MENU_IN_APP_MENU, true);
+  command_updater_.UpdateCommandEnabled(IDC_SEND_TAB_TO_SELF, false);
+  command_updater_.UpdateCommandEnabled(IDC_QRCODE_GENERATOR, false);
   command_updater_.UpdateCommandEnabled(IDC_PASSWORDS_AND_AUTOFILL_MENU,
                                         !guest_session);
   command_updater_.UpdateCommandEnabled(IDC_SHOW_PASSWORD_MANAGER,
@@ -1255,7 +1254,7 @@
   const bool is_web_app_or_custom_tab = IsWebAppOrCustomTab();
   const bool enable_copy_url =
       is_web_app_or_custom_tab ||
-      sharing_hub::SharingHubOmniboxEnabled(browser_->profile());
+      !sharing_hub::SharingIsDisabledByPolicy(browser_->profile());
   command_updater_.UpdateCommandEnabled(IDC_COPY_URL, enable_copy_url);
   command_updater_.UpdateCommandEnabled(IDC_WEB_APP_SETTINGS,
                                         is_web_app_or_custom_tab);
@@ -1424,7 +1423,7 @@
   if (is_locked_fullscreen_)
     return;
 
-  WebContents* current_web_contents =
+  content::WebContents* current_web_contents =
       browser_->tab_strip_model()->GetActiveWebContents();
   if (!current_web_contents)  // May be NULL during tab restore.
     return;
@@ -1466,10 +1465,11 @@
   command_updater_.UpdateCommandEnabled(IDC_INSTALL_PWA, can_create_web_app);
   command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUT,
                                         can_create_web_app);
-  // Note that additional logic in AppMenuModel::Build() controls the presence
-  // of this command.
-  command_updater_.UpdateCommandEnabled(IDC_OPEN_IN_PWA_WINDOW,
-                                        web_app::CanPopOutWebApp(profile()));
+
+  command_updater_.UpdateCommandEnabled(IDC_SEND_TAB_TO_SELF,
+                                        CanSendTabToSelf(browser_));
+  command_updater_.UpdateCommandEnabled(IDC_QRCODE_GENERATOR,
+                                        CanGenerateQrCode(browser_));
 
   bool is_isolated_app = current_web_contents->GetPrimaryMainFrame()
                              ->GetWebExposedIsolationLevel() >=
@@ -1494,7 +1494,8 @@
 }
 
 void BrowserCommandController::UpdateCommandsForZoomState() {
-  WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents();
+  content::WebContents* contents =
+      browser_->tab_strip_model()->GetActiveWebContents();
   if (!contents)
     return;
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents));
@@ -1628,14 +1629,12 @@
   command_updater_.UpdateCommandEnabled(IDC_CHROME_TIPS, show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_CHROME_WHATS_NEW, show_main_ui);
 #endif
-  command_updater_.UpdateCommandEnabled(IDC_QRCODE_GENERATOR, show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_CONTENT_CONTEXT_SHARING_SUBMENU,
                                         show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_SHARING_HUB, show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_SHARING_HUB_SCREENSHOT,
                                         show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_SEND_TAB_TO_SELF, show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_SHOW_MANAGEMENT_PAGE, true);
   command_updater_.UpdateCommandEnabled(IDC_FOLLOW, show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_UNFOLLOW, show_main_ui);
diff --git a/chrome/browser/ui/browser_command_controller_unittest.cc b/chrome/browser/ui/browser_command_controller_unittest.cc
index 4f5f740..ce5b25c 100644
--- a/chrome/browser/ui/browser_command_controller_unittest.cc
+++ b/chrome/browser/ui/browser_command_controller_unittest.cc
@@ -382,7 +382,6 @@
     { IDC_VIEW_PASSWORDS,          true,     false,     false,     false    },
     { IDC_ABOUT,                   true,     false,     false,     false    },
     { IDC_SHOW_APP_MENU,           true,     false,     false,     false    },
-    { IDC_SEND_TAB_TO_SELF,        true,     false,     false,     false    },
     { IDC_FULLSCREEN,              true,     false,     true,      true     },
     { IDC_CLOSE_TAB,               true,     true,      true,      false    },
     { IDC_CLOSE_WINDOW,            true,     true,      true,      false    },
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index ff56bd1..60f65d1 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -43,11 +43,13 @@
 #include "chrome/browser/reading_list/reading_list_model_factory.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h"
 #include "chrome/browser/sessions/session_service.h"
 #include "chrome/browser/sessions/session_service_base.h"
 #include "chrome/browser/sessions/session_service_factory.h"
 #include "chrome/browser/sessions/session_service_lookup.h"
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
+#include "chrome/browser/sharing_hub/sharing_hub_features.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/ui/accelerator_utils.h"
 #include "chrome/browser/ui/autofill/payments/iban_bubble_controller_impl.h"
@@ -1447,12 +1449,27 @@
       ->ShowManagePasswordsBubble(!controller->IsAutomaticallyOpeningBubble());
 }
 
+bool CanSendTabToSelf(const Browser* browser) {
+  return send_tab_to_self::ShouldDisplayEntryPoint(
+      browser->tab_strip_model()->GetActiveWebContents());
+}
+
 void SendTabToSelfFromPageAction(Browser* browser) {
   WebContents* web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
   send_tab_to_self::ShowBubble(web_contents);
 }
 
+bool CanGenerateQrCode(const Browser* browser) {
+  return !sharing_hub::SharingIsDisabledByPolicy(browser->profile()) &&
+         qrcode_generator::QRCodeGeneratorBubbleController::
+             IsGeneratorAvailable(browser->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetController()
+                                      .GetLastCommittedEntry()
+                                      ->GetURL());
+}
+
 void GenerateQRCodeFromPageAction(Browser* browser) {
   WebContents* web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h
index 9862ab53..4037866 100644
--- a/chrome/browser/ui/browser_commands.h
+++ b/chrome/browser/ui/browser_commands.h
@@ -176,7 +176,9 @@
 void ShowVirtualCardEnrollBubble(Browser* browser);
 void Translate(Browser* browser);
 void ManagePasswordsForPage(Browser* browser);
+bool CanSendTabToSelf(const Browser* browser);
 void SendTabToSelfFromPageAction(Browser* browser);
+bool CanGenerateQrCode(const Browser* browser);
 void GenerateQRCodeFromPageAction(Browser* browser);
 void SharingHubFromPageAction(Browser* browser);
 void ScreenshotCaptureFromPageAction(Browser* browser);
diff --git a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm
index b104d9b6..a39e875 100644
--- a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm
+++ b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm
@@ -4,6 +4,7 @@
 
 #import "chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.h"
 
+#include "base/apple/owned_objc.h"
 #include "base/check.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/global_keyboard_shortcuts_mac.h"
@@ -43,7 +44,8 @@
   // when the focused view is not a RenderWidgetHostView, which is why this
   // logic is necessary. Duplicating the logic adds a bit of redundant work,
   // but doesn't cause problems.
-  content::NativeWebKeyboardEvent keyboard_event(event);
+  content::NativeWebKeyboardEvent keyboard_event(
+      (base::apple::OwnedNSEvent(event)));
   ui::Accelerator accelerator =
       ui::GetAcceleratorFromNativeWebKeyboardEvent(keyboard_event);
   auto* bridge =
@@ -110,7 +112,7 @@
   bool will_execute = false;
   const bool kIsBeforeFirstResponder = true;
 
-  // See if this command will excute on the window bridge side.
+  // See if this command will execute on the window bridge side.
   bridge->host()->WillExecuteCommand(result.chrome_command,
                                      WindowOpenDisposition::CURRENT_TAB,
                                      kIsBeforeFirstResponder, &will_execute);
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc
index d8564a0c..791675750 100644
--- a/chrome/browser/ui/color/chrome_color_mixer.cc
+++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -722,10 +722,10 @@
   mixer[kColorReadAnythingBackground] = {
       dark_mode ? kColorReadAnythingBackgroundDark
                 : kColorReadAnythingBackgroundLight};
-  mixer[kColorReadAnythingBackgroundBlue] = {gfx::kGoogleBlue200};
+  mixer[kColorReadAnythingBackgroundBlue] = {gfx::kGoogleBlue100};
   mixer[kColorReadAnythingBackgroundDark] = {gfx::kGoogleGrey900};
   mixer[kColorReadAnythingBackgroundLight] = {gfx::kGoogleGrey100};
-  mixer[kColorReadAnythingBackgroundYellow] = {gfx::kGoogleYellow200};
+  mixer[kColorReadAnythingBackgroundYellow] = {gfx::kGoogleYellow100};
   mixer[kColorReadAnythingForeground] = {
       dark_mode ? kColorReadAnythingForegroundDark
                 : kColorReadAnythingForegroundLight};
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
index 4cbb2039..4a11b74 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -834,10 +834,19 @@
 #endif  // BUILDFLAG(IS_MAC)
 };
 
-// Tests FullscreenController support of multi-screen features.
+// Tests fullscreen with multi-screen features from the Window Management API.
 // Sites with the Window Management permission can request fullscreen on a
 // specific screen, move fullscreen windows to different displays, and more.
-class MultiScreenFullscreenControllerInteractiveTest
+// Tests must run in series to manage virtual displays on supported platforms.
+// Use 2+ physical displays to run locally with --gtest_also_run_disabled_tests.
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
+#define MAYBE_MultiScreenFullscreenControllerInteractiveTest \
+  MultiScreenFullscreenControllerInteractiveTest
+#else
+#define MAYBE_MultiScreenFullscreenControllerInteractiveTest \
+  DISABLED_MultiScreenFullscreenControllerInteractiveTest
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
+class MAYBE_MultiScreenFullscreenControllerInteractiveTest
     : public FullscreenControllerInteractiveTest {
  public:
   void SetUp() override {
@@ -977,7 +986,7 @@
 #define MAYBE_SeparateDisplay DISABLED_SeparateDisplay
 #endif
 // Test requesting fullscreen on a separate display.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_SeparateDisplay) {
   SetUpWindowManagementTab();
   const gfx::Rect original_bounds = browser()->window()->GetBounds();
@@ -1003,7 +1012,7 @@
 #define MAYBE_SeparateDisplayMaximized DISABLED_SeparateDisplayMaximized
 #endif
 // Test requesting fullscreen on a separate display from a maximized window.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_SeparateDisplayMaximized) {
   SetUpWindowManagementTab();
   const gfx::Rect original_bounds = browser()->window()->GetBounds();
@@ -1039,7 +1048,7 @@
 #define MAYBE_SameDisplayAndSwap DISABLED_SameDisplayAndSwap
 #endif
 // Test requesting fullscreen on the current display and then swapping displays.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_SameDisplayAndSwap) {
   SetUpWindowManagementTab();
   const gfx::Rect original_bounds = browser()->window()->GetBounds();
@@ -1070,7 +1079,7 @@
 #endif
 // Test requesting fullscreen on the current display and then swapping displays
 // from a maximized window.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_SameDisplayAndSwapMaximized) {
   SetUpWindowManagementTab();
   const gfx::Rect original_bounds = browser()->window()->GetBounds();
@@ -1114,7 +1123,7 @@
 // Test requesting browser fullscreen on current display, launching
 // tab-fullscreen on a different display, and then closing tab-fullscreen to
 // restore browser-fullscreen on the original display.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_BrowserFullscreenContentFullscreenSwapDisplay) {
   SetUpWindowManagementTab();
 
@@ -1151,7 +1160,7 @@
 #define MAYBE_SeparateDisplayAndSwap DISABLED_SeparateDisplayAndSwap
 #endif
 // Test requesting fullscreen on a separate display and then swapping displays.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_SeparateDisplayAndSwap) {
   SetUpWindowManagementTab();
   const gfx::Rect original_bounds = browser()->window()->GetBounds();
@@ -1180,7 +1189,7 @@
 #define MAYBE_SwapShowsBubble DISABLED_SwapShowsBubble
 #endif
 // Test requesting fullscreen on the current display and then swapping displays.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_SwapShowsBubble) {
   SetUpWindowManagementTab();
 
@@ -1219,7 +1228,7 @@
 #define MAYBE_FullscreenOnPermissionGrant FullscreenOnPermissionGrant
 #endif
 // Test requesting fullscreen using the permission grant's transient activation.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_FullscreenOnPermissionGrant) {
   EXPECT_TRUE(embedded_test_server()->Start());
   const GURL url(embedded_test_server()->GetURL("/simple.html"));
@@ -1258,7 +1267,7 @@
 #define MAYBE_OpenPopupWhileFullscreen OpenPopupWhileFullscreen
 #endif
 // Test opening a popup on a separate display while fullscreen.
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_OpenPopupWhileFullscreen) {
   content::WebContents* tab = SetUpWindowManagementTab();
   const display::Display original_display = GetCurrentDisplay(browser());
@@ -1319,7 +1328,7 @@
 // Test requesting fullscreen on a specific screen and opening a cross-screen
 // popup window from one gesture. Check the expected window activation pattern.
 // https://w3c.github.io/window-placement/#usage-overview-initiate-multi-screen-experiences
-IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
+IN_PROC_BROWSER_TEST_F(MAYBE_MultiScreenFullscreenControllerInteractiveTest,
                        MAYBE_FullscreenCompanionWindow) {
   content::WebContents* tab = SetUpWindowManagementTab();
 
@@ -1384,11 +1393,20 @@
 }
 
 // Tests FullscreenController support for fullscreen on screenschange events.
-class FullscreenOnScreensChangeFullscreenControllerInteractiveTest
-    : public MultiScreenFullscreenControllerInteractiveTest,
+// Tests must run in series to manage virtual displays on supported platforms.
+// Use 2+ physical displays to run locally with --gtest_also_run_disabled_tests.
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
+#define MAYBE_FullscreenOnScreensChangeFullscreenControllerInteractiveTest \
+  FullscreenOnScreensChangeFullscreenControllerInteractiveTest
+#else
+#define MAYBE_FullscreenOnScreensChangeFullscreenControllerInteractiveTest \
+  DISABLED_FullscreenOnScreensChangeFullscreenControllerInteractiveTest
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
+class MAYBE_FullscreenOnScreensChangeFullscreenControllerInteractiveTest
+    : public MAYBE_MultiScreenFullscreenControllerInteractiveTest,
       public testing::WithParamInterface<bool> {
  public:
-  FullscreenOnScreensChangeFullscreenControllerInteractiveTest() {
+  MAYBE_FullscreenOnScreensChangeFullscreenControllerInteractiveTest() {
     feature_list_.InitWithFeatureState(
         blink::features::kWindowPlacementFullscreenOnScreensChange, GetParam());
   }
@@ -1409,7 +1427,7 @@
 #endif
 // Tests async fullscreen requests on screenschange event.
 IN_PROC_BROWSER_TEST_P(
-    FullscreenOnScreensChangeFullscreenControllerInteractiveTest,
+    MAYBE_FullscreenOnScreensChangeFullscreenControllerInteractiveTest,
     MAYBE_FullscreenOnScreensChange) {
   content::WebContents* tab = SetUpWindowManagementTab();
 
@@ -1442,5 +1460,5 @@
 
 INSTANTIATE_TEST_SUITE_P(
     ,
-    FullscreenOnScreensChangeFullscreenControllerInteractiveTest,
+    MAYBE_FullscreenOnScreensChangeFullscreenControllerInteractiveTest,
     ::testing::Bool());
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc
index 50796d5..9d926b7 100644
--- a/chrome/browser/ui/extensions/application_launch.cc
+++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -283,27 +283,17 @@
   return contents;
 }
 
-WebContents* OpenEnabledApplication(Profile* profile,
-                                    apps::AppLaunchParams&& params) {
-  const Extension* extension = GetExtension(profile, params);
-  if (!extension) {
-    return nullptr;
-  }
-
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  if (!profile->IsMainProfile()) {
-    return nullptr;
-  }
-#endif
-
+WebContents* OpenEnabledApplicationHelper(Profile* profile,
+                                          const apps::AppLaunchParams& params,
+                                          const Extension& extension) {
   WebContents* tab = nullptr;
   ExtensionPrefs* prefs = ExtensionPrefs::Get(profile);
-  prefs->SetActiveBit(extension->id(), true);
+  prefs->SetActiveBit(extension.id(), true);
   bool supports_web_file_handlers =
       extensions::WebFileHandlers::SupportsWebFileHandlers(
-          extension->manifest_version());
+          extension.manifest_version());
 
-  if (CanLaunchViaEvent(extension) && !supports_web_file_handlers) {
+  if (CanLaunchViaEvent(&extension) && !supports_web_file_handlers) {
     // When launching an app with a command line, there might be a file path to
     // work with that command line, so
     // LaunchPlatformAppWithCommandLineAndLaunchId should be called to handle
@@ -314,17 +304,17 @@
     if (params.command_line.GetArgs().empty() && !params.launch_files.empty()) {
       if (params.intent && params.intent->activity_name) {
         apps::LaunchPlatformAppWithFileHandler(
-            profile, extension, params.intent->activity_name.value(),
+            profile, &extension, params.intent->activity_name.value(),
             params.launch_files);
       } else {
-        apps::LaunchPlatformAppWithFilePaths(profile, extension,
+        apps::LaunchPlatformAppWithFilePaths(profile, &extension,
                                              params.launch_files);
       }
       return nullptr;
     }
 
     apps::LaunchPlatformAppWithCommandLineAndLaunchId(
-        profile, extension, params.launch_id, params.command_line,
+        profile, &extension, params.launch_id, params.command_line,
         params.current_directory,
         apps::GetAppLaunchSource(params.launch_source));
     return nullptr;
@@ -337,14 +327,14 @@
   if (supports_web_file_handlers && params.intent->activity_name.has_value()) {
     // `params.intent->activity_name` is actually the `action` url set in the
     // manifest of the extension.
-    url = extension->GetResourceURL(params.intent->activity_name.value());
+    url = extension.GetResourceURL(params.intent->activity_name.value());
   } else {
-    url = UrlForExtension(extension, profile, params);
+    url = UrlForExtension(&extension, profile, params);
   }
 
   // Record v1 app launch. Platform app launch is recorded when dispatching
   // the onLaunched event.
-  prefs->SetLastLaunchTime(extension->id(), base::Time::Now());
+  prefs->SetLastLaunchTime(extension.id(), base::Time::Now());
 
   switch (params.container) {
     case apps::LaunchContainer::kLaunchContainerNone: {
@@ -366,17 +356,97 @@
   }
 
   if (supports_web_file_handlers) {
-    extensions::EnqueueLaunchParamsInWebContents(tab, *extension, url,
+    extensions::EnqueueLaunchParamsInWebContents(tab, extension, url,
                                                  params.launch_files);
   }
 
   return tab;
 }
 
+// Launch an application if `launch_type` is `multiple_clients`. First find a
+// matching handler for the intent. Return `web_contents` if a launch occurred.
+WebContents* MaybeOpenApplicationForLaunchTypeMultipleClients(
+    const extensions::api::file_handlers::FileHandler& handler,
+    const apps::AppLaunchParams& params,
+    Profile* profile,
+    const Extension& extension) {
+  // Find the matching file_handler definition based on the handler action.
+  if (handler.action != params.intent->activity_name) {
+    return nullptr;
+  }
+
+  // Determine if this is single-client (default) or multiple-clients.
+  if (handler.launch_type != "multiple-clients") {
+    return nullptr;
+  }
+
+  // Open a new window with a tab for each file being opened.
+  WebContents* web_contents = nullptr;
+  for (const auto& file : params.launch_files) {
+    std::vector<base::FilePath> files({file});
+
+    // Clone intent to clone params.
+    apps::IntentPtr intent =
+        std::make_unique<apps::Intent>(params.intent->action);
+    intent->mime_type = params.intent->mime_type;
+    intent->url = params.intent->url;
+    intent->activity_name = params.intent->activity_name;
+    apps::AppLaunchParams file_params(params.app_id, params.container,
+                                      params.disposition, params.launch_source,
+                                      params.display_id, files, intent);
+
+    // Return the last web_contents to the caller. The web_contents is
+    // only currently used for Arc and therefore WFH doesn't need any of them.
+    // This code path can only be reached by Web File Handlers, not Arc.
+    web_contents =
+        OpenEnabledApplicationHelper(profile, file_params, extension);
+  }
+  return web_contents;
+}
+
+WebContents* OpenEnabledApplication(Profile* profile,
+                                    const apps::AppLaunchParams& params) {
+  const Extension* extension = GetExtension(profile, params);
+  if (!extension) {
+    return nullptr;
+  }
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  if (!profile->IsMainProfile()) {
+    return nullptr;
+  }
+#endif
+
+  // Support for multiple-clients in Web File Handlers. Launch if this is a
+  // multi-client launch. Otherwise fallback to `OpenEnabledApplicationHelper`.
+  if (extensions::WebFileHandlers::SupportsWebFileHandlers(
+          extension->manifest_version())) {
+    auto* handlers = extensions::WebFileHandlers::GetFileHandlers(*extension);
+    if (!handlers) {
+      return nullptr;
+    }
+
+    // Find a matching manifest file handler action for the intent. If there's a
+    // match, return early with the last web_contents opened.
+    WebContents* web_contents = nullptr;
+    for (const auto& handler : *handlers) {
+      web_contents = MaybeOpenApplicationForLaunchTypeMultipleClients(
+          handler, params, profile, *extension);
+      if (web_contents) {
+        return web_contents;
+      }
+    }
+  }
+
+  // This is the default case. Alternatively, Web File Handlers could also reach
+  // this point if they have a single-client launch_type, which is the default.
+  return OpenEnabledApplicationHelper(profile, params, *extension);
+}
+
 }  // namespace
 
 WebContents* OpenApplication(Profile* profile, apps::AppLaunchParams&& params) {
-  return OpenEnabledApplication(profile, std::move(params));
+  return OpenEnabledApplication(profile, params);
 }
 
 Browser* CreateApplicationWindow(Profile* profile,
diff --git a/chrome/browser/ui/global_media_controls/live_translate_combobox_model.cc b/chrome/browser/ui/global_media_controls/live_translate_combobox_model.cc
new file mode 100644
index 0000000..b1763f01
--- /dev/null
+++ b/chrome/browser/ui/global_media_controls/live_translate_combobox_model.cc
@@ -0,0 +1,55 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/global_media_controls/live_translate_combobox_model.h"
+
+#include <vector>
+
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/live_caption/pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "ui/base/l10n/l10n_util.h"
+
+LiveTranslateComboboxModel::LiveTranslateComboboxModel(Profile* profile)
+    : profile_(profile) {
+  std::vector<translate::TranslateLanguageInfo> language_list;
+  translate::TranslatePrefs::GetLanguageInfoList(
+      g_browser_process->GetApplicationLocale(), true, &language_list);
+
+  for (const auto& language : language_list) {
+    if (language.supports_translate &&
+        language.code == l10n_util::GetLanguage(language.code)) {
+      languages_.push_back(language);
+    }
+  }
+}
+
+LiveTranslateComboboxModel::~LiveTranslateComboboxModel() = default;
+
+size_t LiveTranslateComboboxModel::GetItemCount() const {
+  return languages_.size();
+}
+
+std::u16string LiveTranslateComboboxModel::GetItemAt(size_t index) const {
+  return base::UTF8ToUTF16(languages_[index].display_name);
+}
+
+absl::optional<size_t> LiveTranslateComboboxModel::GetDefaultIndex() const {
+  std::string target_language =
+      profile_->GetPrefs()->GetString(prefs::kLiveTranslateTargetLanguageCode);
+  for (size_t i = 0; i < languages_.size(); i++) {
+    if (target_language == languages_[i].code) {
+      return i;
+    }
+  }
+
+  return 0;
+}
+
+void LiveTranslateComboboxModel::UpdateTargetLanguageIndex(int index) {
+  profile_->GetPrefs()->SetString(prefs::kLiveTranslateTargetLanguageCode,
+                                  languages_[index].code);
+}
diff --git a/chrome/browser/ui/global_media_controls/live_translate_combobox_model.h b/chrome/browser/ui/global_media_controls/live_translate_combobox_model.h
new file mode 100644
index 0000000..0215c42
--- /dev/null
+++ b/chrome/browser/ui/global_media_controls/live_translate_combobox_model.h
@@ -0,0 +1,41 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_COMBOBOX_MODEL_H_
+#define CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_COMBOBOX_MODEL_H_
+
+#include <memory>
+#include <string>
+
+#include "base/memory/raw_ptr.h"
+#include "components/translate/core/browser/translate_prefs.h"
+#include "ui/base/models/combobox_model.h"
+
+class Profile;
+
+// The model for the combobox to select a language. This is used by the global
+// media control to select a Live Translate target language.
+class LiveTranslateComboboxModel : public ui::ComboboxModel {
+ public:
+  explicit LiveTranslateComboboxModel(Profile* profile);
+  LiveTranslateComboboxModel(const LiveTranslateComboboxModel&) = delete;
+  LiveTranslateComboboxModel& operator=(const LiveTranslateComboboxModel&) =
+      delete;
+
+  ~LiveTranslateComboboxModel() override;
+
+  // Overridden from ui::ComboboxModel:
+  size_t GetItemCount() const override;
+  std::u16string GetItemAt(size_t index) const override;
+  absl::optional<size_t> GetDefaultIndex() const override;
+
+  void UpdateTargetLanguageIndex(int index);
+
+ private:
+  std::vector<translate::TranslateLanguageInfo> languages_;
+
+  const raw_ptr<Profile> profile_;
+};
+
+#endif  // CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_COMBOBOX_MODEL_H_
diff --git a/chrome/browser/ui/managed_ui.cc b/chrome/browser/ui/managed_ui.cc
index 140fa0c..6dfdc51 100644
--- a/chrome/browser/ui/managed_ui.cc
+++ b/chrome/browser/ui/managed_ui.cc
@@ -25,6 +25,7 @@
 #include "components/policy/core/common/management/management_service.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "components/signin/public/identity_manager/account_info.h"
+#include "components/supervised_user/core/common/buildflags.h"
 #include "components/vector_icons/vector_icons.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/passwords/settings/password_manager_porter_unittest.cc b/chrome/browser/ui/passwords/settings/password_manager_porter_unittest.cc
index 536acb4..d912b05 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_porter_unittest.cc
+++ b/chrome/browser/ui/passwords/settings/password_manager_porter_unittest.cc
@@ -152,7 +152,7 @@
 class FakeCancellingSelectFileDialogFactory
     : public ui::SelectFileDialogFactory {
  public:
-  FakeCancellingSelectFileDialogFactory() {}
+  FakeCancellingSelectFileDialogFactory() = default;
 
   TestSelectFileDialogFactory& operator=(const TestSelectFileDialogFactory&) =
       delete;
diff --git a/chrome/browser/ui/performance_controls/resource_usage_tab_helper.cc b/chrome/browser/ui/performance_controls/resource_usage_tab_helper.cc
new file mode 100644
index 0000000..ad7691b
--- /dev/null
+++ b/chrome/browser/ui/performance_controls/resource_usage_tab_helper.cc
@@ -0,0 +1,21 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/performance_controls/resource_usage_tab_helper.h"
+
+#include "content/public/browser/web_contents.h"
+
+ResourceUsageTabHelper::~ResourceUsageTabHelper() = default;
+
+void ResourceUsageTabHelper::PrimaryPageChanged(content::Page&) {
+  // Reset memory usage count when we navigate to another site since the
+  // memory usage reported will be outdated.
+  memory_usage_bytes_ = 0;
+}
+
+ResourceUsageTabHelper::ResourceUsageTabHelper(content::WebContents* contents)
+    : content::WebContentsObserver(contents),
+      content::WebContentsUserData<ResourceUsageTabHelper>(*contents) {}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(ResourceUsageTabHelper);
diff --git a/chrome/browser/ui/performance_controls/resource_usage_tab_helper.h b/chrome/browser/ui/performance_controls/resource_usage_tab_helper.h
new file mode 100644
index 0000000..b7d3a21
--- /dev/null
+++ b/chrome/browser/ui/performance_controls/resource_usage_tab_helper.h
@@ -0,0 +1,44 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_PERFORMANCE_CONTROLS_RESOURCE_USAGE_TAB_HELPER_H_
+#define CHROME_BROWSER_UI_PERFORMANCE_CONTROLS_RESOURCE_USAGE_TAB_HELPER_H_
+
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace content {
+class WebContents;
+}  // namespace content
+
+// Per-tab class to keep track of current memory usage for each tab.
+class ResourceUsageTabHelper
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<ResourceUsageTabHelper> {
+ public:
+  ResourceUsageTabHelper(const ResourceUsageTabHelper&) = delete;
+  ResourceUsageTabHelper& operator=(const ResourceUsageTabHelper&) = delete;
+
+  ~ResourceUsageTabHelper() override;
+
+  // content::WebContentsObserver
+  void PrimaryPageChanged(content::Page& page) override;
+
+  uint64_t GetMemoryUsageInBytes() { return memory_usage_bytes_; }
+
+  void SetMemoryUsageInBytes(uint64_t memory_usage_bytes) {
+    memory_usage_bytes_ = memory_usage_bytes;
+  }
+
+ private:
+  friend class content::WebContentsUserData<ResourceUsageTabHelper>;
+  explicit ResourceUsageTabHelper(content::WebContents* contents);
+
+  uint64_t memory_usage_bytes_ = 0;
+
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+#endif  // CHROME_BROWSER_UI_PERFORMANCE_CONTROLS_RESOURCE_USAGE_TAB_HELPER_H_
diff --git a/chrome/browser/ui/performance_controls/resource_usage_tab_helper_unittest.cc b/chrome/browser/ui/performance_controls/resource_usage_tab_helper_unittest.cc
new file mode 100644
index 0000000..54fc18a5
--- /dev/null
+++ b/chrome/browser/ui/performance_controls/resource_usage_tab_helper_unittest.cc
@@ -0,0 +1,36 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/performance_controls/resource_usage_tab_helper.h"
+
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "url/gurl.h"
+
+namespace {
+constexpr char kTestDomain[] = "http://foo.bar";
+constexpr uint64_t kTestMemoryUsageBytes = 100000;
+}  // namespace
+
+class ResourceUsageTabHelperTest : public ChromeRenderViewHostTestHarness {
+ protected:
+  ResourceUsageTabHelper* InitializeTabHelper() {
+    ResourceUsageTabHelper::CreateForWebContents(web_contents());
+    return ResourceUsageTabHelper::FromWebContents(web_contents());
+  }
+};
+
+// Return memory usage that was set on the tab helper.
+TEST_F(ResourceUsageTabHelperTest, ReturnsMemoryUsageInBytes) {
+  auto* tab_helper = InitializeTabHelper();
+  tab_helper->SetMemoryUsageInBytes(kTestMemoryUsageBytes);
+  EXPECT_EQ(tab_helper->GetMemoryUsageInBytes(), kTestMemoryUsageBytes);
+}
+
+// Clears memory usage on navigate.
+TEST_F(ResourceUsageTabHelperTest, ClearsMemoryUsageOnNavigate) {
+  auto* tab_helper = InitializeTabHelper();
+  tab_helper->SetMemoryUsageInBytes(kTestMemoryUsageBytes);
+  NavigateAndCommit(GURL(kTestDomain));
+  EXPECT_EQ(tab_helper->GetMemoryUsageInBytes(), 0u);
+}
diff --git a/chrome/browser/ui/serial/serial_chooser_controller.cc b/chrome/browser/ui/serial/serial_chooser_controller.cc
index 0401bc32..83e11860 100644
--- a/chrome/browser/ui/serial/serial_chooser_controller.cc
+++ b/chrome/browser/ui/serial/serial_chooser_controller.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/containers/contains.h"
 #include "base/files/file_path.h"
 #include "base/functional/bind.h"
 #include "base/metrics/histogram_macros.h"
@@ -21,15 +22,61 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_contents.h"
+#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
+#include "services/device/public/cpp/bluetooth/bluetooth_utils.h"
+#include "services/device/public/mojom/serial.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 
+namespace {
+
+using ::device::mojom::SerialPortType;
+
+bool FilterMatchesPort(const blink::mojom::SerialPortFilter& filter,
+                       const device::mojom::SerialPortInfo& port) {
+  if (filter.bluetooth_service_class_id) {
+    if (!port.bluetooth_service_class_id) {
+      return false;
+    }
+    return device::BluetoothUUID(*port.bluetooth_service_class_id) ==
+           device::BluetoothUUID(*filter.bluetooth_service_class_id);
+  }
+  if (!filter.has_vendor_id) {
+    return true;
+  }
+  if (!port.has_vendor_id || port.vendor_id != filter.vendor_id) {
+    return false;
+  }
+  if (!filter.has_product_id) {
+    return true;
+  }
+  return port.has_product_id && port.product_id == filter.product_id;
+}
+
+bool BluetoothPortIsAllowed(
+    const std::vector<::device::BluetoothUUID>& allowed_ids,
+    const device::mojom::SerialPortInfo& port) {
+  if (!port.bluetooth_service_class_id) {
+    return true;
+  }
+  // Serial Port Profile is allowed by default.
+  if (*port.bluetooth_service_class_id == device::GetSerialPortProfileUUID()) {
+    return true;
+  }
+  return base::Contains(allowed_ids, port.bluetooth_service_class_id.value());
+}
+
+}  // namespace
+
 SerialChooserController::SerialChooserController(
     content::RenderFrameHost* render_frame_host,
     std::vector<blink::mojom::SerialPortFilterPtr> filters,
+    std::vector<::device::BluetoothUUID> allowed_bluetooth_service_class_ids,
     content::SerialChooser::Callback callback)
     : ChooserController(CreateChooserTitle(render_frame_host,
                                            IDS_SERIAL_PORT_CHOOSER_PROMPT)),
       filters_(std::move(filters)),
+      allowed_bluetooth_service_class_ids_(
+          std::move(allowed_bluetooth_service_class_ids)),
       callback_(std::move(callback)),
       initiator_document_(render_frame_host->GetWeakDocumentPtr()) {
   origin_ = render_frame_host->GetMainFrame()->GetLastCommittedOrigin();
@@ -50,6 +97,12 @@
     RunCallback(/*port=*/nullptr);
 }
 
+const device::mojom::SerialPortInfo& SerialChooserController::GetPortForTest(
+    size_t index) const {
+  CHECK_LT(index, ports_.size());
+  return *ports_[index];
+}
+
 bool SerialChooserController::ShouldShowHelpButton() const {
   return true;
 }
@@ -73,6 +126,22 @@
   return ports_.size();
 }
 
+// Does the Bluetooth service class ID need to be displayed along with the
+// display name for the provided `port`? The goal is to display the shortest
+// name necessary to identify the port. When two (or more) ports from the same
+// device are selected, the service class ID is added to disambiguate the two
+// ports.
+bool SerialChooserController::DisplayServiceClassId(
+    const device::mojom::SerialPortInfo& port) const {
+  CHECK_EQ(port.type, device::mojom::SerialPortType::BLUETOOTH_CLASSIC_RFCOMM);
+  return base::ranges::any_of(
+      ports_, [&port](const device::mojom::SerialPortInfoPtr& p) {
+        return p->token != port.token &&
+               p->type == SerialPortType::BLUETOOTH_CLASSIC_RFCOMM &&
+               p->path == port.path;
+      });
+}
+
 std::u16string SerialChooserController::GetOption(size_t index) const {
   DCHECK_LT(index, ports_.size());
   const device::mojom::SerialPortInfo& port = *ports_[index];
@@ -82,13 +151,27 @@
   // serial port and to differentiate between ports with similar display names.
   std::u16string display_path = port.path.BaseName().LossyDisplayName();
 
-  if (port.display_name && !port.display_name->empty()) {
-    return l10n_util::GetStringFUTF16(IDS_SERIAL_PORT_CHOOSER_NAME_WITH_PATH,
-                                      base::UTF8ToUTF16(*port.display_name),
+  if (!port.display_name || port.display_name->empty()) {
+    return l10n_util::GetStringFUTF16(IDS_SERIAL_PORT_CHOOSER_PATH_ONLY,
                                       display_path);
   }
 
-  return l10n_util::GetStringFUTF16(IDS_SERIAL_PORT_CHOOSER_PATH_ONLY,
+  if (port.type == device::mojom::SerialPortType::BLUETOOTH_CLASSIC_RFCOMM) {
+    if (DisplayServiceClassId(port)) {
+      // Using UUID in place of path is identical for translation purposes
+      // so using IDS_SERIAL_PORT_CHOOSER_NAME_WITH_PATH is ok.
+      device::BluetoothUUID device_uuid(*port.bluetooth_service_class_id);
+      return l10n_util::GetStringFUTF16(
+          IDS_SERIAL_PORT_CHOOSER_NAME_WITH_PATH,
+          base::UTF8ToUTF16(*port.display_name),
+          base::UTF8ToUTF16(device_uuid.canonical_value()));
+    }
+    return l10n_util::GetStringFUTF16(IDS_SERIAL_PORT_CHOOSER_PATH_ONLY,
+                                      base::UTF8ToUTF16(*port.display_name));
+  }
+
+  return l10n_util::GetStringFUTF16(IDS_SERIAL_PORT_CHOOSER_NAME_WITH_PATH,
+                                    base::UTF8ToUTF16(*port.display_name),
                                     display_path);
 }
 
@@ -178,6 +261,7 @@
 
 bool SerialChooserController::DisplayDevice(
     const device::mojom::SerialPortInfo& port) const {
+  // TODO(b/276945831): Extend this to include protected Bluetooth services.
   if (SerialBlocklist::Get().IsExcluded(port)) {
     DCHECK(port.has_vendor_id && port.has_product_id);
     AddMessageToConsole(
@@ -192,19 +276,15 @@
     return false;
   }
 
-  if (filters_.empty())
-    return true;
+  if (filters_.empty()) {
+    return BluetoothPortIsAllowed(allowed_bluetooth_service_class_ids_, port);
+  }
 
   for (const auto& filter : filters_) {
-    if (filter->has_vendor_id &&
-        (!port.has_vendor_id || filter->vendor_id != port.vendor_id)) {
-      continue;
+    if (FilterMatchesPort(*filter, port) &&
+        BluetoothPortIsAllowed(allowed_bluetooth_service_class_ids_, port)) {
+      return true;
     }
-    if (filter->has_product_id &&
-        (!port.has_product_id || filter->product_id != port.product_id)) {
-      continue;
-    }
-    return true;
   }
 
   return false;
diff --git a/chrome/browser/ui/serial/serial_chooser_controller.h b/chrome/browser/ui/serial/serial_chooser_controller.h
index 12859e3b..6130abc 100644
--- a/chrome/browser/ui/serial/serial_chooser_controller.h
+++ b/chrome/browser/ui/serial/serial_chooser_controller.h
@@ -31,6 +31,7 @@
   SerialChooserController(
       content::RenderFrameHost* render_frame_host,
       std::vector<blink::mojom::SerialPortFilterPtr> filters,
+      std::vector<::device::BluetoothUUID> allowed_bluetooth_service_class_ids,
       content::SerialChooser::Callback callback);
 
   SerialChooserController(const SerialChooserController&) = delete;
@@ -38,6 +39,8 @@
 
   ~SerialChooserController() override;
 
+  const device::mojom::SerialPortInfo& GetPortForTest(size_t index) const;
+
   // permissions::ChooserController:
   bool ShouldShowHelpButton() const override;
   std::u16string GetNoOptionsText() const override;
@@ -64,8 +67,10 @@
   void AddMessageToConsole(blink::mojom::ConsoleMessageLevel level,
                            const std::string& message) const;
   void RunCallback(device::mojom::SerialPortInfoPtr port);
+  bool DisplayServiceClassId(const device::mojom::SerialPortInfo& port) const;
 
   std::vector<blink::mojom::SerialPortFilterPtr> filters_;
+  std::vector<::device::BluetoothUUID> allowed_bluetooth_service_class_ids_;
   content::SerialChooser::Callback callback_;
   content::WeakDocumentPtr initiator_document_;
   url::Origin origin_;
diff --git a/chrome/browser/ui/serial/serial_chooser_controller_unittest.cc b/chrome/browser/ui/serial/serial_chooser_controller_unittest.cc
index e5bb2ed..a24b9b7 100644
--- a/chrome/browser/ui/serial/serial_chooser_controller_unittest.cc
+++ b/chrome/browser/ui/serial/serial_chooser_controller_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/functional/callback_helpers.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
+#include "base/test/gmock_callback_support.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "build/build_config.h"
@@ -20,15 +21,42 @@
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/permissions/mock_chooser_controller_view.h"
+#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/device/public/cpp/bluetooth/bluetooth_utils.h"
 #include "services/device/public/cpp/test/fake_serial_port_manager.h"
 #include "services/device/public/mojom/serial.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/mojom/serial/serial.mojom.h"
 
-using testing::_;
-using testing::Invoke;
+namespace {
+
+using ::device::BluetoothUUID;
+using ::testing::_;
+using ::testing::Invoke;
+
+constexpr char kBluetoothDevice1Address[] = "00:11:22:33:44:55";
+constexpr char16_t kBluetoothDevice1Name[] = u"Bluetooth #1";
+constexpr char kBluetoothDevice2Address[] = "11:22:33:44:55:66";
+constexpr char16_t kBluetoothDevice2Name[] = u"Bluetooth #2";
+const BluetoothUUID kRandomBluetoothServiceClassId(
+    "34a0fe08-1c1f-4251-879e-2a8c397e56ee");
+
+device::mojom::SerialPortInfoPtr CreateBluetoothPort(
+    const std::string& device_address,
+    const std::u16string& device_name,
+    const BluetoothUUID& service_class_id) {
+  auto port = device::mojom::SerialPortInfo::New();
+  port->token = base::UnguessableToken::Create();
+  port->path = base::FilePath::FromUTF8Unsafe(device_address);
+  port->type = device::mojom::SerialPortType::BLUETOOTH_CLASSIC_RFCOMM;
+  port->bluetooth_service_class_id = service_class_id;
+  port->display_name = base::UTF16ToUTF8(device_name);
+  return port;
+}
+
+}  // namespace
 
 class SerialChooserControllerTest : public ChromeRenderViewHostTestHarness {
  public:
@@ -41,6 +69,18 @@
         ->SetPortManagerForTesting(std::move(port_manager));
   }
 
+  base::UnguessableToken AddBluetoothPort(
+      const std::string& device_address,
+      const std::u16string& device_name,
+      const BluetoothUUID& service_class_id) {
+    auto port =
+        CreateBluetoothPort(device_address, device_name, service_class_id);
+
+    base::UnguessableToken port_token = port->token;
+    port_manager().AddPort(std::move(port));
+    return port_token;
+  }
+
   base::UnguessableToken AddPort(
       const std::string& display_name,
       const base::FilePath& path,
@@ -71,6 +111,7 @@
 
 TEST_F(SerialChooserControllerTest, GetPortsLateResponse) {
   std::vector<blink::mojom::SerialPortFilterPtr> filters;
+  std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids;
 
   bool callback_run = false;
   auto callback = base::BindLambdaForTesting(
@@ -80,7 +121,8 @@
       });
 
   auto controller = std::make_unique<SerialChooserController>(
-      main_rfh(), std::move(filters), std::move(callback));
+      main_rfh(), std::move(filters),
+      std::move(allowed_bluetooth_service_class_ids), std::move(callback));
   controller.reset();
 
   // Allow any tasks posted by |controller| to run, such as asynchronous
@@ -97,8 +139,10 @@
   base::HistogramTester histogram_tester;
 
   std::vector<blink::mojom::SerialPortFilterPtr> filters;
+  std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids;
   auto controller = std::make_unique<SerialChooserController>(
-      main_rfh(), std::move(filters), base::DoNothing());
+      main_rfh(), std::move(filters),
+      std::move(allowed_bluetooth_service_class_ids), base::DoNothing());
 
   permissions::MockChooserControllerView view;
   controller->set_view(&view);
@@ -172,8 +216,10 @@
 
   base::MockCallback<content::SerialChooser::Callback> callback;
   std::vector<blink::mojom::SerialPortFilterPtr> filters;
+  std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids;
   auto controller = std::make_unique<SerialChooserController>(
-      main_rfh(), std::move(filters), callback.Get());
+      main_rfh(), std::move(filters),
+      std::move(allowed_bluetooth_service_class_ids), callback.Get());
 
   permissions::MockChooserControllerView view;
   controller->set_view(&view);
@@ -213,6 +259,9 @@
   base::UnguessableToken port_2 =
       AddPort("Test Port 2", base::FilePath(FILE_PATH_LITERAL("/dev/ttyS1")),
               0x1234, 0x0002);
+  // and a Bluetooth port which should always be ignored for this test.
+  AddBluetoothPort(kBluetoothDevice1Address, kBluetoothDevice1Name,
+                   device::GetSerialPortProfileUUID());
 
   // Create a filter which will select only the first port.
   std::vector<blink::mojom::SerialPortFilterPtr> filters;
@@ -223,8 +272,10 @@
   filter->product_id = 0x0001;
   filters.push_back(std::move(filter));
 
+  std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids;
   auto controller = std::make_unique<SerialChooserController>(
-      main_rfh(), std::move(filters), base::DoNothing());
+      main_rfh(), std::move(filters),
+      std::move(allowed_bluetooth_service_class_ids), base::DoNothing());
 
   permissions::MockChooserControllerView view;
   controller->set_view(&view);
@@ -264,6 +315,194 @@
   }
 }
 
+TEST_F(SerialChooserControllerTest, BluetoothPortFiltered) {
+  base::HistogramTester histogram_tester;
+
+  // Create a wired and a Bluetooth port.
+  base::UnguessableToken port_1 =
+      AddPort("Test Port 1", base::FilePath(FILE_PATH_LITERAL("/dev/ttyS0")),
+              0x1234, 0x0001);
+  base::UnguessableToken bluetooth_port_token =
+      AddBluetoothPort(kBluetoothDevice1Address, kBluetoothDevice1Name,
+                       device::GetSerialPortProfileUUID());
+
+  // Create a filter which will select only the Bluetooth port.
+  std::vector<blink::mojom::SerialPortFilterPtr> filters;
+  auto filter = blink::mojom::SerialPortFilter::New();
+  filter->bluetooth_service_class_id = device::GetSerialPortProfileUUID();
+  filters.push_back(std::move(filter));
+
+  std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids;
+  auto controller = std::make_unique<SerialChooserController>(
+      main_rfh(), std::move(filters),
+      std::move(allowed_bluetooth_service_class_ids), base::DoNothing());
+
+  permissions::MockChooserControllerView view;
+  controller->set_view(&view);
+
+  {
+    const std::u16string expected_name = kBluetoothDevice1Name;
+
+    base::RunLoop run_loop;
+    EXPECT_CALL(view, OnOptionsInitialized).WillOnce(Invoke([&] {
+      run_loop.Quit();
+    }));
+    run_loop.Run();
+    // Expect that only the Bluetooth port is shown thanks to the filter.
+    ASSERT_EQ(1u, controller->NumOptions());
+    ASSERT_EQ(expected_name, controller->GetOption(0));
+  }
+
+  // Removing the wired port should be a no-op since it is filtered out.
+  EXPECT_CALL(view, OnOptionRemoved).Times(0);
+  port_manager().RemovePort(port_1);
+  base::RunLoop().RunUntilIdle();
+
+  // Adding it back should be a no-op as well.
+  EXPECT_CALL(view, OnOptionAdded).Times(0);
+  AddPort("Test Port 1", base::FilePath(FILE_PATH_LITERAL("/dev/ttyS0")),
+          0x1234, 0x0001);
+  base::RunLoop().RunUntilIdle();
+
+  // Removing the Bluetooth port should trigger a change in the UI. This also
+  // acts as a synchronization point to make sure that the changes above were
+  // processed.
+  {
+    base::RunLoop run_loop;
+    EXPECT_CALL(view, OnOptionRemoved(0))
+        .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure()));
+    port_manager().RemovePort(bluetooth_port_token);
+    run_loop.Run();
+  }
+}
+
+TEST_F(SerialChooserControllerTest, BluetoothPortFilteredButNotAllowed) {
+  base::HistogramTester histogram_tester;
+
+  base::UnguessableToken port_1 =
+      AddPort("Test Port 1", base::FilePath(FILE_PATH_LITERAL("/dev/ttyS0")),
+              0x1234, 0x0001);
+  // Create a non-standard Bluetooth port.
+  base::UnguessableToken bluetooth_port_token =
+      AddBluetoothPort(kBluetoothDevice1Address, kBluetoothDevice1Name,
+                       kRandomBluetoothServiceClassId);
+
+  // Create a filter which will select only the Bluetooth port.
+  std::vector<blink::mojom::SerialPortFilterPtr> filters;
+  auto filter = blink::mojom::SerialPortFilter::New();
+  filter->bluetooth_service_class_id = kRandomBluetoothServiceClassId;
+  filters.push_back(std::move(filter));
+
+  std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids;
+  auto controller = std::make_unique<SerialChooserController>(
+      main_rfh(), std::move(filters),
+      std::move(allowed_bluetooth_service_class_ids), base::DoNothing());
+
+  permissions::MockChooserControllerView view;
+  controller->set_view(&view);
+
+  {
+    const std::u16string expected_name = kBluetoothDevice1Name;
+
+    base::RunLoop run_loop;
+    EXPECT_CALL(view, OnOptionsInitialized).WillOnce(Invoke([&] {
+      // Expect that only the Bluetooth port is not shown as it is not allowed.
+      EXPECT_EQ(0u, controller->NumOptions());
+      run_loop.Quit();
+    }));
+    run_loop.Run();
+  }
+
+  // Removing the wired port should be a no-op since it is filtered out.
+  EXPECT_CALL(view, OnOptionRemoved).Times(0);
+  port_manager().RemovePort(port_1);
+  base::RunLoop().RunUntilIdle();
+
+  // Adding it back should be a no-op as well.
+  EXPECT_CALL(view, OnOptionAdded).Times(0);
+  AddPort("Test Port 1", base::FilePath(FILE_PATH_LITERAL("/dev/ttyS0")),
+          0x1234, 0x0001);
+  base::RunLoop().RunUntilIdle();
+
+  // Removing the wired port should be a no-op since it is not allowed.
+  EXPECT_CALL(view, OnOptionRemoved).Times(0);
+  port_manager().RemovePort(bluetooth_port_token);
+  base::RunLoop().RunUntilIdle();
+
+  // Adding it back should be a no-op as well.
+  EXPECT_CALL(view, OnOptionAdded).Times(0);
+  AddBluetoothPort(kBluetoothDevice1Address, kBluetoothDevice1Name,
+                   kRandomBluetoothServiceClassId);
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(SerialChooserControllerTest, DeviceNameDisambiguation) {
+  base::HistogramTester histogram_tester;
+
+  // A test Bluetooth service ID to be chosen.
+  const BluetoothUUID kDevice1OtherServiceId(
+      "105b5a98-d8e6-4f39-9432-49ae7529de74");
+
+  // Create the test Bluetooth ports.
+  auto port1_token =
+      AddBluetoothPort(kBluetoothDevice1Address, kBluetoothDevice1Name,
+                       device::GetSerialPortProfileUUID());
+  auto port2_token = AddBluetoothPort(
+      kBluetoothDevice1Address, kBluetoothDevice1Name, kDevice1OtherServiceId);
+  auto port3_token =
+      AddBluetoothPort(kBluetoothDevice2Address, kBluetoothDevice2Name,
+                       device::GetSerialPortProfileUUID());
+
+  // Create a filter that selects all Bluetooth ports.
+  std::vector<blink::mojom::SerialPortFilterPtr> filters;
+  {
+    auto filter = blink::mojom::SerialPortFilter::New();
+    filter->bluetooth_service_class_id = device::GetSerialPortProfileUUID();
+    filters.push_back(std::move(filter));
+
+    filter = blink::mojom::SerialPortFilter::New();
+    filter->bluetooth_service_class_id = kDevice1OtherServiceId;
+    filters.push_back(std::move(filter));
+  }
+
+  std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids;
+  allowed_bluetooth_service_class_ids.push_back(kDevice1OtherServiceId);
+  auto controller = std::make_unique<SerialChooserController>(
+      main_rfh(), std::move(filters),
+      std::move(allowed_bluetooth_service_class_ids), base::DoNothing());
+
+  permissions::MockChooserControllerView view;
+  controller->set_view(&view);
+
+  {
+    base::RunLoop run_loop;
+    EXPECT_CALL(view, OnOptionsInitialized).WillOnce(Invoke([&] {
+      EXPECT_EQ(3u, controller->NumOptions());
+      for (size_t idx = 0; idx < controller->NumOptions(); idx++) {
+        const device::mojom::SerialPortInfo& port_info =
+            controller->GetPortForTest(idx);
+        std::u16string expected_name;
+        if (port_info.token == port1_token) {
+          expected_name =
+              u"Bluetooth #1 (00001101-0000-1000-8000-00805f9b34fb)";
+        } else if (port_info.token == port2_token) {
+          expected_name =
+              u"Bluetooth #1 (105b5a98-d8e6-4f39-9432-49ae7529de74)";
+        } else if (port_info.token == port3_token) {
+          // Only one port for device #2, so expect device display name only.
+          expected_name = u"Bluetooth #2";
+        } else {
+          FAIL() << "Unexpected port token: " << port_info.token;
+        }
+        EXPECT_EQ(expected_name, controller->GetOption(idx))
+            << "incorrect name for index " << idx;
+      }
+      run_loop.Quit();
+    }));
+    run_loop.Run();
+  }
+}
+
 class SerialChooserControllerTestWithBlockedPorts
     : public SerialChooserControllerTest {
  public:
@@ -298,8 +537,10 @@
               0x1234, 0x0002);
 
   std::vector<blink::mojom::SerialPortFilterPtr> filters;
+  std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids;
   auto controller = std::make_unique<SerialChooserController>(
-      main_rfh(), std::move(filters), base::DoNothing());
+      main_rfh(), std::move(filters),
+      std::move(allowed_bluetooth_service_class_ids), base::DoNothing());
 
   permissions::MockChooserControllerView view;
   controller->set_view(&view);
diff --git a/chrome/browser/ui/side_panel/companion/companion_utils.cc b/chrome/browser/ui/side_panel/companion/companion_utils.cc
index ea135fee..b8f541e 100644
--- a/chrome/browser/ui/side_panel/companion/companion_utils.cc
+++ b/chrome/browser/ui/side_panel/companion/companion_utils.cc
@@ -71,14 +71,6 @@
 }
 
 void UpdateCompanionDefaultPinnedToToolbarState(PrefService* pref_service) {
-  absl::optional<bool> should_force_pin =
-      switches::ShouldForceOverrideCompanionPinState();
-  if (should_force_pin) {
-    pref_service->SetBoolean(prefs::kSidePanelCompanionEntryPinnedToToolbar,
-                             *should_force_pin);
-    return;
-  }
-
   bool companion_should_be_default_pinned =
       base::FeatureList::IsEnabled(
           ::features::kSidePanelCompanionDefaultPinned) ||
diff --git a/chrome/browser/ui/side_panel/companion/companion_utils_unittest.cc b/chrome/browser/ui/side_panel/companion/companion_utils_unittest.cc
deleted file mode 100644
index 6d629d542..0000000
--- a/chrome/browser/ui/side_panel/companion/companion_utils_unittest.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/side_panel/companion/companion_utils.h"
-
-#include "base/command_line.h"
-#include "base/feature_list.h"
-#include "base/test/scoped_feature_list.h"
-#include "chrome/browser/companion/core/constants.h"
-#include "chrome/browser/companion/core/features.h"
-#include "chrome/browser/ui/ui_features.h"
-#include "chrome/common/pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/testing_pref_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace companion {
-
-void RegisterPrefs(TestingPrefServiceSimple* pref_service) {
-  pref_service->registry()->RegisterBooleanPref(
-      prefs::kSidePanelCompanionEntryPinnedToToolbar, false);
-  pref_service->registry()->RegisterBooleanPref(
-      companion::kExpsOptInStatusGrantedPref, false);
-}
-
-TEST(CompanionUtilsTest, PinnedStateCommandlineOverridePinned) {
-  TestingPrefServiceSimple pref_service;
-  RegisterPrefs(&pref_service);
-  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-      switches::kForceCompanionPinnedState, "pinned");
-
-  UpdateCompanionDefaultPinnedToToolbarState(&pref_service);
-  EXPECT_EQ(
-      pref_service.GetBoolean(prefs::kSidePanelCompanionEntryPinnedToToolbar),
-      true);
-}
-
-TEST(CompanionUtilsTest, PinnedStateCommandlineOverrideUnpinned) {
-  TestingPrefServiceSimple pref_service;
-  RegisterPrefs(&pref_service);
-  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-      switches::kForceCompanionPinnedState, "unpinned");
-
-  UpdateCompanionDefaultPinnedToToolbarState(&pref_service);
-  EXPECT_EQ(
-      pref_service.GetBoolean(prefs::kSidePanelCompanionEntryPinnedToToolbar),
-      false);
-}
-
-TEST(CompanionUtilsTest, UpdatePinnedStateDefaultUnpinnedLabsOverride) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  TestingPrefServiceSimple pref_service;
-  RegisterPrefs(&pref_service);
-
-  scoped_feature_list.InitAndDisableFeature(
-      ::features::kSidePanelCompanionDefaultPinned);
-  pref_service.SetBoolean(companion::kExpsOptInStatusGrantedPref, true);
-
-  UpdateCompanionDefaultPinnedToToolbarState(&pref_service);
-  EXPECT_EQ(
-      pref_service.GetBoolean(prefs::kSidePanelCompanionEntryPinnedToToolbar),
-      true);
-}
-
-TEST(CompanionUtilsTest, UpdatePinnedStateDefaultPinned) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  TestingPrefServiceSimple pref_service;
-  RegisterPrefs(&pref_service);
-
-  scoped_feature_list.InitAndEnableFeature(
-      ::features::kSidePanelCompanionDefaultPinned);
-  pref_service.SetBoolean(companion::kExpsOptInStatusGrantedPref, false);
-
-  UpdateCompanionDefaultPinnedToToolbarState(&pref_service);
-  EXPECT_EQ(
-      pref_service.GetBoolean(prefs::kSidePanelCompanionEntryPinnedToToolbar),
-      true);
-}
-
-TEST(CompanionUtilsTest, UpdatePinnedStateDefaultUnPinned) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  TestingPrefServiceSimple pref_service;
-  RegisterPrefs(&pref_service);
-
-  scoped_feature_list.InitAndDisableFeature(
-      ::features::kSidePanelCompanionDefaultPinned);
-  pref_service.SetBoolean(companion::kExpsOptInStatusGrantedPref, false);
-
-  UpdateCompanionDefaultPinnedToToolbarState(&pref_service);
-  EXPECT_EQ(
-      pref_service.GetBoolean(prefs::kSidePanelCompanionEntryPinnedToToolbar),
-      false);
-}
-
-}  // namespace companion
\ No newline at end of file
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index 78dc13c..e1e8184 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -88,6 +88,7 @@
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h"
 #include "chrome/browser/ui/performance_controls/high_efficiency_chip_tab_helper.h"
+#include "chrome/browser/ui/performance_controls/resource_usage_tab_helper.h"
 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
 #include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.h"
 #include "chrome/browser/ui/recently_audible_helper.h"
@@ -501,6 +502,10 @@
   SearchTabHelper::CreateForWebContents(web_contents);
   TabDialogs::CreateForWebContents(web_contents);
   HighEfficiencyChipTabHelper::CreateForWebContents(web_contents);
+  if (base::FeatureList::IsEnabled(
+          performance_manager::features::kMemoryUsageInHovercards)) {
+    ResourceUsageTabHelper::CreateForWebContents(web_contents);
+  }
   if (base::FeatureList::IsEnabled(features::kTabHoverCardImages) ||
       base::FeatureList::IsEnabled(features::kWebUITabStrip)) {
     ThumbnailTabHelper::CreateForWebContents(web_contents);
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.cc b/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.cc
index 61d3d8c..cc1560a 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.cc
@@ -108,6 +108,10 @@
     TabStripModel* tab_strip_model,
     content::WebContents* web_contents,
     int tabstrip_index_of_moved_tab) {
+  if (paused_) {
+    return;
+  }
+
   // Ex:        0 1   2 3 4
   //  TabStrip: A B [ C D E ]
   //  TabGroup:       0 1 2
diff --git a/chrome/browser/ui/test/popup_multiscreen_interactive_uitest.cc b/chrome/browser/ui/test/popup_multiscreen_interactive_uitest.cc
index 2b4401a..96c9d5f 100644
--- a/chrome/browser/ui/test/popup_multiscreen_interactive_uitest.cc
+++ b/chrome/browser/ui/test/popup_multiscreen_interactive_uitest.cc
@@ -38,10 +38,16 @@
 // Tests popups with multi-screen features from the Window Management API.
 // Tests are run with and without the requisite Window Management permission.
 // Tests must run in series to manage virtual displays on supported platforms.
-class PopupMultiScreenTest : public PopupTestBase,
-                             public ::testing::WithParamInterface<bool> {
+// Use 2+ physical displays to run locally with --gtest_also_run_disabled_tests.
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
+#define MAYBE_PopupMultiScreenTest PopupMultiScreenTest
+#else
+#define MAYBE_PopupMultiScreenTest DISABLED_PopupMultiScreenTest
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
+class MAYBE_PopupMultiScreenTest : public PopupTestBase,
+                                   public ::testing::WithParamInterface<bool> {
  public:
-  PopupMultiScreenTest() {
+  MAYBE_PopupMultiScreenTest() {
     scoped_feature_list_.InitWithFeatures(
         {blink::features::kFullscreenPopupWindows}, {});
   }
@@ -107,10 +113,10 @@
 #endif
 };
 
-INSTANTIATE_TEST_SUITE_P(, PopupMultiScreenTest, ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(, MAYBE_PopupMultiScreenTest, ::testing::Bool());
 
 // Tests opening a popup on another screen.
-IN_PROC_BROWSER_TEST_P(PopupMultiScreenTest, OpenOnAnotherScreen) {
+IN_PROC_BROWSER_TEST_P(MAYBE_PopupMultiScreenTest, OpenOnAnotherScreen) {
   // Copy the display vector so references are not invalidated while looping.
   std::vector<display::Display> displays =
       display::Screen::GetScreen()->GetAllDisplays();
@@ -152,7 +158,7 @@
 
 // Tests opening a popup on the same screen, then moving it to another screen.
 // TODO(crbug.com/1444721): Re-enable this test
-IN_PROC_BROWSER_TEST_P(PopupMultiScreenTest, MAYBE_MoveToAnotherScreen) {
+IN_PROC_BROWSER_TEST_P(MAYBE_PopupMultiScreenTest, MAYBE_MoveToAnotherScreen) {
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   // Copy the display vector so references are not invalidated while looping.
@@ -198,7 +204,7 @@
 }
 
 // Tests opening a popup on another screen from a cross-origin iframe.
-IN_PROC_BROWSER_TEST_P(PopupMultiScreenTest, CrossOriginIFrame) {
+IN_PROC_BROWSER_TEST_P(MAYBE_PopupMultiScreenTest, CrossOriginIFrame) {
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
   https_server.AddDefaultHandlers(GetChromeTestDataDir());
@@ -264,7 +270,7 @@
 }
 
 // Tests opening a fullscreen popup on another display, when permitted.
-IN_PROC_BROWSER_TEST_P(PopupMultiScreenTest, FullscreenDifferentScreen) {
+IN_PROC_BROWSER_TEST_P(MAYBE_PopupMultiScreenTest, FullscreenDifferentScreen) {
   // Falls back to opening a popup on the current screen in testing scenarios
   // where window management is not granted in SetUpWindowManagement().
   Browser* popup = OpenPopup(browser(), R"JS(
diff --git a/chrome/browser/ui/test/test_browser_ui.cc b/chrome/browser/ui/test/test_browser_ui.cc
index 21e248d..7bfb0c0 100644
--- a/chrome/browser/ui/test/test_browser_ui.cc
+++ b/chrome/browser/ui/test/test_browser_ui.cc
@@ -24,6 +24,7 @@
 // of lacros-chrome is complete.
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
     (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#include "content/public/common/content_switches.h"
 #include "ui/base/test/skia_gold_matching_algorithm.h"
 #include "ui/compositor/compositor.h"
 #include "ui/compositor/test/draw_waiter_for_test.h"
@@ -107,16 +108,22 @@
     const std::string& screenshot_name) {
 #ifdef SUPPORTS_PIXEL_TEST
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-          "browser-ui-tests-verify-pixels"))
+          switches::kVerifyPixels)) {
     return ui::test::ActionResult::kNotAttempted;
+  }
 
   // Disable and hide cursor to prvent any interference with the
   // screenshots.
   ScopedMouseDisabler disable(view);
 
-  // Clear widget focus to avoid flakiness caused by some widgets having focus
-  // and some not due to tests being run in parallel.
-  view->GetWidget()->GetFocusManager()->ClearFocus();
+  // If there is a focused view, clear it to avoid flakiness caused by
+  // unpredictable widget focus (due to test parallelism). It's important to not
+  // do this unless necessary, since it will close transient UI like menus,
+  // which interferes with tests attempting to verify such UI.
+  if (auto* const focus_manager = view->GetWidget()->GetFocusManager();
+      focus_manager->GetFocusedView()) {
+    focus_manager->ClearFocus();
+  }
 
   // Request that the compositor perform a frame and then wait for it to
   // complete. Because there might not be anything left to draw after waiting
diff --git a/chrome/browser/ui/test/test_infobar.cc b/chrome/browser/ui/test/test_infobar.cc
index ac85a6c..62859de8 100644
--- a/chrome/browser/ui/test/test_infobar.cc
+++ b/chrome/browser/ui/test/test_infobar.cc
@@ -24,19 +24,13 @@
 bool TestInfoBar::VerifyUi() {
   absl::optional<InfoBars> infobars = GetNewInfoBars();
   if (!infobars || infobars->empty()) {
-    ADD_FAILURE() << "No new infobars were displayed.";
     return false;
   }
 
-  bool expected_infobars_found =
-      base::ranges::equal(*infobars, expected_identifiers_, std::equal_to<>(),
-                          [](infobars::InfoBar* infobar) {
-                            return infobar->delegate()->GetIdentifier();
-                          });
-  if (!expected_infobars_found)
-    ADD_FAILURE() << "Found unexpected infobars.";
-
-  return expected_infobars_found;
+  return base::ranges::equal(*infobars, expected_identifiers_, {},
+                             [](infobars::InfoBar* infobar) {
+                               return infobar->delegate()->GetIdentifier();
+                             });
 }
 
 void TestInfoBar::WaitForUserDismissal() {
@@ -80,8 +74,9 @@
   const InfoBars& infobars = infobar_manager->infobars_;
   if ((infobars.size() < starting_infobars_.size()) ||
       !std::equal(starting_infobars_.begin(), starting_infobars_.end(),
-                  infobars.begin()))
+                  infobars.begin())) {
     return absl::nullopt;
+  }
   return InfoBars(std::next(infobars.begin(), starting_infobars_.size()),
                   infobars.end());
 }
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index 10cb20c..3b35695 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -33,6 +33,7 @@
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/search/search.h"
+#include "chrome/browser/sharing_hub/sharing_hub_features.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #include "chrome/browser/ui/browser.h"
@@ -140,8 +141,6 @@
 
 namespace {
 
-constexpr size_t kMaxAppNameLength = 30;
-
 // Conditionally return the update app menu item title based on upgrade detector
 // state.
 std::u16string GetUpgradeDialogMenuItemName() {
@@ -170,17 +169,43 @@
 
 // Returns the appropriate menu label for the IDC_INSTALL_PWA command if
 // available.
-absl::optional<std::u16string> GetInstallPWAAppMenuItemName(Browser* browser) {
-  WebContents* web_contents =
-      browser->tab_strip_model()->GetActiveWebContents();
-  if (!web_contents)
-    return absl::nullopt;
-  std::u16string app_name =
+std::u16string GetInstallPWALabel(const Browser* browser) {
+  // There may be no active web contents in tests.
+  auto* const web_contents = browser->tab_strip_model()->GetActiveWebContents();
+  if (!web_contents) {
+    return std::u16string();
+  }
+
+  const std::u16string app_name =
       webapps::AppBannerManager::GetInstallableWebAppName(web_contents);
-  if (app_name.empty())
-    return absl::nullopt;
-  return l10n_util::GetStringFUTF16(IDS_INSTALL_TO_OS_LAUNCH_SURFACE,
-                                    ui::EscapeMenuLabelAmpersands(app_name));
+  return app_name.empty() ? app_name
+                          : l10n_util::GetStringFUTF16(
+                                IDS_INSTALL_TO_OS_LAUNCH_SURFACE,
+                                ui::EscapeMenuLabelAmpersands(app_name));
+}
+
+// Returns the appropriate menu label for the IDC_OPEN_IN_PWA_WINDOW command if
+// available.
+std::u16string GetOpenPWALabel(const Browser* browser) {
+  absl::optional<web_app::AppId> app_id =
+      web_app::GetWebAppForActiveTab(browser);
+  if (!app_id.has_value()) {
+    return std::u16string();
+  }
+
+  // Only show this menu item for apps that open in an app window.
+  const auto* const provider =
+      web_app::WebAppProvider::GetForLocalAppsUnchecked(browser->profile());
+  if (provider->registrar_unsafe().GetAppUserDisplayMode(*app_id) ==
+      web_app::mojom::UserDisplayMode::kBrowser) {
+    return std::u16string();
+  }
+
+  const std::u16string short_name =
+      base::UTF8ToUTF16(provider->registrar_unsafe().GetAppShortName(*app_id));
+  return l10n_util::GetStringFUTF16(
+      IDS_OPEN_IN_APP_WINDOW, ui::EscapeMenuLabelAmpersands(gfx::TruncateString(
+                                  short_name, 30, gfx::CHARACTER_BREAK)));
 }
 
 bool IsPasswordManagerPage(const GURL& url) {
@@ -467,7 +492,7 @@
     ui::SimpleMenuModel::Delegate* delegate)
     : SimpleMenuModel(delegate) {
   AddItemWithStringIdAndIcon(
-      IDC_SHOW_PASSWORD_MANAGER, IDS_PASSWORD_MANAGER_SUBMENU_OPTION,
+      IDC_SHOW_PASSWORD_MANAGER, IDS_VIEW_PASSWORDS,
       ui::ImageModel::FromVectorIcon(kKeyChromeRefreshIcon, ui::kColorMenuIcon,
                                      kDefaultIconSize));
   AddItemWithStringIdAndIcon(
@@ -572,7 +597,6 @@
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
          command_id == IDC_LACROS_DATA_MIGRATION ||
 #endif
-         (command_id == IDC_INSTALL_PWA && !features::IsChromeRefresh2023()) ||
          command_id == IDC_UPGRADE_DIALOG;
 }
 
@@ -598,8 +622,6 @@
     case IDC_LACROS_DATA_MIGRATION:
       return GetLacrosDataMigrationMenuItemName();
 #endif
-    case IDC_INSTALL_PWA:
-      return GetInstallPWAAppMenuItemName(browser_).value();
     case IDC_UPGRADE_DIALOG:
       DCHECK(browser_defaults::kShowUpgradeMenuItem);
       return GetUpgradeDialogMenuItemName();
@@ -816,6 +838,20 @@
       LogMenuAction(MENU_ACTION_PASTE);
       break;
 
+    case IDC_INSTALL_PWA:
+      if (!uma_action_recorded_) {
+        UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.InstallPwa", delta);
+      }
+      LogMenuAction(MENU_ACTION_INSTALL_PWA);
+      break;
+    case IDC_OPEN_IN_PWA_WINDOW:
+      if (!uma_action_recorded_) {
+        UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.OpenInPwaWindow",
+                                   delta);
+      }
+      LogMenuAction(MENU_ACTION_OPEN_IN_PWA_WINDOW);
+      break;
+
     // Tools menu.
     case IDC_CREATE_SHORTCUT:
       if (!uma_action_recorded_) {
@@ -1257,9 +1293,7 @@
     // TODO(josephjoopark): Update translate string with StringId when
     // finalized.
     AddItem(IDC_TRANSLATE_PAGE, u"Google Translate");
-  }
 
-  if (features::IsChromeRefresh2023()) {
     sub_menus_.push_back(std::make_unique<FindAndEditSubMenuModel>(this));
     AddSubMenuWithStringId(IDC_FIND_AND_EDIT_MENU, IDS_FIND_AND_EDIT_MENU,
                            sub_menus_.back().get());
@@ -1267,30 +1301,18 @@
     AddItemWithStringId(IDC_FIND, IDS_FIND);
   }
 
-  if (absl::optional<std::u16string> name =
-          GetInstallPWAAppMenuItemName(browser_)) {
-    AddItem(IDC_INSTALL_PWA, *name);
+  if (std::u16string install_item = GetInstallPWALabel(browser_);
+      !install_item.empty()) {
+    AddItem(IDC_INSTALL_PWA, install_item);
     if (features::IsChromeRefresh2023()) {
       SetCommandIcon(this, IDC_INSTALL_PWA, kInstallDesktopChromeRefreshIcon);
     }
-  } else if (absl::optional<web_app::AppId> app_id =
-                 web_app::GetWebAppForActiveTab(browser_)) {
-    auto* provider =
-        web_app::WebAppProvider::GetForLocalAppsUnchecked(browser_->profile());
-    // Only applies to apps that open in an app window.
-    if (provider->registrar_unsafe().GetAppUserDisplayMode(*app_id) !=
-        web_app::mojom::UserDisplayMode::kBrowser) {
-      const std::u16string short_name = base::UTF8ToUTF16(
-          provider->registrar_unsafe().GetAppShortName(*app_id));
-      const std::u16string truncated_name = gfx::TruncateString(
-          short_name, kMaxAppNameLength, gfx::CHARACTER_BREAK);
-      AddItem(
-          IDC_OPEN_IN_PWA_WINDOW,
-          l10n_util::GetStringFUTF16(IDS_OPEN_IN_APP_WINDOW, truncated_name));
-      if (features::IsChromeRefresh2023()) {
-        SetCommandIcon(this, IDC_OPEN_IN_PWA_WINDOW,
-                       kDesktopWindowsChromeRefreshIcon);
-      }
+  } else if (std::u16string open_item = GetOpenPWALabel(browser_);
+             !open_item.empty()) {
+    AddItem(IDC_OPEN_IN_PWA_WINDOW, open_item);
+    if (features::IsChromeRefresh2023()) {
+      SetCommandIcon(this, IDC_OPEN_IN_PWA_WINDOW,
+                     kDesktopWindowsChromeRefreshIcon);
     }
   }
 
diff --git a/chrome/browser/ui/toolbar/app_menu_model.h b/chrome/browser/ui/toolbar/app_menu_model.h
index 8648fcc..453323d 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.h
+++ b/chrome/browser/ui/toolbar/app_menu_model.h
@@ -76,18 +76,17 @@
   MENU_ACTION_OPEN_IN_CHROME = 48,
   MENU_ACTION_SITE_SETTINGS = 49,
   MENU_ACTION_APP_INFO = 50,
-  // Only used by WebAppMenuModel:
   MENU_ACTION_UNINSTALL_APP = 51,
   MENU_ACTION_CHROME_TIPS = 53,
   MENU_ACTION_CHROME_WHATS_NEW = 54,
   MENU_ACTION_LACROS_DATA_MIGRATION = 55,
   MENU_ACTION_MENU_OPENED = 56,
-  // Only used by ExtensionsMenuModel sub menu.
   MENU_ACTION_VISIT_CHROME_WEB_STORE = 57,
   MENU_ACTION_PASSWORD_MANAGER = 58,
   MENU_ACTION_TRANSLATE_PAGE = 59,
-  // ToolsMenuModel
   MENU_ACTION_SHOW_CHROME_LABS = 60,
+  MENU_ACTION_INSTALL_PWA = 61,
+  MENU_ACTION_OPEN_IN_PWA_WINDOW = 62,
   LIMIT_MENU_ACTION
 };
 
diff --git a/chrome/browser/ui/views/accelerator_table.cc b/chrome/browser/ui/views/accelerator_table.cc
index 08b9080..baa8e76 100644
--- a/chrome/browser/ui/views/accelerator_table.cc
+++ b/chrome/browser/ui/views/accelerator_table.cc
@@ -119,7 +119,7 @@
     {ui::VKEY_8, ui::EF_ALT_DOWN, IDC_SELECT_TAB_7},
     {ui::VKEY_NUMPAD8, ui::EF_ALT_DOWN, IDC_SELECT_TAB_7},
     {ui::VKEY_BROWSER_FAVORITES, ui::EF_NONE, IDC_SHOW_BOOKMARK_BAR},
-#endif  // BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX)
     {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR,
      IDC_SHOW_BOOKMARK_BAR},
     {ui::VKEY_OEM_MINUS, ui::EF_PLATFORM_ACCELERATOR, IDC_ZOOM_MINUS},
@@ -194,9 +194,9 @@
     {ui::VKEY_BROWSER_SEARCH, ui::EF_NONE, IDC_FOCUS_SEARCH},
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_MAC)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
     {ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, IDC_FEEDBACK},
-#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_MAC)
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
     {ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR,
      IDC_NEW_INCOGNITO_WINDOW},
     {ui::VKEY_T, ui::EF_PLATFORM_ACCELERATOR, IDC_NEW_TAB},
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
index fa929259..395bf7e 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -55,6 +55,7 @@
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/page_navigator.h"
 #include "ui/base/test/ui_controls.h"
+#include "ui/display/display_switches.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/button/menu_button.h"
@@ -919,8 +920,10 @@
     const views::View* target_view = drop_submenu->GetMenuItemAt(0);
     SetStopDraggingView(target_view);
 
-    // Drag to the top of the target view.
-    gfx::Point target(target_view->width() / 2, 0);
+    // Drag to the top of the target view. Use 2 instead of 0 for target.y
+    // so that the mouse event will be in the target view for device scale
+    // factors other than 1.0.
+    gfx::Point target(target_view->width() / 2, 2);
     views::View::ConvertPointToScreen(target_view, &target);
     GetDragTaskRunner()->PostTask(
         FROM_HERE,
diff --git a/chrome/browser/ui/views/chrome_layout_provider.cc b/chrome/browser/ui/views/chrome_layout_provider.cc
index 6109922..2a72d35 100644
--- a/chrome/browser/ui/views/chrome_layout_provider.cc
+++ b/chrome/browser/ui/views/chrome_layout_provider.cc
@@ -9,6 +9,7 @@
 #include "base/feature_list.h"
 #include "base/logging.h"
 #include "chrome/browser/ui/views/chrome_typography.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/omnibox/common/omnibox_features.h"
 #include "ui/base/pointer/touch_ui_controller.h"
 #include "ui/base/ui_base_features.h"
@@ -157,7 +158,7 @@
     case DISTANCE_BETWEEN_PRIMARY_AND_SECONDARY_LABELS_HORIZONTAL:
       return 24;
     case DISTANCE_OMNIBOX_CELL_VERTICAL_PADDING:
-      return 8;
+      return OmniboxFieldTrial::IsCr23LayoutEnabled() ? 12 : 8;
     case DISTANCE_OMNIBOX_TWO_LINE_CELL_VERTICAL_PADDING:
       return 4;
     case DISTANCE_SIDE_PANEL_HEADER_VECTOR_ICON_SIZE:
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc
index 30828fa..6413e4c 100644
--- a/chrome/browser/ui/views/content_setting_bubble_contents.cc
+++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -29,6 +29,7 @@
 #include "ui/base/models/combobox_model.h"
 #include "ui/base/models/image_model.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/base/ui_base_features.h"
 #include "ui/color/color_id.h"
 #include "ui/color/color_provider.h"
 #include "ui/gfx/color_utils.h"
@@ -643,6 +644,9 @@
     manage_button->SetMinSize(gfx::Size(
         layout->GetDistanceMetric(views::DISTANCE_DIALOG_BUTTON_MINIMUM_WIDTH),
         0));
+    if (features::IsChromeRefresh2023()) {
+      manage_button->SetStyle(ui::ButtonStyle::kTonal);
+    }
     manage_button_ = manage_button.get();
     extra_views.push_back(std::move(manage_button));
   }
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_handler.h b/chrome/browser/ui/views/extensions/extensions_menu_handler.h
index f588e9c..7968901df8 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_handler.h
+++ b/chrome/browser/ui/views/extensions/extensions_menu_handler.h
@@ -7,7 +7,6 @@
 
 #include "extensions/browser/permissions_manager.h"
 #include "extensions/common/extension_id.h"
-#include "ui/views/controls/button/toggle_button.h"
 
 // An interface that provides callbacks to the extensions menu pages.
 class ExtensionsMenuHandler {
@@ -25,6 +24,9 @@
   // Closes the currently-showing extensions menu, if it exists.
   virtual void CloseBubble() = 0;
 
+  // Updates the user site setting whether toggle `is_on`.
+  virtual void OnSiteSettingsToggleButtonPressed(bool is_on) = 0;
+
   // Updates the user site access for `extension_id` to `site_access`.
   virtual void OnSiteAccessSelected(
       extensions::ExtensionId extension_id,
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
index e98797f..86316eb 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
@@ -54,8 +54,6 @@
 
 namespace {
 
-using PermissionsManager = extensions::PermissionsManager;
-
 // Updates the `toggle_button` text based on its state.
 std::u16string GetSiteSettingToggleText(bool is_on) {
   int label_id = is_on ? IDS_EXTENSIONS_MENU_SITE_SETTINGS_TOGGLE_ON_TOOLTIP
@@ -380,8 +378,15 @@
                   views::Builder<views::ToggleButton>()
                       .CopyAddressTo(&site_settings_toggle_)
                       .SetCallback(base::BindRepeating(
-                          &ExtensionsMenuMainPageView::OnToggleButtonPressed,
-                          base::Unretained(this))),
+                          [](views::ToggleButton* toggle_button,
+                             base::RepeatingCallback<void(bool)> callback) {
+                            callback.Run(toggle_button->GetIsOn());
+                          },
+                          site_settings_toggle_,
+                          base::BindRepeating(
+                              &ExtensionsMenuHandler::
+                                  OnSiteSettingsToggleButtonPressed,
+                              base::Unretained(menu_handler)))),
                   // Close button.
                   views::Builder<views::Button>(
                       views::BubbleFrameView::CreateCloseButton(
@@ -445,21 +450,6 @@
   menu_items_->RemoveChildViewT(item);
 }
 
-void ExtensionsMenuMainPageView::OnToggleButtonPressed() {
-  const url::Origin& origin =
-      GetActiveWebContents()->GetPrimaryMainFrame()->GetLastCommittedOrigin();
-  PermissionsManager::UserSiteSetting site_setting =
-      site_settings_toggle_->GetIsOn()
-          ? PermissionsManager::UserSiteSetting::kCustomizeByExtension
-          : PermissionsManager::UserSiteSetting::kBlockAllExtensions;
-
-  PermissionsManager::Get(browser_->profile())
-      ->UpdateUserSiteSetting(origin, site_setting);
-
-  // TODO(crbug.com/1390952): Show reload message in menu if any extension needs
-  // a page refresh for the update to take effect.
-}
-
 void ExtensionsMenuMainPageView::UpdateSubheader(
     const std::u16string& current_site,
     bool is_site_settings_toggle_visible,
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h
index af96e7e..c64bc26 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h
+++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h
@@ -92,8 +92,6 @@
   // if existent.
   void RemoveExtensionRequestingAccess(const extensions::ExtensionId& id);
 
-  void OnToggleButtonPressed();
-
   // Accessors used by tests:
   // Returns the currently-showing menu items.
   views::ToggleButton* GetSiteSettingsToggleForTesting() {
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc
index c67040f8..61d6cd6 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc
@@ -326,6 +326,21 @@
                                GetActiveWebContents(), site_access);
 }
 
+void ExtensionsMenuViewController::OnSiteSettingsToggleButtonPressed(
+    bool is_on) {
+  const url::Origin& origin =
+      GetActiveWebContents()->GetPrimaryMainFrame()->GetLastCommittedOrigin();
+  PermissionsManager::UserSiteSetting site_setting =
+      is_on ? PermissionsManager::UserSiteSetting::kCustomizeByExtension
+            : PermissionsManager::UserSiteSetting::kBlockAllExtensions;
+
+  PermissionsManager::Get(browser_->profile())
+      ->UpdateUserSiteSetting(origin, site_setting);
+
+  // TODO(crbug.com/1390952): Show reload message in menu if any extension needs
+  // a page refresh for the update to take effect.
+}
+
 void ExtensionsMenuViewController::OnExtensionToggleSelected(
     extensions::ExtensionId extension_id,
     bool is_on) {
@@ -651,8 +666,9 @@
     return;
   }
 
-  DCHECK(GetMainPage(current_page_));
-  UpdatePage(GetActiveWebContents());
+  ExtensionsMenuMainPageView* main_page = GetMainPage(current_page_);
+  DCHECK(main_page);
+  UpdateMainPage(main_page, GetActiveWebContents());
 
   // TODO(crbug.com/1390952): Update the "highlighted section" based on the
   // `site_setting` and whether a page refresh is needed.
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.h b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.h
index 7ab9d611..1e36cfc 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.h
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.h
@@ -44,6 +44,7 @@
   void OpenMainPage() override;
   void OpenSitePermissionsPage(extensions::ExtensionId extension_id) override;
   void CloseBubble() override;
+  void OnSiteSettingsToggleButtonPressed(bool is_on) override;
   void OnSiteAccessSelected(
       extensions::ExtensionId extension_id,
       extensions::PermissionsManager::UserSiteAccess site_access) override;
diff --git a/chrome/browser/ui/views/frame/browser_frame_mac.mm b/chrome/browser/ui/views/frame/browser_frame_mac.mm
index eb1570b..4811b2a 100644
--- a/chrome/browser/ui/views/frame/browser_frame_mac.mm
+++ b/chrome/browser/ui/views/frame/browser_frame_mac.mm
@@ -66,10 +66,10 @@
     return false;
 
   // If the event was not synthesized it should have an os_event.
-  DCHECK(event.os_event);
+  DCHECK(event.os_event.IsValid());
 
   // Do not fire shortcuts on key up.
-  return [event.os_event type] == NSEventTypeKeyDown;
+  return event.os_event.Get().type == NSEventTypeKeyDown;
 }
 
 }  // namespace
@@ -471,12 +471,15 @@
   // -[CommandDispatcher performKeyEquivalent:]. If this logic is being hit,
   // it means that the event was not handled, so we must return either
   // NOT_HANDLED or NOT_HANDLED_IS_SHORTCUT.
-  if (EventUsesPerformKeyEquivalent(event.os_event)) {
-    int command_id = CommandForKeyEvent(event.os_event).chrome_command;
-    if (command_id == -1)
-      command_id = DelayedWebContentsCommandForKeyEvent(event.os_event);
-    if (command_id != -1)
+  NSEvent* ns_event = event.os_event.Get();
+  if (EventUsesPerformKeyEquivalent(ns_event)) {
+    int command_id = CommandForKeyEvent(ns_event).chrome_command;
+    if (command_id == -1) {
+      command_id = DelayedWebContentsCommandForKeyEvent(ns_event);
+    }
+    if (command_id != -1) {
       return content::KeyboardEventProcessingResult::NOT_HANDLED_IS_SHORTCUT;
+    }
   }
 
   return content::KeyboardEventProcessingResult::NOT_HANDLED;
@@ -484,12 +487,13 @@
 
 bool BrowserFrameMac::HandleKeyboardEvent(
     const content::NativeWebKeyboardEvent& event) {
-  if (!ShouldHandleKeyboardEvent(event))
+  if (!ShouldHandleKeyboardEvent(event)) {
     return false;
+  }
 
   // Redispatch the event. If it's a keyEquivalent:, this gives
   // CommandDispatcher the opportunity to finish passing the event to consumers.
-  return GetNSWindowHost()->RedispatchKeyEvent(event.os_event);
+  return GetNSWindowHost()->RedispatchKeyEvent(event.os_event.Get());
 }
 
 bool BrowserFrameMac::ShouldRestorePreviousBrowserWidgetState() const {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
index 9da888a1..98f7a7b 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
@@ -213,6 +213,28 @@
 #endif
 }
 
+// Verifies that the incognito window frame is always the right color.
+IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewBrowserTest,
+                       IncognitoIsCorrectColor) {
+  // Set the color that's expected to be ignored.
+  auto* theme = ui::NativeTheme::GetInstanceForNativeUi();
+  theme->set_user_color(gfx::kGoogleBlue400);
+  theme->NotifyOnNativeThemeUpdated();
+
+  Browser* incognito_browser = CreateIncognitoBrowser(browser()->profile());
+
+  BrowserView* view = BrowserView::GetBrowserViewForBrowser(incognito_browser);
+  BrowserFrame* frame = view->frame();
+  BrowserNonClientFrameView* frame_view = frame->GetFrameView();
+
+  // Checking the exact color is brittle but there's no better way to ensure
+  // that it's not overridden by accident.
+  EXPECT_EQ(gfx::kGoogleGrey900,
+            frame_view->GetFrameColor(BrowserFrameActiveState::kActive));
+
+  incognito_browser->window()->Close();
+}
+
 // Checks that the title bar for hosted app windows is hidden when in fullscreen
 // for tab mode.
 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewBrowserTest,
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
index 4a971e8..fbb8efe2 100644
--- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
@@ -8,17 +8,22 @@
 #include <string>
 #include <utility>
 
+#include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/observer_list.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/global_media_controls/media_item_ui_metrics.h"
 #include "chrome/browser/ui/global_media_controls/media_notification_service.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
+#include "chrome/browser/ui/views/controls/rich_hover_button.h"
 #include "chrome/browser/ui/views/global_media_controls/media_dialog_view_observer.h"
 #include "chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h"
 #include "chrome/browser/ui/views/global_media_controls/media_item_ui_footer_view.h"
@@ -32,6 +37,7 @@
 #include "components/live_caption/pref_names.h"
 #include "components/media_router/browser/media_router.h"
 #include "components/media_router/browser/media_router_factory.h"
+#include "components/prefs/pref_change_registrar.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "components/soda/constants.h"
 #include "components/sync_preferences/pref_service_syncable.h"
@@ -47,21 +53,27 @@
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/background.h"
 #include "ui/views/bubble/bubble_frame_view.h"
+#include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/button/toggle_button.h"
+#include "ui/views/controls/combobox/combobox.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
+#include "ui/views/controls/separator.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
+#include "ui/views/layout/layout_provider.h"
 #include "ui/views/views_features.h"
 
 using media_session::mojom::MediaSessionAction;
 
 namespace {
 
-static constexpr int kLiveCaptionBetweenChildSpacing = 4;
-static constexpr int kLiveCaptionHorizontalMarginDip = 16;
-static constexpr int kLiveCaptionImageWidthDip = 20;
-static constexpr int kLiveCaptionVerticalMarginDip = 10;
+static constexpr int kHorizontalMarginDip = 16;
+static constexpr int kImageWidthDip = 20;
+static constexpr int kVerticalMarginDip = 10;
+
+// Delta between the font size of the Live Translate title and subtitle.
+static constexpr int kLiveTranslateSubtitleFontSizeDelta = -2;
 
 std::u16string GetLiveCaptionTitle(PrefService* profile_prefs) {
   if (!base::FeatureList::IsEnabled(media::kLiveCaptionMultiLanguage)) {
@@ -263,8 +275,65 @@
     return;
   }
   const int width = active_sessions_view_->GetPreferredSize().width();
-  const int height = live_caption_container_->GetPreferredSize().height();
-  live_caption_container_->SetPreferredSize(gfx::Size(width, height));
+  const int live_caption_height =
+      live_caption_container_->GetPreferredSize().height();
+  live_caption_container_->SetPreferredSize(
+      gfx::Size(width, live_caption_height));
+
+  if (base::FeatureList::IsEnabled(media::kLiveTranslate)) {
+    const int live_translate_height =
+        live_translate_container_->GetPreferredSize().height();
+    live_translate_container_->SetPreferredSize(
+        gfx::Size(width, live_translate_height));
+
+    const gfx::FontList& base_font_list = views::Label::GetDefaultFontList();
+    live_translate_subtitle_->SetFontList(base_font_list.DeriveWithSizeDelta(
+        kLiveTranslateSubtitleFontSizeDelta));
+
+    live_translate_label_wrapper_->SetPreferredSize(gfx::Size(
+        width, live_translate_label_wrapper_->GetPreferredSize().height()));
+
+    // Align the combo box with the text labels.
+    const int target_language_container_height =
+        target_language_container_->GetPreferredSize().height();
+    target_language_container_->SetPreferredSize(
+        gfx::Size(width, target_language_container_height));
+    target_language_combobox_->SetPreferredSize(
+        gfx::Size(width - 2 * (kImageWidthDip + kHorizontalMarginDip +
+                               ChromeLayoutProvider::Get()->GetDistanceMetric(
+                                   views::DISTANCE_RELATED_LABEL_HORIZONTAL)),
+                  target_language_container_height));
+  }
+
+  separator_->SetPreferredLength(width);
+  caption_settings_button_->SetPreferredSize(
+      gfx::Size(width, live_caption_height));
+}
+
+void MediaDialogView::OnLiveCaptionEnabledChanged() {
+  bool enabled = profile_->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled);
+
+  // Do not update the title if SODA is currently downloading.
+  if (!speech::SodaInstaller::GetInstance()->IsSodaDownloading(
+          speech::GetLanguageCode(
+              prefs::GetLiveCaptionLanguageCode(profile_->GetPrefs())))) {
+    SetLiveCaptionTitle(GetLiveCaptionTitle(profile_->GetPrefs()));
+  }
+
+  live_caption_button_->SetIsOn(enabled);
+
+  if (base::FeatureList::IsEnabled(media::kLiveTranslate)) {
+    live_translate_container_->SetVisible(enabled);
+  }
+
+  UpdateBubbleSize();
+}
+
+void MediaDialogView::OnLiveTranslateEnabledChanged() {
+  bool enabled = profile_->GetPrefs()->GetBoolean(prefs::kLiveTranslateEnabled);
+  live_translate_button_->SetIsOn(enabled);
+  target_language_container_->SetVisible(enabled);
+  UpdateBubbleSize();
 }
 
 void MediaDialogView::OnMediaItemUISizeChanged() {
@@ -299,6 +368,13 @@
   observers_.RemoveObserver(observer);
 }
 
+void MediaDialogView::TargetLanguageChanged() {
+  static_cast<LiveTranslateComboboxModel*>(
+      target_language_combobox_->GetModel())
+      ->UpdateTargetLanguageIndex(
+          target_language_combobox_->GetSelectedIndex().value());
+}
+
 const std::map<const std::string, global_media_controls::MediaItemUIView*>&
 MediaDialogView::GetItemsForTesting() const {
   return active_sessions_view_->items_for_testing();  // IN-TEST
@@ -330,6 +406,17 @@
   SetAccessibleTitle(
       l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_DIALOG_NAME));
   DCHECK(service_);
+
+  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
+  pref_change_registrar_->Init(profile->GetPrefs());
+  pref_change_registrar_->Add(
+      prefs::kLiveCaptionEnabled,
+      base::BindRepeating(&MediaDialogView::OnLiveCaptionEnabledChanged,
+                          base::Unretained(this)));
+  pref_change_registrar_->Add(
+      prefs::kLiveTranslateEnabled,
+      base::BindRepeating(&MediaDialogView::OnLiveTranslateEnabledChanged,
+                          base::Unretained(this)));
 }
 
 MediaDialogView::~MediaDialogView() {
@@ -349,42 +436,14 @@
                        views::BoxLayout::Orientation::kVertical))
       ->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kStart);
 
-  auto live_caption_container = std::make_unique<View>();
-  auto* live_caption_container_layout =
-      live_caption_container->SetLayoutManager(
-          std::make_unique<views::BoxLayout>(
-              views::BoxLayout::Orientation::kHorizontal,
-              gfx::Insets::VH(kLiveCaptionVerticalMarginDip,
-                              kLiveCaptionHorizontalMarginDip),
-              kLiveCaptionBetweenChildSpacing));
+  InitializeLiveCaptionSection();
+  if (base::FeatureList::IsEnabled(media::kLiveTranslate)) {
+    InitializeLiveTranslateSection();
+  }
 
-  auto live_caption_image = std::make_unique<views::ImageView>();
-  live_caption_image->SetImage(ui::ImageModel::FromVectorIcon(
-      vector_icons::kLiveCaptionOnIcon, ui::kColorIcon,
-      kLiveCaptionImageWidthDip));
-  live_caption_container->AddChildView(std::move(live_caption_image));
-
-  std::u16string live_caption_title_message =
-      GetLiveCaptionTitle(profile_->GetPrefs());
-  auto live_caption_title =
-      std::make_unique<views::Label>(live_caption_title_message);
-  live_caption_title->SetHorizontalAlignment(
-      gfx::HorizontalAlignment::ALIGN_LEFT);
-  live_caption_title->SetMultiLine(true);
-  live_caption_title_ =
-      live_caption_container->AddChildView(std::move(live_caption_title));
-  live_caption_container_layout->SetFlexForView(live_caption_title_, 1);
-
-  auto live_caption_button = std::make_unique<views::ToggleButton>(
-      base::BindRepeating(&MediaDialogView::OnLiveCaptionButtonPressed,
-                          base::Unretained(this)));
-  live_caption_button->SetIsOn(
-      profile_->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled));
-  live_caption_button->SetAccessibleName(live_caption_title_->GetText());
-  live_caption_button_ =
-      live_caption_container->AddChildView(std::move(live_caption_button));
-
-  live_caption_container_ = AddChildView(std::move(live_caption_container));
+  separator_ = AddChildView(std::make_unique<views::Separator>());
+  separator_->SetOrientation(views::Separator::Orientation::kHorizontal);
+  InitializeCaptionSettingsSection();
 }
 
 void MediaDialogView::WindowClosing() {
@@ -397,22 +456,24 @@
 
 void MediaDialogView::OnLiveCaptionButtonPressed() {
   bool enabled = !profile_->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled);
-  ToggleLiveCaption(enabled);
+  profile_->GetPrefs()->SetBoolean(prefs::kLiveCaptionEnabled, enabled);
   base::UmaHistogramBoolean(
       "Accessibility.LiveCaption.EnableFromGlobalMediaControls", enabled);
 }
 
-void MediaDialogView::ToggleLiveCaption(bool enabled) {
-  profile_->GetPrefs()->SetBoolean(prefs::kLiveCaptionEnabled, enabled);
+void MediaDialogView::OnLiveTranslateButtonPressed() {
+  bool enabled =
+      !profile_->GetPrefs()->GetBoolean(prefs::kLiveTranslateEnabled);
+  profile_->GetPrefs()->SetBoolean(prefs::kLiveTranslateEnabled, enabled);
+}
 
-  // Do not update the title if SODA is currently downloading.
-  if (!speech::SodaInstaller::GetInstance()->IsSodaDownloading(
-          speech::GetLanguageCode(
-              prefs::GetLiveCaptionLanguageCode(profile_->GetPrefs())))) {
-    SetLiveCaptionTitle(GetLiveCaptionTitle(profile_->GetPrefs()));
-  }
-
-  live_caption_button_->SetIsOn(enabled);
+void MediaDialogView::OnSettingsButtonPressed() {
+  NavigateParams navigate_params(profile_,
+                                 GURL(captions::GetCaptionSettingsUrl()),
+                                 ui::PAGE_TRANSITION_LINK);
+  navigate_params.window_action = NavigateParams::WindowAction::SHOW_WINDOW;
+  navigate_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
+  Navigate(&navigate_params);
 }
 
 void MediaDialogView::OnSodaInstalled(speech::LanguageCode language_code) {
@@ -465,6 +526,143 @@
       IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_PROGRESS, progress));
 }
 
+void MediaDialogView::InitializeLiveCaptionSection() {
+  auto live_caption_container = std::make_unique<View>();
+  auto* live_caption_container_layout =
+      live_caption_container->SetLayoutManager(
+          std::make_unique<views::BoxLayout>(
+              views::BoxLayout::Orientation::kHorizontal,
+              gfx::Insets::VH(kVerticalMarginDip, kHorizontalMarginDip),
+              ChromeLayoutProvider::Get()->GetDistanceMetric(
+                  views::DISTANCE_RELATED_LABEL_HORIZONTAL)));
+
+  auto live_caption_image = std::make_unique<views::ImageView>();
+  live_caption_image->SetImage(ui::ImageModel::FromVectorIcon(
+      vector_icons::kLiveCaptionOnIcon, ui::kColorIcon, kImageWidthDip));
+  live_caption_container->AddChildView(std::move(live_caption_image));
+
+  auto live_caption_title =
+      std::make_unique<views::Label>(GetLiveCaptionTitle(profile_->GetPrefs()));
+  live_caption_title->SetHorizontalAlignment(
+      gfx::HorizontalAlignment::ALIGN_LEFT);
+  live_caption_title->SetMultiLine(true);
+  live_caption_title_ =
+      live_caption_container->AddChildView(std::move(live_caption_title));
+  live_caption_container_layout->SetFlexForView(live_caption_title_, 1);
+
+  auto live_caption_button = std::make_unique<views::ToggleButton>(
+      base::BindRepeating(&MediaDialogView::OnLiveCaptionButtonPressed,
+                          base::Unretained(this)));
+  live_caption_button->SetIsOn(
+      profile_->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled));
+  live_caption_button->SetAccessibleName(live_caption_title_->GetText());
+  live_caption_button_ =
+      live_caption_container->AddChildView(std::move(live_caption_button));
+
+  live_caption_container_ = AddChildView(std::move(live_caption_container));
+}
+
+void MediaDialogView::InitializeLiveTranslateSection() {
+  auto live_translate_container = std::make_unique<View>();
+  live_translate_container->SetVisible(
+      profile_->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled));
+  auto* live_translate_container_layout =
+      live_translate_container->SetLayoutManager(
+          std::make_unique<views::BoxLayout>(
+              views::BoxLayout::Orientation::kHorizontal,
+              gfx::Insets::VH(kVerticalMarginDip, kHorizontalMarginDip),
+              ChromeLayoutProvider::Get()->GetDistanceMetric(
+                  views::DISTANCE_RELATED_LABEL_HORIZONTAL)));
+  live_translate_container_layout->set_cross_axis_alignment(
+      views::BoxLayout::CrossAxisAlignment::kStart);
+
+  auto live_translate_image = std::make_unique<views::ImageView>();
+  live_translate_image->SetImage(ui::ImageModel::FromVectorIcon(
+      kTranslateChromeRefreshIcon, ui::kColorIcon, kImageWidthDip));
+  live_translate_container->AddChildView(std::move(live_translate_image));
+
+  auto live_translate_label_wrapper = std::make_unique<View>();
+  live_translate_label_wrapper->SetLayoutManager(
+      std::make_unique<views::BoxLayout>(
+          views::BoxLayout::Orientation::kVertical));
+  auto live_translate_title =
+      std::make_unique<views::Label>(l10n_util::GetStringUTF16(
+          IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_TRANSLATE_TITLE));
+  live_translate_title->SetHorizontalAlignment(
+      gfx::HorizontalAlignment::ALIGN_LEFT);
+  live_translate_title->SetMultiLine(true);
+  live_translate_title_ = live_translate_label_wrapper->AddChildView(
+      std::move(live_translate_title));
+
+  auto live_translate_subtitle =
+      std::make_unique<views::Label>(l10n_util::GetStringUTF16(
+          IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_SUBTITLE));
+  live_translate_subtitle->SetHorizontalAlignment(
+      gfx::HorizontalAlignment::ALIGN_LEFT);
+  live_translate_subtitle_ = live_translate_label_wrapper->AddChildView(
+      std::move(live_translate_subtitle));
+
+  live_translate_label_wrapper_ = live_translate_container->AddChildView(
+      std::move(live_translate_label_wrapper));
+  live_translate_container_layout->SetFlexForView(live_translate_label_wrapper_,
+                                                  1);
+
+  auto live_translate_button = std::make_unique<views::ToggleButton>(
+      base::BindRepeating(&MediaDialogView::OnLiveTranslateButtonPressed,
+                          base::Unretained(this)));
+  live_translate_button->SetIsOn(
+      profile_->GetPrefs()->GetBoolean(prefs::kLiveTranslateEnabled));
+  live_translate_button->SetAccessibleName(live_translate_title_->GetText());
+  live_translate_button_ =
+      live_translate_container->AddChildView(std::move(live_translate_button));
+  live_translate_container_ = AddChildView(std::move(live_translate_container));
+
+  // Initialize the target language container.
+  auto target_language_container = std::make_unique<View>();
+  target_language_container->SetBorder(
+      views::CreateEmptyBorder(gfx::Insets::TLBR(0, 0, kVerticalMarginDip, 0)));
+  target_language_container->SetVisible(
+      profile_->GetPrefs()->GetBoolean(prefs::kLiveTranslateEnabled));
+  target_language_container
+      ->SetLayoutManager(std::make_unique<views::BoxLayout>(
+          views::BoxLayout::Orientation::kVertical))
+      ->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kCenter);
+
+  auto target_language_model =
+      std::make_unique<LiveTranslateComboboxModel>(profile_);
+  auto target_language_combobox =
+      std::make_unique<views::Combobox>(std::move(target_language_model));
+  target_language_combobox->SetCallback(base::BindRepeating(
+      &MediaDialogView::TargetLanguageChanged, base::Unretained(this)));
+  target_language_combobox->SetAccessibleName(l10n_util::GetStringUTF16(
+      IDS_GLOBAL_MEDIA_CONTROLS_LIVE_TRANSLATE_TARGET_LANGUAGE_ACCNAME));
+  target_language_combobox_ = target_language_container->AddChildView(
+      std::move(target_language_combobox));
+  target_language_container_ =
+      AddChildView(std::move(target_language_container));
+}
+
+void MediaDialogView::InitializeCaptionSettingsSection() {
+  auto caption_settings_container = std::make_unique<View>();
+  caption_settings_container->SetLayoutManager(
+      std::make_unique<views::BoxLayout>(
+          views::BoxLayout::Orientation::kHorizontal,
+          gfx::Insets::VH(kVerticalMarginDip, 0)));
+  auto caption_settings_button = std::make_unique<RichHoverButton>(
+      base::BindRepeating(&MediaDialogView::OnSettingsButtonPressed,
+                          base::Unretained(this)),
+      ui::ImageModel::FromVectorIcon(vector_icons::kSettingsIcon,
+                                     ui::kColorIcon, kImageWidthDip),
+      l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_CAPTION_SETTINGS),
+      std::u16string(), std::u16string(), std::u16string(),
+      ui::ImageModel::FromVectorIcon(vector_icons::kLaunchIcon, ui::kColorIcon,
+                                     kImageWidthDip));
+  caption_settings_button_ = caption_settings_container->AddChildView(
+      std::move(caption_settings_button));
+  caption_settings_container_ =
+      AddChildView(std::move(caption_settings_container));
+}
+
 void MediaDialogView::SetLiveCaptionTitle(const std::u16string& new_text) {
   live_caption_title_->SetText(new_text);
   UpdateBubbleSize();
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.h b/chrome/browser/ui/views/global_media_controls/media_dialog_view.h
index e49301b..84a4e78b 100644
--- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.h
+++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.h
@@ -11,6 +11,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
+#include "chrome/browser/ui/global_media_controls/live_translate_combobox_model.h"
 #include "components/global_media_controls/public/constants.h"
 #include "components/global_media_controls/public/media_dialog_delegate.h"
 #include "components/global_media_controls/public/media_item_ui_observer.h"
@@ -19,6 +20,9 @@
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
 
+class PrefChangeRegistrar;
+class RichHoverButton;
+
 namespace content {
 class WebContents;
 }  // namespace content
@@ -30,7 +34,9 @@
 }  // namespace global_media_controls
 
 namespace views {
+class Combobox;
 class Label;
+class Separator;
 class ToggleButton;
 }  // namespace views
 
@@ -98,6 +104,8 @@
   void AddObserver(MediaDialogViewObserver* observer);
   void RemoveObserver(MediaDialogViewObserver* observer);
 
+  void TargetLanguageChanged();
+
   const std::map<const std::string, global_media_controls::MediaItemUIView*>&
   GetItemsForTesting() const;
 
@@ -129,10 +137,14 @@
 
   // views::Button::PressedCallback
   void OnLiveCaptionButtonPressed();
+  void OnLiveTranslateButtonPressed();
+  void OnSettingsButtonPressed();
 
-  void ToggleLiveCaption(bool enabled);
   void UpdateBubbleSize();
 
+  void OnLiveCaptionEnabledChanged();
+  void OnLiveTranslateEnabledChanged();
+
   // SodaInstaller::Observer overrides:
   void OnSodaInstalled(speech::LanguageCode language_code) override;
   void OnSodaInstallError(speech::LanguageCode language_code,
@@ -140,6 +152,9 @@
   void OnSodaProgress(speech::LanguageCode language_code,
                       int progress) override;
 
+  void InitializeLiveCaptionSection();
+  void InitializeLiveTranslateSection();
+  void InitializeCaptionSettingsSection();
   void SetLiveCaptionTitle(const std::u16string& new_text);
 
   std::unique_ptr<global_media_controls::MediaItemUIFooter> BuildFooterView(
@@ -153,6 +168,7 @@
   const raw_ptr<MediaNotificationService> service_;
 
   const raw_ptr<Profile> profile_;
+  std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
 
   const raw_ptr<global_media_controls::MediaItemUIListView>
       active_sessions_view_;
@@ -167,6 +183,20 @@
   raw_ptr<views::Label> live_caption_title_ = nullptr;
   raw_ptr<views::ToggleButton> live_caption_button_ = nullptr;
 
+  raw_ptr<views::Separator> separator_ = nullptr;
+  raw_ptr<views::View> live_translate_container_ = nullptr;
+  raw_ptr<views::View> live_translate_label_wrapper_ = nullptr;
+  raw_ptr<views::Label> live_translate_title_ = nullptr;
+  raw_ptr<views::Label> live_translate_subtitle_ = nullptr;
+  raw_ptr<views::ToggleButton> live_translate_button_ = nullptr;
+  raw_ptr<views::View> live_translate_settings_container_ = nullptr;
+
+  raw_ptr<views::View> target_language_container_ = nullptr;
+  raw_ptr<views::Combobox> target_language_combobox_ = nullptr;
+
+  raw_ptr<RichHoverButton> caption_settings_button_ = nullptr;
+  raw_ptr<views::View> caption_settings_container_ = nullptr;
+
   // It stores the WebContents* from which a MediaRouterDialogControllerViews
   // opened the dialog for a presentation request. It is nullptr if the dialog
   // is opened from the toolbar.
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
index 24625525..61d2f46 100644
--- a/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
@@ -32,6 +32,7 @@
 #include "components/feature_engagement/public/feature_constants.h"
 #include "components/global_media_controls/public/views/media_item_ui_list_view.h"
 #include "components/global_media_controls/public/views/media_item_ui_view.h"
+#include "components/live_caption/pref_names.h"
 #include "components/media_message_center/media_notification_view_impl.h"
 #include "components/media_router/browser/media_routes_observer.h"
 #include "components/media_router/browser/presentation/web_contents_presentation_manager.h"
@@ -341,7 +342,7 @@
     feature_list_.InitWithFeatures(
         {media::kGlobalMediaControls, media::kLiveCaption,
          feature_engagement::kIPHLiveCaptionFeature,
-         media::kLiveCaptionMultiLanguage},
+         media::kLiveCaptionMultiLanguage, media::kLiveTranslate},
         {});
   }
 
@@ -488,6 +489,14 @@
     ui_test_utils::ClickOnView(live_caption_button);
   }
 
+  void ClickEnableLiveTranslateOnDialog() {
+    base::RunLoop().RunUntilIdle();
+    ASSERT_TRUE(MediaDialogView::IsShowing());
+    views::Button* live_translate_button = static_cast<views::Button*>(
+        MediaDialogView::GetDialogViewForTesting()->live_translate_button_);
+    ui_test_utils::ClickOnView(live_translate_button);
+  }
+
   void ClickItemByTitle(const std::u16string& title) {
     ASSERT_TRUE(MediaDialogView::IsShowing());
     global_media_controls::MediaItemUIView* item = GetItemByTitle(title);
@@ -537,6 +546,10 @@
     return MediaDialogView::GetDialogViewForTesting()->live_caption_title_;
   }
 
+  views::Label* GetLiveTranslateTitleLabel() {
+    return MediaDialogView::GetDialogViewForTesting()->live_translate_title_;
+  }
+
   void OnSodaProgress(int progress) {
     speech::SodaInstaller::GetInstance()->NotifySodaProgressForTesting(
         progress);
@@ -1105,6 +1118,43 @@
             base::UTF16ToUTF8(GetLiveCaptionTitleLabel()->GetText()));
 }
 
+IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest, LiveTranslate) {
+  // Open a tab and play media.
+  OpenTestURL();
+  StartPlayback();
+  WaitForStart();
+  speech::SodaInstaller::GetInstance()->NeverDownloadSodaForTesting();
+
+  // Open the media dialog.
+  EXPECT_TRUE(ui_.WaitForToolbarIconShown());
+  ui_.ClickToolbarIcon();
+  EXPECT_TRUE(ui_.WaitForDialogOpened());
+  EXPECT_TRUE(ui_.IsDialogVisible());
+
+  // Click the Live Caption toggle to toggle it on.
+  ClickEnableLiveCaptionOnDialog();
+  EXPECT_TRUE(
+      browser()->profile()->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled));
+
+  // The Live Translate title should appear.
+  EXPECT_TRUE(GetLiveTranslateTitleLabel()->GetVisible());
+  EXPECT_EQ("Live Translate",
+            base::UTF16ToUTF8(GetLiveTranslateTitleLabel()->GetText()));
+
+  // Click the Live Translate toggle to toggle it on.
+  ClickEnableLiveTranslateOnDialog();
+  EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
+      prefs::kLiveTranslateEnabled));
+
+  // Click the Live Caption toggle to toggle it off, which toggles off Live
+  // Translate as well.
+  ClickEnableLiveCaptionOnDialog();
+  EXPECT_FALSE(
+      browser()->profile()->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled));
+  EXPECT_FALSE(browser()->profile()->GetPrefs()->GetBoolean(
+      prefs::kLiveTranslateEnabled));
+}
+
 class MediaDialogViewWithBackForwardCacheBrowserTest
     : public MediaDialogViewBrowserTest {
  protected:
diff --git a/chrome/browser/ui/views/intent_picker_dialog_browsertest.cc b/chrome/browser/ui/views/intent_picker_dialog_browsertest.cc
index 0009828d..01c0069 100644
--- a/chrome/browser/ui/views/intent_picker_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/intent_picker_dialog_browsertest.cc
@@ -25,7 +25,6 @@
 #include "content/public/test/browser_test_utils.h"
 #include "ui/base/models/image_model.h"
 #include "ui/events/test/event_generator.h"
-#include "ui/gfx/animation/animation_test_api.h"
 #include "ui/gfx/favicon_size.h"
 #include "ui/gfx/image/image.h"
 #include "ui/views/widget/widget_utils.h"
@@ -39,9 +38,6 @@
 
   // DialogBrowserTest:
   void ShowUi(const std::string& name) override {
-    animation_mode_reset_ = gfx::AnimationTestApi::SetRichAnimationRenderMode(
-        gfx::Animation::RichAnimationRenderMode::FORCE_DISABLED);
-
     std::vector<apps::IntentPickerAppInfo> app_info;
     const auto add_entry = [&app_info](const std::string& str) {
       auto icon_size = apps::GetIntentPickerBubbleIconSize();
@@ -70,9 +66,6 @@
         ->toolbar_button_provider()
         ->GetPageActionIconView(PageActionIconType::kIntentPicker);
   }
-
-  std::unique_ptr<base::AutoReset<gfx::Animation::RichAnimationRenderMode>>
-      animation_mode_reset_;
 };
 
 #if BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
index c996b26c..cddf9fc 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
@@ -172,13 +172,17 @@
     : popup_contents_view_(popup_contents_view),
       model_(model),
       model_index_(model_index) {
+  int left_margin = OmniboxMatchCellView::GetTextIndent();
+  // +4 for the focus bar width, which shifts the suggest text but isn't
+  // included in `GetTextIndent()`.
+  if (OmniboxFieldTrial::IsCr23LayoutEnabled())
+    left_margin += 4;
   int bottom_margin = ChromeLayoutProvider::Get()->GetDistanceMetric(
       DISTANCE_OMNIBOX_CELL_VERTICAL_PADDING);
   SetLayoutManager(std::make_unique<views::FlexLayout>())
       ->SetCrossAxisAlignment(views::LayoutAlignment::kStart)
       .SetCollapseMargins(true)
-      .SetInteriorMargin(gfx::Insets::TLBR(
-          0, OmniboxMatchCellView::GetTextIndent(), bottom_margin, 0))
+      .SetInteriorMargin(gfx::Insets::TLBR(0, left_margin, bottom_margin, 0))
       .SetDefault(
           views::kMarginsKey,
           gfx::Insets::VH(0, ChromeLayoutProvider::Get()->GetDistanceMetric(
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc b/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc
index 22516dd..6506d40 100644
--- a/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc
+++ b/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc
@@ -48,7 +48,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/text/bytes_formatting.h"
 #include "ui/gfx/animation/animation.h"
-#include "ui/gfx/animation/animation_test_api.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/styled_label.h"
@@ -690,9 +689,6 @@
         {{"discard_tab_treatment_option", base::NumberToString(static_cast<int>(
                                               GetParam().treatment_option))}});
 
-    animation_mode_reset_ = gfx::AnimationTestApi::SetRichAnimationRenderMode(
-        gfx::Animation::RichAnimationRenderMode::FORCE_DISABLED);
-
     HighEfficiencyInteractiveTest::SetUp();
   }
 
@@ -706,8 +702,6 @@
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
-  std::unique_ptr<base::AutoReset<gfx::Animation::RichAnimationRenderMode>>
-      animation_mode_reset_;
 };
 
 IN_PROC_BROWSER_TEST_P(HighEfficiencyFaviconTreatmentTest,
@@ -765,16 +759,11 @@
     scoped_feature_list_.InitAndEnableFeature(
         performance_manager::features::kMemorySavingsReportingImprovements);
 
-    animation_mode_reset_ = gfx::AnimationTestApi::SetRichAnimationRenderMode(
-        gfx::Animation::RichAnimationRenderMode::FORCE_DISABLED);
-
     HighEfficiencyInteractiveTest::SetUp();
   }
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
-  std::unique_ptr<base::AutoReset<gfx::Animation::RichAnimationRenderMode>>
-      animation_mode_reset_;
 };
 
 // The high efficiency chip dialog renders a gauge style visualization that
diff --git a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc
index 7e97dae..275f20f 100644
--- a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc
+++ b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc
@@ -30,6 +30,7 @@
 #include "content/public/browser/download_request_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
+#include "ui/base/clipboard/scoped_clipboard_writer.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/theme_provider.h"
@@ -181,6 +182,7 @@
 }
 
 void QRCodeGeneratorBubble::DisplayError(mojom::QRCodeGeneratorError error) {
+  copy_button_->SetEnabled(false);
   download_button_->SetEnabled(false);
   if (error == mojom::QRCodeGeneratorError::INPUT_TOO_LONG) {
     ShrinkAndHideDisplay(center_error_label_);
@@ -196,11 +198,12 @@
   center_error_label_->SetVisible(true);
 }
 
-void QRCodeGeneratorBubble::HideErrors(bool enable_download_button) {
+void QRCodeGeneratorBubble::HideErrors(bool enable_button) {
   ShrinkAndHideDisplay(center_error_label_);
   bottom_error_label_->SetVisible(false);
   bottom_error_label_->GetViewAccessibility().OverrideIsIgnored(true);
-  download_button_->SetEnabled(enable_download_button);
+  copy_button_->SetEnabled(enable_button);
+  download_button_->SetEnabled(enable_button);
 }
 
 void QRCodeGeneratorBubble::ShrinkAndHideDisplay(views::View* view) {
@@ -305,6 +308,9 @@
       AddChildView(std::make_unique<views::BoxLayoutView>());
   button_container->SetCrossAxisAlignment(
       views::BoxLayout::CrossAxisAlignment::kCenter);
+  button_container->SetBetweenChildSpacing(
+      ChromeLayoutProvider::Get()->GetDistanceMetric(
+          views::DISTANCE_RELATED_BUTTON_HORIZONTAL));
 
   // "More info" tooltip; looks like (i).
   auto tooltip_icon = std::make_unique<views::TooltipIcon>(
@@ -320,6 +326,15 @@
   auto* flex = button_container->AddChildView(std::make_unique<views::View>());
   button_container->SetFlexForView(flex, 1);
 
+  // Copy button.
+  copy_button_ =
+      button_container->AddChildView(std::make_unique<views::MdTextButton>(
+          base::BindRepeating(&QRCodeGeneratorBubble::CopyButtonPressed,
+                              base::Unretained(this)),
+          l10n_util::GetStringUTF16(
+              IDS_BROWSER_SHARING_QR_CODE_DIALOG_COPY_BUTTON_LABEL)));
+  copy_button_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
+
   // Download button.
   download_button_ =
       button_container->AddChildView(std::make_unique<views::MdTextButton>(
@@ -419,12 +434,22 @@
   qrcode_service_override_ = std::move(qrcode_service_override);
 }
 
-void QRCodeGeneratorBubble::DownloadButtonPressed() {
+const SkBitmap QRCodeGeneratorBubble::GetBitmap() {
   const gfx::ImageSkia& image_ref = qr_code_image_->GetImage();
   // Returns closest scaling to parameter (1.0).
   // Should be exact since we generated the bitmap.
   const gfx::ImageSkiaRep& image_rep = image_ref.GetRepresentation(1.0f);
-  const SkBitmap& bitmap = image_rep.GetBitmap();
+  return image_rep.GetBitmap();
+}
+
+// Copy image to system clipboard.
+void QRCodeGeneratorBubble::CopyButtonPressed() {
+  const SkBitmap& bitmap = GetBitmap();
+  ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste).WriteImage(bitmap);
+}
+
+void QRCodeGeneratorBubble::DownloadButtonPressed() {
+  const SkBitmap& bitmap = GetBitmap();
   const GURL data_url = GURL(webui::GetBitmapDataUrl(bitmap));
 
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
diff --git a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.h b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.h
index a24567f..4552c0e 100644
--- a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.h
+++ b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.h
@@ -114,6 +114,10 @@
   bool HandleMouseEvent(views::Textfield* sender,
                         const ui::MouseEvent& mouse_event) override;
 
+  const SkBitmap GetBitmap();
+
+  void CopyButtonPressed();
+
   void DownloadButtonPressed();
 
   void BackButtonPressed();
@@ -146,6 +150,7 @@
   // Pointers to view widgets; weak.
   raw_ptr<views::ImageView, DanglingUntriaged> qr_code_image_ = nullptr;
   raw_ptr<views::Textfield, DanglingUntriaged> textfield_url_ = nullptr;
+  raw_ptr<views::LabelButton, DanglingUntriaged> copy_button_ = nullptr;
   raw_ptr<views::LabelButton, DanglingUntriaged> download_button_ = nullptr;
   raw_ptr<views::TooltipIcon, DanglingUntriaged> tooltip_icon_ = nullptr;
   raw_ptr<views::Label, DanglingUntriaged> center_error_label_ = nullptr;
diff --git a/chrome/browser/ui/views/safe_browsing/OWNERS b/chrome/browser/ui/views/safe_browsing/OWNERS
index 5225674..9035c46 100644
--- a/chrome/browser/ui/views/safe_browsing/OWNERS
+++ b/chrome/browser/ui/views/safe_browsing/OWNERS
@@ -1 +1,3 @@
 file://components/safe_browsing/OWNERS
+
+per-file *tailored_security*=jacastro@chromium.org
diff --git a/chrome/browser/ui/views/toolbar/app_menu_browsertest.cc b/chrome/browser/ui/views/toolbar/app_menu_browsertest.cc
index fefac74f..23febf5 100644
--- a/chrome/browser/ui/views/toolbar/app_menu_browsertest.cc
+++ b/chrome/browser/ui/views/toolbar/app_menu_browsertest.cc
@@ -2,8 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string>
+#include <utility>
+
+#include "base/auto_reset.h"
+#include "base/containers/contains.h"
+#include "base/containers/fixed_flat_map.h"
 #include "base/files/file_path.h"
+#include "base/functional/callback.h"
+#include "base/memory/raw_ptr.h"
+#include "base/run_loop.h"
+#include "base/scoped_observation.h"
+#include "base/strings/string_piece.h"
 #include "base/test/scoped_feature_list.h"
+#include "build/branding_buildflags.h"
 #include "build/buildflag.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
@@ -11,36 +23,147 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/test/test_browser_ui.h"
+#include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/ui/views/frame/app_menu_button_observer.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/toolbar/app_menu.h"
 #include "chrome/browser/ui/views/toolbar/browser_app_menu_button.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
-#include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/password_manager/core/common/password_manager_features.h"
 #include "content/public/test/browser_test.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/views/controls/menu/menu_item_view.h"
 #include "ui/views/controls/menu/menu_runner.h"
-#include "url/gurl.h"
-
-using AppMenuBrowserTest = InProcessBrowserTest;
+#include "ui/views/controls/menu/submenu_view.h"
 
 namespace {
 
-bool TabRestoreServiceHasClosedWindow(sessions::TabRestoreService* service) {
-  for (const auto& entry : service->entries()) {
-    if (entry->type == sessions::TabRestoreService::WINDOW)
-      return true;
+class AppMenuBrowserTest : public UiBrowserTest {
+ public:
+  // UiBrowserTest:
+  void ShowUi(const std::string& name) override;
+  bool VerifyUi() override;
+  void WaitForUserDismissal() override;
+
+ protected:
+  // Changes the return value of `browser()` as long as the returned object is
+  // alive. This resetting behavior is necessary to null `browser_` before its
+  // destruction, lest the allocator complain about dangling refs.
+  [[nodiscard]] base::AutoReset<raw_ptr<Browser>> SetBrowser(Browser* browser) {
+    return base::AutoReset<raw_ptr<Browser>>(&browser_, browser);
   }
-  return false;
+
+  Browser* browser() {
+    return browser_ ? browser_.get() : UiBrowserTest::browser();
+  }
+
+  BrowserAppMenuButton* menu_button() {
+    return BrowserView::GetBrowserViewForBrowser(browser())
+        ->toolbar()
+        ->app_menu_button();
+  }
+
+ private:
+  raw_ptr<Browser> browser_ = nullptr;
+  absl::optional<int> command_id_;
+};
+
+void AppMenuBrowserTest::ShowUi(const std::string& name) {
+  // Include mnemonics in screenshots so that we detect changes to them.
+  menu_button()->ShowMenu(views::MenuRunner::SHOULD_SHOW_MNEMONICS);
+
+  if (base::StartsWith(name, "main")) {
+    return;
+  }
+
+  constexpr auto kSubmenus = base::MakeFixedFlatMap<base::StringPiece, int>({
+    // Submenus present in all versions.
+    {"history", IDC_RECENT_TABS_MENU}, {"bookmarks", IDC_BOOKMARKS_MENU},
+        {"more_tools", IDC_MORE_TOOLS_MENU},
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+        {"help", IDC_HELP_MENU},
+#endif
+
+        // Submenus only present after Chrome Refresh.
+        {"passwords_and_autofill", IDC_PASSWORDS_AND_AUTOFILL_MENU},
+        {"reading_list", IDC_READING_LIST_MENU},  // Inside the bookmarks menu.
+        {"extensions", IDC_EXTENSIONS_SUBMENU},
+        {"find_and_edit", IDC_FIND_AND_EDIT_MENU},
+  });
+  const auto* const id_entry = kSubmenus.find(name);
+  if (id_entry == kSubmenus.end()) {
+    ADD_FAILURE() << "Unknown submenu " << name;
+    return;
+  }
+  command_id_ = id_entry->second;
+  views::MenuItemView* const menu_root =
+      menu_button()->app_menu()->root_menu_item();
+  menu_root->GetMenuController()->SelectItemAndOpenSubmenu(
+      menu_root->GetMenuItemByID(command_id_.value()));
 }
 
-void ShowAppMenu(Browser* browser) {
-  BrowserView::GetBrowserViewForBrowser(browser)
-      ->toolbar()
-      ->app_menu_button()
-      ->ShowMenu(views::MenuRunner::NO_FLAGS);
+bool AppMenuBrowserTest::VerifyUi() {
+  if (!menu_button()->IsMenuShowing()) {
+    return false;
+  }
+  views::MenuItemView* menu_item = menu_button()->app_menu()->root_menu_item();
+  if (command_id_.has_value()) {
+    menu_item = menu_item->GetMenuItemByID(command_id_.value());
+  }
+  if (!menu_item->SubmenuIsShowing()) {
+    return false;
+  }
+
+  const auto* const test_info =
+      testing::UnitTest::GetInstance()->current_test_info();
+  return VerifyPixelUi(menu_item->GetSubmenu(), test_info->test_case_name(),
+                       test_info->name()) != ui::test::ActionResult::kFailed;
 }
 
-}  // namespace
+void AppMenuBrowserTest::WaitForUserDismissal() {
+  base::RunLoop run_loop;
+
+  class CloseWaiter : public AppMenuButtonObserver {
+   public:
+    explicit CloseWaiter(base::RepeatingClosure quit_closure)
+        : quit_closure_(std::move(quit_closure)) {}
+
+    // AppMenuButtonObserver:
+    void AppMenuClosed() override { quit_closure_.Run(); }
+
+   private:
+    const base::RepeatingClosure quit_closure_;
+  } waiter(run_loop.QuitClosure());
+
+  base::ScopedObservation<BrowserAppMenuButton, CloseWaiter> observation(
+      &waiter);
+  observation.Observe(menu_button());
+
+  run_loop.Run();
+}
+
+// Test case for menus that only appear after Chrome Refresh.
+class AppMenuBrowserTestRefreshOnly : public AppMenuBrowserTest {
+ public:
+  AppMenuBrowserTestRefreshOnly() {
+    // TODO(pkasting): It would be better if the tests below merely
+    // GTEST_SKIP()ed if the appropriate features weren't set, but in local
+    // testing that seemed to result in them always being skipped when the
+    // default feature state wasn't correct, even when setting the correct state
+    // via command-line flags. Probably I was doing something wrong...
+    scoped_feature_list_.InitWithFeatures(
+        {features::kChromeRefresh2023,
+         // Needed for the "extensions" test
+         features::kExtensionsMenuInAppMenu},
+        // Needed for the "passwords_and_autofill" test
+        {password_manager::features::kPasswordManagerRedesign});
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
 
 // This test shows the app-menu with a closed window added to the
 // TabRestoreService. This is a regression test to ensure menu code handles this
@@ -64,40 +187,69 @@
   EXPECT_TRUE(content::WaitForLoadStop(new_contents));
   chrome::CloseWindow(second_browser);
   ui_test_utils::WaitForBrowserToClose(second_browser);
-  EXPECT_TRUE(TabRestoreServiceHasClosedWindow(tab_restore_service));
+  EXPECT_TRUE(base::Contains(tab_restore_service->entries(),
+                             sessions::TabRestoreService::WINDOW,
+                             &sessions::TabRestoreService::Entry::type));
 
   // Show the AppMenu.
-  ShowAppMenu(browser());
+  menu_button()->ShowMenu(views::MenuRunner::NO_FLAGS);
 }
 
-class AppMenuChromeRefresh2023BrowserTest : public AppMenuBrowserTest {
- public:
-  AppMenuChromeRefresh2023BrowserTest() {
-    scoped_feature_list_.InitAndEnableFeature(features::kChromeRefresh2023);
-  }
+// There should be at least one subtest below for every distinct submenu of the
+// app menu; note that the "main" menu also counts as a submenu. More tests are
+// needed if a submenu can have distinct appearances that should all be tested,
+// e.g. if different profile data alters the menu appearance.
 
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-// Opens up the app menu with a standard user profile.
-IN_PROC_BROWSER_TEST_F(AppMenuChromeRefresh2023BrowserTest, TestProfileRow) {
-  ShowAppMenu(browser());
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTest, InvokeUi_main) {
+  ShowAndVerifyUi();
 }
 
-// Opens up the app menu with a guest profile.
-IN_PROC_BROWSER_TEST_F(AppMenuChromeRefresh2023BrowserTest,
-                       TestGuestProfileRow) {
-  // TODO(crbug.com/1427667): ChromeOS specific profile logic still needs to be
-  // updated, setup this test for a Guest user session with appropriate command
-  // line switches afterwards.
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTestRefreshOnly, InvokeUi_main_guest) {
+// TODO(crbug.com/1427667): ChromeOS specific profile logic still needs to be
+// updated, setup this test for a Guest user session with appropriate command
+// line switches afterwards.
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
-  ShowAppMenu(CreateGuestBrowser());
+  auto browser_resetter = SetBrowser(CreateGuestBrowser());
+  ShowAndVerifyUi();
 #endif
 }
 
-// Opens up the app menu with an incognito profile.
-IN_PROC_BROWSER_TEST_F(AppMenuChromeRefresh2023BrowserTest,
-                       TestIncognitoProfileRow) {
-  ShowAppMenu(CreateIncognitoBrowser(browser()->profile()));
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTestRefreshOnly, InvokeUi_main_incognito) {
+  auto browser_resetter = SetBrowser(CreateIncognitoBrowser());
+  ShowAndVerifyUi();
 }
+
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTest, InvokeUi_history) {
+  ShowAndVerifyUi();
+}
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTest, InvokeUi_bookmarks) {
+  ShowAndVerifyUi();
+}
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTest, InvokeUi_more_tools) {
+  ShowAndVerifyUi();
+}
+
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTest, InvokeUi_help) {
+  ShowAndVerifyUi();
+}
+#endif
+
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTestRefreshOnly,
+                       InvokeUi_passwords_and_autofill) {
+  ShowAndVerifyUi();
+}
+
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTestRefreshOnly, InvokeUi_reading_list) {
+  ShowAndVerifyUi();
+}
+
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTestRefreshOnly, InvokeUi_extensions) {
+  ShowAndVerifyUi();
+}
+
+IN_PROC_BROWSER_TEST_F(AppMenuBrowserTestRefreshOnly, InvokeUi_find_and_edit) {
+  ShowAndVerifyUi();
+}
+
+}  // namespace
diff --git a/chrome/browser/ui/views/toolbar/avatar_toolbar_button_browsertest.cc b/chrome/browser/ui/views/toolbar/avatar_toolbar_button_browsertest.cc
index 27301fc..76052aca 100644
--- a/chrome/browser/ui/views/toolbar/avatar_toolbar_button_browsertest.cc
+++ b/chrome/browser/ui/views/toolbar/avatar_toolbar_button_browsertest.cc
@@ -43,7 +43,7 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(AvatarToolbarButtonBrowserTest, IncogntioWindowCount) {
+IN_PROC_BROWSER_TEST_F(AvatarToolbarButtonBrowserTest, IncognitoWindowCount) {
   Profile* profile = browser()->profile();
   Browser* browser1 = CreateIncognitoBrowser(profile);
   EXPECT_FALSE(GetWindowCountInAvatarButtonText(browser1).has_value());
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc
index 6c555cd..cb57edd4 100644
--- a/chrome/browser/ui/web_applications/web_app_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -1878,7 +1878,8 @@
   EXPECT_TRUE(app_menu_model->GetModelAndIndexForCommandId(IDC_INSTALL_PWA,
                                                            &model, &index));
   EXPECT_EQ(app_menu_model.get(), model);
-  EXPECT_EQ(model->GetLabelAt(index), u"Install Manifest test app…");
+  const std::u16string label = model->GetLabelAt(index);
+  EXPECT_NE(std::u16string::npos, label.find(u"Manifest test"));
 }
 
 // Check that no assertions are hit when showing a permission request bubble.
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.cc b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
index 0f32925..0182d04 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_utils.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
@@ -216,12 +216,13 @@
 
 }  // namespace
 
-absl::optional<AppId> GetWebAppForActiveTab(Browser* browser) {
-  WebAppProvider* provider = WebAppProvider::GetForWebApps(browser->profile());
+absl::optional<AppId> GetWebAppForActiveTab(const Browser* browser) {
+  const WebAppProvider* const provider =
+      WebAppProvider::GetForWebApps(browser->profile());
   if (!provider)
     return absl::nullopt;
 
-  content::WebContents* web_contents =
+  const content::WebContents* const web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
   if (!web_contents)
     return absl::nullopt;
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.h b/chrome/browser/ui/web_applications/web_app_launch_utils.h
index 3655fc0..870cc32 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_utils.h
+++ b/chrome/browser/ui/web_applications/web_app_launch_utils.h
@@ -28,7 +28,7 @@
 
 class AppBrowserController;
 
-absl::optional<AppId> GetWebAppForActiveTab(Browser* browser);
+absl::optional<AppId> GetWebAppForActiveTab(const Browser* browser);
 
 // Clears navigation history prior to user entering app scope.
 void PrunePreScopeNavigationHistory(const GURL& scope,
diff --git a/chrome/browser/ui/webui/ash/diagnostics_dialog.cc b/chrome/browser/ui/webui/ash/diagnostics_dialog.cc
index e7c99d6..57fb6e2 100644
--- a/chrome/browser/ui/webui/ash/diagnostics_dialog.cc
+++ b/chrome/browser/ui/webui/ash/diagnostics_dialog.cc
@@ -6,7 +6,6 @@
 
 #include <string>
 
-#include "ash/constants/ash_features.h"
 #include "ash/system/diagnostics/diagnostics_log_controller.h"
 #include "ash/webui/diagnostics_ui/diagnostics_ui.h"
 #include "ash/webui/diagnostics_ui/url_constants.h"
@@ -56,10 +55,7 @@
   DiagnosticsDialog* dialog = new DiagnosticsDialog(page);
 
   // Ensure log controller configuration matches current session.
-  if (features::IsLogControllerForDiagnosticsAppEnabled()) {
-    diagnostics::DiagnosticsLogController::Get()
-        ->ResetAndInitializeLogWriters();
-  }
+  diagnostics::DiagnosticsLogController::Get()->ResetAndInitializeLogWriters();
 
   dialog->ShowSystemDialog(parent);
 }
diff --git a/chrome/browser/ui/webui/ash/login/auto_enrollment_check_screen_handler.cc b/chrome/browser/ui/webui/ash/login/auto_enrollment_check_screen_handler.cc
index d251d8a6..986e524 100644
--- a/chrome/browser/ui/webui/ash/login/auto_enrollment_check_screen_handler.cc
+++ b/chrome/browser/ui/webui/ash/login/auto_enrollment_check_screen_handler.cc
@@ -21,6 +21,7 @@
     ::login::LocalizedValuesBuilder* builder) {
   builder->Add("autoEnrollmentCheckMessage",
                IDS_AUTO_ENROLLMENT_CHECK_SCREEN_MESSAGE);
+  builder->Add("gettingDeviceReadyTitle", IDS_GETTING_DEVICE_READY);
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ui/webui/ash/login/oobe_ui.cc b/chrome/browser/ui/webui/ash/login/oobe_ui.cc
index adb669f..cce92e4 100644
--- a/chrome/browser/ui/webui/ash/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/ash/login/oobe_ui.cc
@@ -317,6 +317,9 @@
   source->AddBoolean("isDisplaySizeEnabled",
                      features::IsOobeDisplaySizeEnabled());
 
+  source->AddBoolean("isOobeSoftwareUpdateEnabled",
+                     features::IsOobeSoftwareUpdateEnabled());
+
   // Configure shared resources
   AddProductLogoResources(source);
   if (ash::features::IsOobeSimonEnabled()) {
@@ -777,8 +780,11 @@
 }
 
 bool OobeUI::IsJSReady(base::OnceClosure display_is_ready_callback) {
-  if (!ready_)
+  if (!ready_) {
     ready_callbacks_.AddUnsafe(std::move(display_is_ready_callback));
+    return ready_;
+  }
+  std::move(display_is_ready_callback).Run();
   return ready_;
 }
 
diff --git a/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.cc b/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.cc
index 0613cc8..95f1cef 100644
--- a/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.cc
+++ b/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.cc
@@ -40,6 +40,11 @@
   CallExternalAPI("setQRCode", std::move(blob));
 }
 
+void QuickStartScreenHandler::SetDiscoverableName(
+    const std::string& discoverable_name) {
+  CallExternalAPI("setDiscoverableName", discoverable_name);
+}
+
 void QuickStartScreenHandler::ShowConnectingToWifi() {
   CallExternalAPI("showConnectingToWifi");
 }
diff --git a/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h b/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h
index 09087393..d8dc219 100644
--- a/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h
+++ b/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h
@@ -27,6 +27,7 @@
   virtual void Show() = 0;
   virtual void SetShapes(const quick_start::ShapeList& shape_list) = 0;
   virtual void SetQRCode(base::Value::List blob) = 0;
+  virtual void SetDiscoverableName(const std::string& discoverable_name) = 0;
   virtual void ShowConnectingToWifi() = 0;
   virtual void ShowConnectedToWifi(std::string ssid, std::string password) = 0;
 };
@@ -48,6 +49,7 @@
   void Show() override;
   void SetShapes(const quick_start::ShapeList& shape_list) override;
   void SetQRCode(base::Value::List blob) override;
+  void SetDiscoverableName(const std::string& discoverable_name) override;
   void ShowConnectingToWifi() override;
   void ShowConnectedToWifi(std::string ssid, std::string password) override;
 
diff --git a/chrome/browser/ui/webui/ash/login/update_screen_handler.cc b/chrome/browser/ui/webui/ash/login/update_screen_handler.cc
index d67f3c1..3f5668f 100644
--- a/chrome/browser/ui/webui/ash/login/update_screen_handler.cc
+++ b/chrome/browser/ui/webui/ash/login/update_screen_handler.cc
@@ -122,6 +122,8 @@
   builder->Add("slideUnselectedButtonLabel",
                IDS_UPDATE_UNSELECTED_BUTTON_LABEL);
 
+  builder->Add("gettingDeviceReadyTitle", IDS_GETTING_DEVICE_READY);
+
   builder->Add("updateOverCellularPromptTitle",
                IDS_UPDATE_OVER_CELLULAR_PROMPT_TITLE);
   builder->Add("updateOverCellularPromptMessage",
diff --git a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
index bd45226..d83e6ba3 100644
--- a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
+++ b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
@@ -34,6 +34,7 @@
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "media/base/media_switches.h"
+#include "printing/buildflags/buildflags.h"
 #include "ui/accessibility/accessibility_features.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -47,14 +48,14 @@
 
 class NavigationObserver : public content::WebContentsObserver {
  public:
-  enum NavigationResult {
-    NOT_FINISHED,
-    ERROR_PAGE,
-    SUCCESS,
+  enum class Result {
+    kNotFinished,
+    kErrorPage,
+    kSuccess,
   };
 
   explicit NavigationObserver(content::WebContents* web_contents)
-      : WebContentsObserver(web_contents), navigation_result_(NOT_FINISHED) {}
+      : WebContentsObserver(web_contents) {}
 
   NavigationObserver(const NavigationObserver&) = delete;
   NavigationObserver& operator=(const NavigationObserver&) = delete;
@@ -66,8 +67,8 @@
     if (!navigation_handle->IsInPrimaryMainFrame()) {
       return;
     }
-    navigation_result_ =
-        navigation_handle->IsErrorPage() ? ERROR_PAGE : SUCCESS;
+    navigation_result_ = navigation_handle->IsErrorPage() ? Result::kErrorPage
+                                                          : Result::kSuccess;
     net_error_ = navigation_handle->GetNetErrorCode();
     got_navigation_ = true;
     if (navigation_handle->HasCommitted() &&
@@ -78,18 +79,18 @@
     }
   }
 
-  NavigationResult navigation_result() const { return navigation_result_; }
+  Result navigation_result() const { return navigation_result_; }
   net::Error net_error() const { return net_error_; }
   bool got_navigation() const { return got_navigation_; }
   int http_status_code() const { return http_status_code_; }
 
   void Reset() {
-    navigation_result_ = NOT_FINISHED;
+    navigation_result_ = Result::kNotFinished;
     net_error_ = net::OK;
   }
 
  private:
-  NavigationResult navigation_result_;
+  Result navigation_result_ = Result::kNotFinished;
   net::Error net_error_ = net::OK;
   bool got_navigation_ = false;
   int http_status_code_ = -1;
@@ -124,14 +125,15 @@
       browser()->tab_strip_model()->GetActiveWebContents());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), GURL("chrome://theme/IDR_SETTINGS_FAVICON")));
-  EXPECT_EQ(NavigationObserver::SUCCESS, observer.navigation_result());
+  EXPECT_EQ(NavigationObserver::Result::kSuccess, observer.navigation_result());
   EXPECT_EQ(net::OK, observer.net_error());
 
   // Unknown resource
   observer.Reset();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), GURL("chrome://theme/IDR_ASDFGHJKL")));
-  EXPECT_EQ(NavigationObserver::ERROR_PAGE, observer.navigation_result());
+  EXPECT_EQ(NavigationObserver::Result::kErrorPage,
+            observer.navigation_result());
   // The presence of net error means that navigation did not commit to the
   // original url.
   EXPECT_NE(net::OK, observer.net_error());
@@ -144,14 +146,15 @@
       browser()->tab_strip_model()->GetActiveWebContents());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), GURL("chrome://theme/IDR_SETTINGS_FAVICON@2x")));
-  EXPECT_EQ(NavigationObserver::SUCCESS, observer.navigation_result());
+  EXPECT_EQ(NavigationObserver::Result::kSuccess, observer.navigation_result());
   EXPECT_EQ(net::OK, observer.net_error());
 
   // Unreasonably large scale
   observer.Reset();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), GURL("chrome://theme/IDR_SETTINGS_FAVICON@99999x")));
-  EXPECT_EQ(NavigationObserver::ERROR_PAGE, observer.navigation_result());
+  EXPECT_EQ(NavigationObserver::Result::kErrorPage,
+            observer.navigation_result());
   // The presence of net error means that navigation did not commit to the
   // original url.
   EXPECT_NE(net::OK, observer.net_error());
@@ -173,8 +176,9 @@
     enabled_features.push_back(user_notes::kUserNotes);
 
 #if !BUILDFLAG(IS_CHROMEOS)
-    if (GetParam() == std::string("chrome://welcome"))
+    if (GetParam() == base::StringPiece("chrome://welcome")) {
       enabled_features.push_back(welcome::kForceEnabled);
+    }
 #endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     enabled_features.push_back(ash::features::kDriveFsMirroring);
@@ -187,13 +191,12 @@
   }
 
   void CheckNoTrustedTypesViolation(base::StringPiece url) {
-    std::string message_filter1 = "*This document requires*assignment*";
-    std::string message_filter2 = "*Refused to create a TrustedTypePolicy*";
+    const std::string kMessageFilter =
+        "*Refused to create a TrustedTypePolicy*";
     content::WebContents* content =
         browser()->tab_strip_model()->GetActiveWebContents();
     content::WebContentsConsoleObserver console_observer(content);
-    console_observer.SetPattern(message_filter1);
-    console_observer.SetPattern(message_filter2);
+    console_observer.SetPattern(kMessageFilter);
 
     ASSERT_TRUE(embedded_test_server()->Start());
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(url)));
@@ -316,7 +319,6 @@
     "chrome://policy",
     "chrome://predictors",
     "chrome://prefs-internals",
-    "chrome://print",
     "chrome://privacy-sandbox-dialog/?debug",
     "chrome://process-internals",
     "chrome://quota-internals",
@@ -449,6 +451,9 @@
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
     "chrome://webuijserror",
 #endif
+#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
+    "chrome://print",
+#endif
 };
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
index 59e911b..5498a85 100644
--- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
+++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -617,10 +617,16 @@
     }
   }
 
+  bool show_banner = false;
+  std::string show_banner_string;
+  if (net::GetValueForKeyInQuery(url, "show_banner", &show_banner_string)) {
+    show_banner = show_banner_string == "1";
+  }
+
   return supervised_user::BuildErrorPageHtml(
       allow_access_requests, profile_image_url, profile_image_url2, custodian,
       custodian_email, second_custodian, second_custodian_email, reason,
       g_browser_process->GetApplicationLocale(), /*already_sent_request=*/false,
-      /*is_main_frame=*/true);
+      /*is_main_frame=*/true, show_banner);
 }
 #endif
diff --git a/chrome/browser/ui/webui/nearby_share/nearby_share.mojom b/chrome/browser/ui/webui/nearby_share/nearby_share.mojom
index ae255eb..55cf7221 100644
--- a/chrome/browser/ui/webui/nearby_share/nearby_share.mojom
+++ b/chrome/browser/ui/webui/nearby_share/nearby_share.mojom
@@ -38,6 +38,8 @@
   url.mojom.Url? image_url;
   // Payload preview for the attachment(s).
   PayloadPreview payload_preview;
+  // True if the remote device is signed into the same Gaia account as the user.
+  bool for_self_share;
 };
 
 // Result of selecting a share target.
diff --git a/chrome/browser/ui/webui/nearby_share/nearby_share_dialog_ui.cc b/chrome/browser/ui/webui/nearby_share/nearby_share_dialog_ui.cc
index 2985ee5..9e0d7973 100644
--- a/chrome/browser/ui/webui/nearby_share/nearby_share_dialog_ui.cc
+++ b/chrome/browser/ui/webui/nearby_share/nearby_share_dialog_ui.cc
@@ -117,6 +117,10 @@
 
   const GURL& url = web_ui->GetWebContents()->GetVisibleURL();
   SetAttachmentFromQueryParameter(url);
+
+  html_source->AddBoolean(
+      "isSelfShareEnabled",
+      base::FeatureList::IsEnabled(features::kNearbySharingSelfShareUI));
 }
 
 NearbyShareDialogUI::~NearbyShareDialogUI() = default;
diff --git a/chrome/browser/ui/webui/nearby_share/nearby_share_mojom_traits.cc b/chrome/browser/ui/webui/nearby_share/nearby_share_mojom_traits.cc
index 14c15fe..c56c550 100644
--- a/chrome/browser/ui/webui/nearby_share/nearby_share_mojom_traits.cc
+++ b/chrome/browser/ui/webui/nearby_share/nearby_share_mojom_traits.cc
@@ -65,8 +65,9 @@
   }
 
   // If there are no attachments, return an empty text preview.
-  if (!attachment)
+  if (!attachment) {
     return payload_preview;
+  }
 
   payload_preview->description = attachment->GetDescription();
 
@@ -82,6 +83,13 @@
 }
 
 // static
+bool mojo::StructTraits<nearby_share::mojom::ShareTargetDataView,
+                        ShareTarget>::for_self_share(const ShareTarget&
+                                                         share_target) {
+  return share_target.for_self_share;
+}
+
+// static
 bool StructTraits<nearby_share::mojom::ShareTargetDataView, ShareTarget>::Read(
     nearby_share::mojom::ShareTargetDataView data,
     ShareTarget* out) {
diff --git a/chrome/browser/ui/webui/nearby_share/nearby_share_mojom_traits.h b/chrome/browser/ui/webui/nearby_share/nearby_share_mojom_traits.h
index 1581b98..f71a352 100644
--- a/chrome/browser/ui/webui/nearby_share/nearby_share_mojom_traits.h
+++ b/chrome/browser/ui/webui/nearby_share/nearby_share_mojom_traits.h
@@ -25,6 +25,7 @@
       const ShareTarget& share_target);
   static nearby_share::mojom::PayloadPreviewPtr payload_preview(
       const ShareTarget& share_target);
+  static bool for_self_share(const ShareTarget& share_target);
   static bool Read(nearby_share::mojom::ShareTargetDataView data,
                    ShareTarget* out);
 };
diff --git a/chrome/browser/ui/webui/settings/ash/accessibility_section.cc b/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
index 5ab8175..ba7e3982 100644
--- a/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
@@ -727,6 +727,8 @@
        IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION},
       {"focusHighlightLabelSubtext",
        IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION_SUBTEXT},
+      {"focusHighlightDisabledByChromevoxTooltip",
+       IDS_SETTINGS_FOCUS_HIGHLIGHT_DISABLED_BY_CHROMEVOX_TOOLTIP},
       {"greyscaleLabel", IDS_SETTINGS_GREYSCALE_LABEL},
       {"highContrastDescription", IDS_SETTINGS_HIGH_CONTRAST_DESCRIPTION},
       {"highContrastLabel", IDS_SETTINGS_HIGH_CONTRAST_LABEL},
@@ -883,6 +885,8 @@
       {"startupSoundLabel", IDS_SETTINGS_STARTUP_SOUND_LABEL},
       {"stickyKeysDescription", IDS_SETTINGS_STICKY_KEYS_DESCRIPTION},
       {"stickyKeysLabel", IDS_SETTINGS_STICKY_KEYS_LABEL},
+      {"stickyKeysDisabledByChromevoxTooltip",
+       IDS_SETTINGS_STICKY_KEYS_DISABLED_BY_CHROMEVOX_TOOLTIP},
       {"switchAccessActionAssignmentAddAssignmentIconLabel",
        IDS_SETTINGS_SWITCH_ACCESS_ACTION_ASSIGNMENT_ADD_ASSIGNMENT_ICON_LABEL},
       {"switchAccessActionAssignmentAssignedIconLabel",
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper_unittest.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper_unittest.cc
index 7d79ac9..46b7e1a 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper_unittest.cc
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper_unittest.cc
@@ -111,9 +111,8 @@
 
 TEST_F(WebAppPublisherHelperTest, CreateWebApp_Random) {
   for (uint32_t seed = 0; seed < 100; ++seed) {
-    const GURL base_url("https://example.com/base_url");
     std::unique_ptr<WebApp> random_app =
-        test::CreateRandomWebApp({base_url, seed});
+        test::CreateRandomWebApp({.seed = seed});
 
     auto info = std::make_unique<WebAppInstallInfo>();
     info->title = base::UTF8ToUTF16(random_app->untranslated_name());
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.h b/chrome/browser/web_applications/test/web_app_test_utils.h
index a1019fb..91ff530e 100644
--- a/chrome/browser/web_applications/test/web_app_test_utils.h
+++ b/chrome/browser/web_applications/test/web_app_test_utils.h
@@ -65,8 +65,8 @@
 // Do not use this for installation! Instead, use the utilities in
 // web_app_install_test_util.h.
 struct CreateRandomWebAppParams {
-  const GURL& base_url;
-  uint32_t seed;
+  const GURL& base_url = GURL("https://example.com/path");
+  uint32_t seed = 0;
   bool non_zero = false;
   bool allow_system_source = true;
 };
diff --git a/chrome/browser/web_applications/web_app_database_unittest.cc b/chrome/browser/web_applications/web_app_database_unittest.cc
index cc13d18..9b88499 100644
--- a/chrome/browser/web_applications/web_app_database_unittest.cc
+++ b/chrome/browser/web_applications/web_app_database_unittest.cc
@@ -103,14 +103,13 @@
     run_loop.Run();
   }
 
-  Registry WriteWebApps(const GURL& base_url, uint32_t num_apps) {
+  Registry WriteWebApps(uint32_t num_apps) {
     Registry registry;
 
     auto write_batch = database_factory().GetStore()->CreateWriteBatch();
 
     for (uint32_t i = 0; i < num_apps; ++i) {
-      std::unique_ptr<WebApp> app =
-          test::CreateRandomWebApp({.base_url = base_url, .seed = i});
+      std::unique_ptr<WebApp> app = test::CreateRandomWebApp({.seed = i});
       std::unique_ptr<WebAppProto> proto =
           WebAppDatabase::CreateWebAppProto(*app);
       const AppId app_id = app->app_id();
@@ -171,17 +170,14 @@
   EXPECT_TRUE(registrar().is_empty());
 
   const uint32_t num_apps = 100;
-  const GURL base_url("https://example.com/path");
 
-  std::unique_ptr<WebApp> app =
-      test::CreateRandomWebApp({.base_url = base_url, .seed = 0});
+  std::unique_ptr<WebApp> app = test::CreateRandomWebApp({.seed = 0});
   AppId app_id = app->app_id();
   RegisterApp(std::move(app));
   EXPECT_TRUE(IsDatabaseRegistryEqualToRegistrar());
 
   for (uint32_t i = 1; i <= num_apps; ++i) {
-    std::unique_ptr<WebApp> extra_app =
-        test::CreateRandomWebApp({.base_url = base_url, .seed = i});
+    std::unique_ptr<WebApp> extra_app = test::CreateRandomWebApp({.seed = i});
     RegisterApp(std::move(extra_app));
   }
   EXPECT_TRUE(IsDatabaseRegistryEqualToRegistrar());
@@ -198,7 +194,6 @@
   EXPECT_TRUE(registrar().is_empty());
 
   const uint32_t num_apps = 100;
-  const GURL base_url("https://example.com/path");
 
   RegistryUpdateData::Apps apps_to_create;
   std::vector<AppId> apps_to_delete;
@@ -211,18 +206,13 @@
 #endif
 
   for (uint32_t i = 0; i < num_apps; ++i) {
-    std::unique_ptr<WebApp> app =
-        test::CreateRandomWebApp({.base_url = base_url,
-                                  .seed = i,
-                                  .allow_system_source = allow_system_source});
+    std::unique_ptr<WebApp> app = test::CreateRandomWebApp(
+        {.seed = i, .allow_system_source = allow_system_source});
     apps_to_delete.push_back(app->app_id());
     apps_to_create.push_back(std::move(app));
 
-    std::unique_ptr<WebApp> expected_app =
-        test::CreateRandomWebApp({.base_url = base_url,
-                                  .seed = i,
-                                  .non_zero = false,
-                                  .allow_system_source = allow_system_source});
+    std::unique_ptr<WebApp> expected_app = test::CreateRandomWebApp(
+        {.seed = i, .allow_system_source = allow_system_source});
     expected_registry.emplace(expected_app->app_id(), std::move(expected_app));
   }
 
@@ -266,7 +256,7 @@
 }
 
 TEST_F(WebAppDatabaseTest, OpenDatabaseAndReadRegistry) {
-  Registry registry = WriteWebApps(GURL("https://example.com/path"), 100);
+  Registry registry = WriteWebApps(100);
 
   InitSyncBridge();
   EXPECT_TRUE(IsRegistryEqual(mutable_registrar().registry(), registry));
@@ -479,7 +469,7 @@
   const int num_icons = 32;
 
   std::unique_ptr<WebApp> app =
-      test::CreateRandomWebApp({.base_url = base_url, .seed = 0});
+      test::CreateRandomWebApp({.base_url = base_url});
   AppId app_id = app->app_id();
 
   std::vector<apps::IconInfo> icons;
@@ -520,8 +510,7 @@
 }
 
 TEST_F(WebAppDatabaseTest, MigrateOldLaunchHandlerSyntax) {
-  std::unique_ptr<WebApp> base_app = test::CreateRandomWebApp(
-      {.base_url = GURL("https://example.com"), .seed = 0});
+  std::unique_ptr<WebApp> base_app = test::CreateRandomWebApp({});
   std::unique_ptr<WebAppProto> base_proto =
       WebAppDatabase::CreateWebAppProto(*base_app);
 
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc
index b940b37..e402f8b 100644
--- a/chrome/browser/web_applications/web_app_unittest.cc
+++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -305,9 +305,7 @@
   const base::FilePath path_to_test_file =
       GetPathToTestFile("sample_web_app.json");
   const base::Value web_app_debug_value = WebAppToPlatformAgnosticDebugValue(
-      test::CreateRandomWebApp({.base_url = GURL("https://example.com/"),
-                                .seed = 1234,
-                                .non_zero = true}));
+      test::CreateRandomWebApp({.seed = 1234, .non_zero = true}));
 
   if (IsRebaseline()) {
     LOG(INFO) << "Generating expectations sample web app unit test in "
@@ -323,6 +321,16 @@
       << kGenerateExpectationsMessage;
 }
 
+TEST(WebAppTest, RandomAppAsDebugValue_NoCrash) {
+  for (uint32_t seed = 0; seed < 1000; ++seed) {
+    const base::Value web_app_debug_value =
+        test::CreateRandomWebApp({.seed = seed})->AsDebugValue();
+
+    EXPECT_TRUE(web_app_debug_value.is_dict());
+    EXPECT_TRUE(base::ToString(web_app_debug_value).length() > 10);
+  }
+}
+
 TEST(WebAppTest, IsolationDataStartsEmpty) {
   WebApp app{GenerateAppId(/*manifest_id=*/absl::nullopt,
                            GURL("https://example.com"))};
diff --git a/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc b/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc
index f854c20..eaff51e 100644
--- a/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc
+++ b/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc
@@ -59,15 +59,18 @@
   webauthn_account_selection_callback_ = std::move(callback);
 
   std::vector<PasskeyCredential> display_credentials;
-  base::ranges::transform(credentials, std::back_inserter(display_credentials),
-                          [](const auto& credential) {
-                            return PasskeyCredential(
-                                PasskeyCredential::Source::kAndroidPhone,
-                                credential.rp_id, credential.cred_id,
-                                credential.user.id,
-                                credential.user.name.value_or(""),
-                                credential.user.display_name.value_or(""));
-                          });
+  base::ranges::transform(
+      credentials, std::back_inserter(display_credentials),
+      [](const auto& credential) {
+        return PasskeyCredential(
+            PasskeyCredential::Source::kAndroidPhone,
+            PasskeyCredential::RpId(credential.rp_id),
+            PasskeyCredential::CredentialId(credential.cred_id),
+            PasskeyCredential::UserId(credential.user.id),
+            PasskeyCredential::Username(credential.user.name.value_or("")),
+            PasskeyCredential::DisplayName(
+                credential.user.display_name.value_or("")));
+      });
 
   if (is_conditional_request) {
     conditional_request_in_progress_ = true;
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
index 73abc54e..7f49a94 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -989,6 +989,16 @@
                                                    size_t mechanism_index) {
   current_mechanism_ = mechanism_index;
 
+#if BUILDFLAG(IS_MAC)
+  if (transport_availability()->ble_access_denied) {
+    // |step| is not saved because macOS asks the user to restart Chrome
+    // after permission has been granted. So the user will end up retrying
+    // the whole WebAuthn request in the new process.
+    SetCurrentStep(Step::kBlePermissionMac);
+    return;
+  }
+#endif
+
   if (transport_availability_.request_type ==
           device::FidoRequestType::kMakeCredential &&
       transport_availability_.is_off_the_record_context) {
@@ -1045,10 +1055,15 @@
         ephemeral_state_.creds_, std::back_inserter(credentials),
         [](const auto& credential) {
           return password_manager::PasskeyCredential(
-              ToPasswordManagerSource(credential.source), credential.rp_id,
-              credential.cred_id, credential.user.id,
-              credential.user.name.value_or(""),
-              credential.user.display_name.value_or(""));
+              ToPasswordManagerSource(credential.source),
+              password_manager::PasskeyCredential::RpId(credential.rp_id),
+              password_manager::PasskeyCredential::CredentialId(
+                  credential.cred_id),
+              password_manager::PasskeyCredential::UserId(credential.user.id),
+              password_manager::PasskeyCredential::Username(
+                  credential.user.name.value_or("")),
+              password_manager::PasskeyCredential::DisplayName(
+                  credential.user.display_name.value_or("")));
         });
     ReportConditionalUiPasskeyCount(credentials.size());
     ChromeWebAuthnCredentialsDelegateFactory::GetFactory(web_contents)
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
index cfc8486..6a73d797 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -1233,3 +1233,56 @@
   EXPECT_EQ(model.current_step(), Step::kCableActivate);
   EXPECT_EQ(model.selected_phone_name(), "phone");
 }
+
+#if BUILDFLAG(IS_MAC)
+TEST_F(AuthenticatorRequestDialogModelTest, BluetoothPermissionPrompt) {
+  // When BLE permission is denied on macOS, we should jump to the sheet that
+  // explains that if the user tries to use a linked phone or tries to show the
+  // QR code.
+  for (const bool ble_access_denied : {false, true}) {
+    for (const bool click_specific_phone : {false, true}) {
+      SCOPED_TRACE(::testing::Message()
+                   << "ble_access_denied=" << ble_access_denied);
+      SCOPED_TRACE(::testing::Message()
+                   << "click_specific_phone=" << click_specific_phone);
+
+      AuthenticatorRequestDialogModel model(/*render_frame_host=*/nullptr);
+      std::vector<AuthenticatorRequestDialogModel::PairedPhone> phones(
+          {{"phone", /*contact_id=*/0, /*public_key_x962=*/{{0}}}});
+      model.set_cable_transport_info(/*extension_is_v2=*/absl::nullopt,
+                                     std::move(phones), base::DoNothing(),
+                                     absl::nullopt);
+      TransportAvailabilityInfo transports_info;
+      transports_info.is_ble_powered = true;
+      transports_info.ble_access_denied = ble_access_denied;
+      transports_info.request_type = device::FidoRequestType::kGetAssertion;
+      transports_info.available_transports = {
+          AuthenticatorTransport::kHybrid,
+          AuthenticatorTransport::kUsbHumanInterfaceDevice};
+      model.StartFlow(std::move(transports_info),
+                      /*is_conditional_mediation=*/false);
+
+      base::ranges::find_if(
+          model.mechanisms(),
+          [click_specific_phone](const auto& m) -> bool {
+            if (click_specific_phone) {
+              return absl::holds_alternative<
+                  AuthenticatorRequestDialogModel::Mechanism::Phone>(m.type);
+            } else {
+              return absl::holds_alternative<
+                  AuthenticatorRequestDialogModel::Mechanism::AddPhone>(m.type);
+            }
+          })
+          ->callback.Run();
+
+      if (ble_access_denied) {
+        EXPECT_EQ(model.current_step(), Step::kBlePermissionMac);
+      } else if (click_specific_phone) {
+        EXPECT_EQ(model.current_step(), Step::kCableActivate);
+      } else {
+        EXPECT_EQ(model.current_step(), Step::kCableV2QRCode);
+      }
+    }
+  }
+}
+#endif
diff --git a/chrome/build/lacros-arm.pgo.txt b/chrome/build/lacros-arm.pgo.txt
index f944106..6de697c 100644
--- a/chrome/build/lacros-arm.pgo.txt
+++ b/chrome/build/lacros-arm.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-arm-generic-main-1684930180-f243cf9df4e93748939d7f2d317a917135a389df.profdata
+chrome-chromeos-arm-generic-main-1684972937-a8771f8f79b06559cce52eefe3ba320f0269f8ca.profdata
diff --git a/chrome/build/lacros-arm64.pgo.txt b/chrome/build/lacros-arm64.pgo.txt
index 16eca36..d33c2da1 100644
--- a/chrome/build/lacros-arm64.pgo.txt
+++ b/chrome/build/lacros-arm64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-arm64-generic-main-1684929692-9c45b3ffaf7c411bbaa469b2b43b6b97e7a94d63.profdata
+chrome-chromeos-arm64-generic-main-1684972937-3fb8e58cc0ac7c4daf8f9071062810c091fb4006.profdata
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt
index 6f3022d..de24106 100644
--- a/chrome/build/lacros64.pgo.txt
+++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-amd64-generic-main-1684929692-1cb7f3b05150a78fa4ab6ff7d5634300b3267192.profdata
+chrome-chromeos-amd64-generic-main-1684972937-1f1bf7639929f031a74387c0be192371a07d6098.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 9a359e4..4cc96bc 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1684929171-67e5a3869a16c2a8253e52c642b9c35980e7391c.profdata
+chrome-linux-main-1684993784-6f366df8a14b672456c91ab29ea28d8c00b789eb.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index c0c732b..2ae2a78 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1684936766-407ae1ea115427d6b084f9e49fd330053e9c7381.profdata
+chrome-mac-arm-main-1685001328-8536e1408867e5892b9b73ded32291f773e1da90.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 6b58e51b..0ee1724 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1684907930-4ac6ec08f1838412b0e13dbfc5354ec7a19d5def.profdata
+chrome-mac-main-1684993784-60a5f98975532e00333595727ffaaf1bfaaf10f7.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index d64ddc1..21594c5 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1684918786-c6d19e47062f8327802869d9a51b617307f13560.profdata
+chrome-win32-main-1684993784-ea7d1b9507a370811d55fbf184495d7acce30bdf.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 6af315a..46b38c3 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1684929171-fc8684cad1193ac4d6454d655ddf76a1b01ee267.profdata
+chrome-win64-main-1684993784-515e5455b0fec7f23f346a2e8e24d7a5e0cf1a3b.profdata
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index d8ce74e..b604870 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -608,8 +608,6 @@
     "//components/bookmarks/common",
     "//components/nacl/common:switches",
     "//components/offline_pages/buildflags",
-    "//components/supervised_user/core/common",
-    "//components/supervised_user/core/common:buildflags",
     "//extensions/buildflags",
     "//media:media_buildflags",
     "//ppapi/buildflags",
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 6c74a02..2ee3b0e 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -781,6 +781,12 @@
 constexpr base::FeatureParam<base::TimeDelta> kKAnonymityServiceQueryInterval{
     &kKAnonymityService, "KAnonymityServiceJoinInterval", base::Days(1)};
 
+// When enabled, LCP critical path predictor will optimize the subsequent visits
+// to websites using performance hints collected in the past page loads.
+BASE_FEATURE(kLCPCriticalPathPredictor,
+             "LCPCriticalPathPredictor",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // When enabled, the k-Anonymity Service will send requests to the Join and
 // Query k-anonymity servers.
 BASE_FEATURE(kKAnonymityServiceOHTTPRequests,
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 236e39a..d4c0dba 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -465,6 +465,9 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 BASE_DECLARE_FEATURE(kKAnonymityServiceStorage);
 
+COMPONENT_EXPORT(CHROME_FEATURES)
+BASE_DECLARE_FEATURE(kLCPCriticalPathPredictor);
+
 #if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kLinuxLowMemoryMonitor);
 COMPONENT_EXPORT(CHROME_FEATURES)
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 6a221ecf..6e39f3d 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -299,23 +299,6 @@
 // be treated as not from the webstore when doing install verification.
 const char kExtensionsNotWebstore[] = "extensions-not-webstore";
 
-// Specifies a proxy server for origins specified in
-// kIPAnonymizationProxyAllowList. This proxy will be used on a best-effort
-// basis when normal proxy resolution would result in trying direct connections
-// (possibly after trying some other proxy server).
-const char kIPAnonymizationProxyServer[] = "ip-anonymization-proxy-server";
-
-// Specifies a list of origins on which to use the server specified by
-// `kIPAnonymizationProxyServer`. if `kIPAnonymizationProxyServer` is empty this
-// list will be ignored. This is intended as a reverse bypass rules list.
-const char kIPAnonymizationProxyAllowList[] =
-    "ip-anonymization-proxy-allow-list";
-
-// Specifies a value for the "password" header to be passed to the proxy
-// specified by `kIPAnonymizationProxyServer`. if `kIPAnonymizationProxyServer`
-// is empty this list will be ignored.
-const char kIPAnonymizationProxyPassword[] = "ip-anonymization-proxy-password";
-
 // Forces application mode. This hides certain system UI elements and forces
 // the app to be installed if it hasn't been already.
 const char kForceAppMode[] = "force-app-mode";
@@ -545,6 +528,10 @@
 // Simulates an update being available.
 const char kSimulateUpgrade[] = "simulate-upgrade";
 
+// Sets the IdleTimeout policy to a very short value (shorter than normally
+// possible) for testing purposes.
+const char kSimulateIdleTimeout[] = "simulate-idle-timeout";
+
 // Specifies the maximum SSL/TLS version ("tls1.2" or "tls1.3").
 const char kSSLVersionMax[] = "ssl-version-max";
 
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 277345e4..dc42a22 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -107,9 +107,6 @@
 extern const char kExtensionContentVerificationEnforceStrict[];
 extern const char kExtensionsInstallVerification[];
 extern const char kExtensionsNotWebstore[];
-extern const char kIPAnonymizationProxyServer[];
-extern const char kIPAnonymizationProxyAllowList[];
-extern const char kIPAnonymizationProxyPassword[];
 extern const char kForceAppMode[];
 extern const char kForceFirstRun[];
 extern const char kForceWhatsNew[];
@@ -167,6 +164,7 @@
 extern const char kSimulateOutdated[];
 extern const char kSimulateOutdatedNoAU[];
 extern const char kSimulateUpgrade[];
+extern const char kSimulateIdleTimeout[];
 extern const char kSSLVersionMax[];
 extern const char kSSLVersionMin[];
 extern const char kSSLVersionTLSv12[];
diff --git a/chrome/common/chromeos/extensions/api/_api_features.json b/chrome/common/chromeos/extensions/api/_api_features.json
index 2a43ec5..af51523 100644
--- a/chrome/common/chromeos/extensions/api/_api_features.json
+++ b/chrome/common/chromeos/extensions/api/_api_features.json
@@ -54,6 +54,18 @@
     "channel": "stable",
     "feature_flag": "TelemetryExtensionPendingApprovalApi"
   },
+  "os.events.onKeyboardDiagnosticEvent": {
+    "dependencies": [ "permission:os.events" ],
+    "contexts": [
+      "blessed_extension"
+    ],
+    "platforms": [
+      "chromeos",
+      "lacros"
+    ],
+    "channel": "stable",
+    "feature_flag": "TelemetryExtensionPendingApprovalApi"
+  },
   "os.telemetry": {
     "dependencies": [ "permission:os.telemetry" ],
     "contexts": [
diff --git a/chrome/common/chromeos/extensions/api/events.idl b/chrome/common/chromeos/extensions/api/events.idl
index dc7b2de..f500f3d 100644
--- a/chrome/common/chromeos/extensions/api/events.idl
+++ b/chrome/common/chromeos/extensions/api/events.idl
@@ -239,6 +239,10 @@
         // Informs the extension  that an `AudioJack` event occured.
         static void onAudioJackEvent(AudioJackEventInfo event_info);
 
+        // Informs the extension that a Keyboard diagnostic has been completed
+        // in the first party diagnostic tool.
+        static void onKeyboardDiagnosticEvent(KeyboardDiagnosticEventInfo event_info);
+
         // Informs the extension that a `Lid` event occured.
         static void onLidEvent(LidEventInfo event_info);
 
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl
index 2184056..29438d1 100644
--- a/chrome/common/extensions/api/autotest_private.idl
+++ b/chrome/common/extensions/api/autotest_private.idl
@@ -820,6 +820,8 @@
   // Callback invoked when the temporary directory was removed.
   callback RemoveFuseboxTempDirCallback = void();
 
+  callback IsFeatureEnabledCallback = void(boolean enabled);
+
   interface Functions {
     // Must be called to allow autotestPrivateAPI events to be fired.
     static void initializeEvents();
@@ -1568,6 +1570,11 @@
     // Delete a bruschetta VM.
     [supportsPromises] static void removeBruschetta(
       DOMString vm_name, VoidCallback callback);
+
+    // Returns whether a base::Feature is enabled. The state may change because
+    // a Chrome uprev into ChromeOS changed the default feature state.
+    [supportsPromises] static void isFeatureEnabled(
+      DOMString feature_name, IsFeatureEnabledCallback callback);
   };
 
   interface Events {
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index ed9885a..ff7650cf 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -15,7 +15,6 @@
 #include "chrome/common/buildflags.h"
 #include "components/offline_pages/buildflags/buildflags.h"
 #include "components/signin/public/base/signin_buildflags.h"
-#include "components/supervised_user/core/common/buildflags.h"
 #include "extensions/buildflags/buildflags.h"
 #include "media/media_buildflags.h"
 #include "ppapi/buildflags/buildflags.h"
diff --git a/chrome/services/qrcode_generator/qrcode_generator_service_pixeltest.cc b/chrome/services/qrcode_generator/qrcode_generator_service_pixeltest.cc
index 566348d..d1a9f28b 100644
--- a/chrome/services/qrcode_generator/qrcode_generator_service_pixeltest.cc
+++ b/chrome/services/qrcode_generator/qrcode_generator_service_pixeltest.cc
@@ -8,6 +8,7 @@
 #include "chrome/services/qrcode_generator/public/cpp/qrcode_generator_service.h"
 #include "chrome/services/qrcode_generator/public/mojom/qrcode_generator.mojom.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
 #include "ui/base/test/skia_gold_pixel_diff.h"
 
@@ -65,7 +66,7 @@
     BUILDFLAG(IS_CHROMEOS_LACROS)
     // Verify image contents through go/chrome-engprod-skia-gold.
     if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-            "browser-ui-tests-verify-pixels")) {
+            switches::kVerifyPixels)) {
       const ::testing::TestInfo* test_info =
           ::testing::UnitTest::GetInstance()->current_test_info();
       ui::test::SkiaGoldPixelDiff pixel_diff;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 324d6b1..5230e2b 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -5219,6 +5219,7 @@
       "//ui/gfx/codec",
       "//ui/ozone",
       "//ui/platform_window",
+      "//ui/strings:ui_strings_grit",
     ]
 
     if (use_cups) {
@@ -7259,13 +7260,13 @@
       "../browser/ui/passwords/password_manager_navigation_throttle_unittest.cc",
       "../browser/ui/passwords/well_known_change_password_navigation_throttle_unittest.cc",
       "../browser/ui/performance_controls/performance_controls_hats_service_unittest.cc",
+      "../browser/ui/performance_controls/resource_usage_tab_helper_unittest.cc",
       "../browser/ui/qrcode_generator/qrcode_generator_bubble_controller_unittest.cc",
       "../browser/ui/recently_audible_helper_unittest.cc",
       "../browser/ui/search/ntp_user_data_logger_unittest.cc",
       "../browser/ui/search/search_ipc_router_policy_unittest.cc",
       "../browser/ui/search/search_ipc_router_unittest.cc",
       "../browser/ui/serial/serial_chooser_controller_unittest.cc",
-      "../browser/ui/side_panel/companion/companion_utils_unittest.cc",
       "../browser/ui/singleton_tabs_unittest.cc",
       "../browser/ui/startup/launch_mode_recorder_unittest.cc",
       "../browser/ui/sync/sync_promo_ui_unittest.cc",
@@ -7630,6 +7631,7 @@
       "//components/user_notes:features",
       "//components/user_notes/browser",
       "//components/user_notes/interfaces",
+      "//services/device/public/cpp/bluetooth",
       "//services/metrics/public/cpp:ukm_builders",
       "//services/network:test_support",
       "//third_party/libaddressinput",
@@ -7723,6 +7725,7 @@
       "../browser/apps/app_service/file_utils_unittest.cc",
       "../browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc",
       "../browser/apps/app_service/promise_apps/promise_app_almanac_connector_unittest.cc",
+      "../browser/apps/app_service/promise_apps/promise_app_icon_cache_unittest.cc",
       "../browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc",
       "../browser/apps/app_service/promise_apps/promise_app_service_unittest.cc",
       "../browser/apps/app_service/promise_apps/promise_app_unittest.cc",
@@ -8697,6 +8700,8 @@
       "../browser/policy/developer_tools_policy_handler_unittest.cc",
       "../browser/profiles/guest_mode_policy_handler_unittest.cc",
     ]
+
+    deps += [ "//components/webauthn/core/browser:test_support" ]
   }
 
   if (use_gio) {
@@ -9441,6 +9446,10 @@
       "//third_party/fuchsia-sdk/sdk/pkg/vulkan/client.shard.cml",
     ]
   }
+
+  if (is_win || is_mac || is_linux || is_chromeos) {
+    deps += [ "../browser/enterprise/data_controls:unit_tests" ]
+  }
 }
 
 static_library("test_support_unit") {
diff --git a/chrome/test/data/extensions/api_test/autotest_private/test.js b/chrome/test/data/extensions/api_test/autotest_private/test.js
index 9bfc880..7b0ee69 100644
--- a/chrome/test/data/extensions/api_test/autotest_private/test.js
+++ b/chrome/test/data/extensions/api_test/autotest_private/test.js
@@ -1517,6 +1517,27 @@
       }));
 }];
 
+var isFeatureEnabledTests = [
+  function getEnabledFeature() {
+    chrome.autotestPrivate.isFeatureEnabled("EnabledFeatureForTest",
+      chrome.test.callbackPass(enabled => {
+        chrome.test.assertTrue(enabled);
+      }));
+  },
+  function getDisabledFeature() {
+    chrome.autotestPrivate.isFeatureEnabled("DisabledFeatureForTest",
+      chrome.test.callbackPass(enabled => {
+        chrome.test.assertFalse(enabled);
+      }));
+  },
+  function getUnknownFeature() {
+    chrome.autotestPrivate.isFeatureEnabled("UnknownFeature",
+      chrome.test.callbackFail(
+        "feature UnknownFeature is not on allowlist, see " +
+        "AutotestPrivateIsFeatureEnabledFunction::Run() to update the list"));
+  }
+];
+
 var launcherSearchBoxStateTests = [ function verifyGhostText(){
   chrome.autotestPrivate.getLauncherSearchBoxState(
       chrome.test.callbackPass(info => {
@@ -1610,6 +1631,7 @@
       'splitviewPrimarySnapped': splitviewPrimarySnappedTests,
       'scrollableShelf': scrollableShelfTests,
       'shelf': shelfTests,
+      'isFeatureEnabled': isFeatureEnabledTests,
       'holdingSpace': holdingSpaceTests,
       'systemWebApps': systemWebAppsTests,
       'lacrosEnabled': lacrosEnabledTests,
diff --git a/chrome/test/data/extensions/good/Preferences b/chrome/test/data/extensions/good/Preferences
index 6229d8e8..22d18ae 100644
--- a/chrome/test/data/extensions/good/Preferences
+++ b/chrome/test/data/extensions/good/Preferences
@@ -76,7 +76,39 @@
                 "page": "background.html"
               }
             }
-         }
+         },
+         "lckcjklfapeiadkadngidmocpbkemckm": {
+          "active_permissions": {
+            "api": [],
+            "explicit_host": [],
+            "manifest_permissions": [],
+            "scriptable_host": []
+          },
+          "commands": {},
+          "content_settings": [],
+          "creation_flags": 38,
+          "events": [],
+          "first_install_time": "13322357429642204",
+          "from_webstore": false,
+          "granted_permissions": {
+            "api": [],
+            "explicit_host": [],
+            "manifest_permissions": [],
+            "scriptable_host": []
+          },
+          "incognito_content_settings": [],
+          "incognito_preferences": {},
+          "last_update_time": "13322357429642204",
+          "location": 4,
+          "newAllowFileAccess": true,
+          "path": "good_juKvIh",
+          "preferences": {},
+          "regular_only_preferences": {},
+          "state": 1,
+          "was_installed_by_default": false,
+          "was_installed_by_oem": false,
+          "withholding_permissions": false
+        }
       }
    }
 }
diff --git a/chrome/test/data/extensions/good/UnpackedExtensions/good_juKvIh/manifest.json b/chrome/test/data/extensions/good/UnpackedExtensions/good_juKvIh/manifest.json
new file mode 100644
index 0000000..843ded9
--- /dev/null
+++ b/chrome/test/data/extensions/good/UnpackedExtensions/good_juKvIh/manifest.json
@@ -0,0 +1,5 @@
+{
+  "name": "Testing Unpacked Extension Installation",
+  "version": "0.1",
+  "manifest_version": 3
+}
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index 5f40c53..2479a1fe 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -31,7 +31,6 @@
       "extensions/cr_extensions_interactive_ui_tests.js",
       "history/history_focus_test.js",
       "password_manager/password_manager_interactive_ui_tests.js",
-      "print_preview/print_preview_interactive_ui_tests.js",
       "settings/cr_settings_interactive_ui_tests.js",
       "support_tool/support_tool_interactive_ui_test.js",
       "tab_search/tab_search_interactive_ui_tests.js",
@@ -39,10 +38,12 @@
 
     if (is_chromeos_ash) {
       sources += [ "cr_focus_row_behavior_interactive_test.js" ]
+    } else {
+      sources += [ "signin/local_profile_customization_interactive_ui_test.js" ]
     }
 
-    if (!is_chromeos_ash) {
-      sources += [ "signin/local_profile_customization_interactive_ui_test.js" ]
+    if (enable_print_preview) {
+      sources += [ "print_preview/print_preview_interactive_ui_tests.js" ]
     }
 
     if (enable_webui_tab_strip) {
@@ -115,10 +116,6 @@
       "whats_new/whats_new_browsertest.js",
     ]
 
-    if (is_chrome_branded) {
-      sources += [ "media_router/cast_feedback_ui_browsertest.js" ]
-    }
-
     gen_include_files = [
       "a11y/accessibility_audit_rules.js",
       "a11y/accessibility_test.js",
@@ -137,16 +134,15 @@
       "//skia",
     ]
 
+    if (is_chrome_branded) {
+      sources += [ "media_router/cast_feedback_ui_browsertest.js" ]
+    }
+
     if (use_nss_certs) {
       deps +=
           [ "//ui/webui/resources/cr_components/certificate_manager:build_ts" ]
     }
 
-    if (is_chromeos_ash) {
-      gen_include_files +=
-          [ "settings/chromeos/a11y/os_settings_accessibility_test.js" ]
-    }
-
     if (is_chromeos_ash || is_win || is_mac) {
       sources += [ "inline_login/inline_login_browsertest.js" ]
       deps += [ "//build:chromeos_buildflags" ]
@@ -179,6 +175,8 @@
         "settings/chromeos/a11y/os_a11y_browsertest.js",
         "settings/chromeos/os_settings_browsertest.js",
       ]
+      gen_include_files +=
+          [ "settings/chromeos/a11y/os_settings_accessibility_test.js" ]
     } else {
       sources += [
         "intro/intro_browsertest.js",
@@ -527,19 +525,6 @@
     grdp_files += [ "$target_gen_dir/media_router/resources.grdp" ]
   }
 
-  if (!is_chromeos_ash) {
-    deps += [
-      "intro:build_grdp",
-      "signin:build_grdp",
-      "welcome:build_grdp",
-    ]
-    grdp_files += [
-      "$target_gen_dir/intro/resources.grdp",
-      "$target_gen_dir/welcome/resources.grdp",
-      "$target_gen_dir/signin/resources.grdp",
-    ]
-  }
-
   if (is_win || is_mac || is_linux) {
     deps += [
       "app_home:build_grdp",
@@ -593,6 +578,17 @@
       "$root_gen_dir/ui/file_manager/tests_resources.grdp",
       "$root_gen_dir/ui/file_manager/tests_gen_resources.grdp",
     ]
+  } else {
+    deps += [
+      "intro:build_grdp",
+      "signin:build_grdp",
+      "welcome:build_grdp",
+    ]
+    grdp_files += [
+      "$target_gen_dir/intro/resources.grdp",
+      "$target_gen_dir/welcome/resources.grdp",
+      "$target_gen_dir/signin/resources.grdp",
+    ]
   }
 
   if (is_chromeos_ash || is_win || is_mac) {
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js
index 1a91ce3..c1ced27 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js
+++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js
@@ -525,10 +525,7 @@
   /** @override */
   get featureList() {
     return {
-      enabled: [
-        'ash::features::kPersonalizationJelly',
-        'chromeos::features::kJelly',
-      ],
+      enabled: ['chromeos::features::kJelly'],
     };
   }
 }
@@ -578,6 +575,14 @@
         }
       }
 
+      setup(async () => {
+        // Reset to default state before each test to reduce dependencies.
+        setDynamicColorToggle(/* checkedState= */ true);
+        const colorSchemeButtons =
+            Array.from(getColorSchemeSelector().querySelectorAll('cr-button'));
+        colorSchemeButtons[0].click();
+      });
+
       suite('dynamic color', () => {
         test('shows dynamic color options', () => {
           assertTrue(!!getDynamicColorToggle());
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_browsertest.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_browsertest.js
index eeb1f6a..0ac02f4e 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_browsertest.js
+++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_browsertest.js
@@ -9,7 +9,6 @@
 
 GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']);
 
-GEN('#include "ash/constants/ash_features.h"');
 GEN('#include "ash/public/cpp/style/dark_light_mode_controller.h"');
 GEN('#include "ash/webui/personalization_app/test/personalization_app_mojom_banned_browsertest_fixture.h"');
 GEN('#include "chromeos/constants/chromeos_features.h"');
@@ -20,14 +19,6 @@
     return 'chrome://personalization/';
   }
 
-  get featureList() {
-    return {
-      enabled: [
-        'ash::features::kPersonalizationJelly',
-      ]
-    };
-  }
-
   get testGenPreamble() {
     // Force light mode in test to reduce randomness.
     return () => {
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.ts
index 9b203f0..15be694 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.ts
@@ -9,7 +9,7 @@
 import {FakeShortcutProvider} from 'chrome://shortcut-customization/js/fake_shortcut_provider.js';
 import {Accelerator, AcceleratorCategory, AcceleratorSource, AcceleratorState, Modifier, MojoAccelerator, MojoAcceleratorInfo, StandardAcceleratorInfo} from 'chrome://shortcut-customization/js/shortcut_types.js';
 import {areAcceleratorsEqual, createEmptyAccelInfoFromAccel} from 'chrome://shortcut-customization/js/shortcut_utils.js';
-import {assertDeepEquals, assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 suite('acceleratorLookupManagerTest', function() {
   let provider: FakeShortcutProvider|null = null;
@@ -94,6 +94,27 @@
     });
   });
 
+  test('GetIsCategoryLocked', async () => {
+    // First, initialize the accelerators into the AcceleratorLookupManager.
+    getProvider().setFakeAcceleratorConfig(fakeAcceleratorConfig);
+    const {config: accelConfig} = await getProvider().getAccelerators();
+    assertDeepEquals(fakeAcceleratorConfig, accelConfig);
+    getManager().setAcceleratorLookup(accelConfig);
+
+    // Then, initialize the layout infos into the AcceleratorLookupManager.
+    getProvider().setFakeAcceleratorLayoutInfos(fakeLayoutInfo);
+    const {layoutInfos: layoutInfos} =
+        await getProvider().getAcceleratorLayoutInfos();
+    assertDeepEquals(fakeLayoutInfo, layoutInfos);
+    getManager().setAcceleratorLayoutLookup(layoutInfos);
+
+    // We expect that kWindowsAndDesks category is not locked.
+    assertFalse(
+        getManager().isCategoryLocked(AcceleratorCategory.kWindowsAndDesks));
+    // We expect that kBrowser category is locked.
+    assertTrue(getManager().isCategoryLocked(AcceleratorCategory.kBrowser));
+  });
+
   test('ReplaceBasicAccelerator', () => {
     getProvider().setFakeAcceleratorConfig(fakeAcceleratorConfig);
     return getProvider().getAccelerators().then((result) => {
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.ts
index 63958c8c..d4af50b 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.ts
@@ -24,9 +24,6 @@
     manager = AcceleratorLookupManager.getInstance();
     manager!.setAcceleratorLookup(fakeAcceleratorConfig);
     manager!.setAcceleratorLayoutLookup(fakeLayoutInfo);
-
-    sectionElement = document.createElement('accelerator-subsection');
-    document.body.appendChild(sectionElement);
   });
 
   teardown(() => {
@@ -37,9 +34,19 @@
     sectionElement = null;
   });
 
+  async function initAcceleratorSubsectionElement(
+      category: AcceleratorCategory) {
+    sectionElement = document.createElement('accelerator-subsection');
+    sectionElement.category = category;
+    document.body.appendChild(sectionElement);
+    return flushTasks();
+  }
+
   // TODO(jimmyxgong): Update this test after retrieving accelerators is
   // implemented for a subsection.
   test('LoadsBasicSection', async () => {
+    await initAcceleratorSubsectionElement(
+        AcceleratorCategory.kWindowsAndDesks);
     const acceleratorInfo1 = createUserAcceleratorInfo(
         Modifier.CONTROL | Modifier.SHIFT,
         /*key=*/ 71,
@@ -76,9 +83,10 @@
   });
 
   test('LoadCategoryAndConfirmDescriptions', async () => {
+    await initAcceleratorSubsectionElement(
+        AcceleratorCategory.kWindowsAndDesks);
     const expectedTitle = 'test title';
     sectionElement!.title = expectedTitle;
-    sectionElement!.category = AcceleratorCategory.kWindowsAndDesks;
     sectionElement!.subcategory = AcceleratorSubcategory.kWindows;
 
     await flushTasks();
@@ -105,9 +113,9 @@
   });
 
   test('SkipAddingRowWhenCertainKeysAreUnavailable', async () => {
+    await initAcceleratorSubsectionElement(AcceleratorCategory.kGeneral);
     const expectedTitle = 'test title';
     sectionElement!.title = expectedTitle;
-    sectionElement!.category = AcceleratorCategory.kGeneral;
     sectionElement!.subcategory = AcceleratorSubcategory.kApps;
 
     await flushTasks();
@@ -133,9 +141,9 @@
   });
 
   test('RemoveAcceleratorWhenCertainKeysAreUnavailable', async () => {
+    await initAcceleratorSubsectionElement(AcceleratorCategory.kGeneral);
     const expectedTitle = 'test title';
     sectionElement!.title = expectedTitle;
-    sectionElement!.category = AcceleratorCategory.kGeneral;
     sectionElement!.subcategory = AcceleratorSubcategory.kGeneralControls;
 
     await flushTasks();
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts
index ca7f1ef..2028df2 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts
@@ -15,7 +15,6 @@
 import {InputKeyElement, KeyInputState} from 'chrome://shortcut-customization/js/input_key.js';
 import {setShortcutProviderForTesting} from 'chrome://shortcut-customization/js/mojo_interface_provider.js';
 import {AcceleratorConfigResult, AcceleratorSource, LayoutStyle, Modifier} from 'chrome://shortcut-customization/js/shortcut_types.js';
-import {isCategoryLocked} from 'chrome://shortcut-customization/js/shortcut_utils.js';
 import {AcceleratorResultData} from 'chrome://shortcut-customization/mojom-webui/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom-webui.js';
 import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
@@ -276,13 +275,14 @@
         // replicate getCategory() logic.
         const category = manager!.getAcceleratorCategory(
             layoutInfo.source, layoutInfo.action);
+        const categoryIsLocked = manager!.isCategoryLocked(category);
         // replicate shouldShowLockIcon() logic.
         const expectLockIconVisible = scenario.customizationEnabled &&
-            !isCategoryLocked(category) &&
-            (scenario.locked || scenario.sourceIsLocked);
+            !categoryIsLocked && (scenario.locked || scenario.sourceIsLocked);
         testCases.push({
           ...scenario,
           layoutInfo: layoutInfo,
+          categoryIsLocked: categoryIsLocked,
           expectLockIconVisible: expectLockIconVisible,
         });
       }
@@ -294,6 +294,7 @@
       viewElement = initAcceleratorViewElement();
       viewElement.source = testCase.layoutInfo.source;
       viewElement.action = testCase.layoutInfo.action;
+      viewElement.categoryIsLocked = testCase.categoryIsLocked;
       const acceleratorInfo = createStandardAcceleratorInfo(
           Modifier.CONTROL | Modifier.SHIFT,
           /*key=*/ 71,
@@ -353,13 +354,15 @@
         // replicate getCategory() logic.
         const category = manager!.getAcceleratorCategory(
             layoutInfo.source, layoutInfo.action);
+        const categoryIsLocked = manager!.isCategoryLocked(category);
         // replicate shouldShowLockIcon() logic.
         const expectEditIconVisible = scenario.customizationEnabled &&
-            scenario.isAcceleratorRow && !isCategoryLocked(category) &&
+            scenario.isAcceleratorRow && !categoryIsLocked &&
             !scenario.locked && !scenario.sourceIsLocked;
         testCases.push({
           ...scenario,
           layoutInfo: layoutInfo,
+          categoryIsLocked: categoryIsLocked,
           expectEditIconVisible: expectEditIconVisible,
         });
       }
@@ -370,6 +373,7 @@
       viewElement = initAcceleratorViewElement();
       viewElement.source = testCase.layoutInfo.source;
       viewElement.action = testCase.layoutInfo.action;
+      viewElement.categoryIsLocked = testCase.categoryIsLocked;
       viewElement.showEditIcon = testCase.isAcceleratorRow;
       const acceleratorInfo = createStandardAcceleratorInfo(
           Modifier.CONTROL | Modifier.SHIFT,
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_utils_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_utils_test.ts
index e249c2d..632bdb83 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_utils_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_utils_test.ts
@@ -8,7 +8,7 @@
 import {CycleTabsTextSearchResult, SnapWindowLeftSearchResult, TakeScreenshotSearchResult} from 'chrome://shortcut-customization/js/fake_data.js';
 import {stringToMojoString16} from 'chrome://shortcut-customization/js/mojo_utils.js';
 import {Accelerator, AcceleratorCategory, Modifier, MojoAccelerator, StandardAcceleratorInfo, TextAcceleratorPart, TextAcceleratorPartType} from 'chrome://shortcut-customization/js/shortcut_types.js';
-import {areAcceleratorsEqual, compareAcceleratorInfos, getAccelerator, getAcceleratorId, getModifiersForAcceleratorInfo, getModifierString, getSortedModifiers, getURLForSearchResult, isCustomizationDisabled, isSearchEnabled, isStandardAcceleratorInfo, isTextAcceleratorInfo, SHORTCUTS_APP_URL} from 'chrome://shortcut-customization/js/shortcut_utils.js';
+import {areAcceleratorsEqual, compareAcceleratorInfos, getAccelerator, getAcceleratorId, getModifiersForAcceleratorInfo, getModifierString, getSortedModifiers, getSourceAndActionFromAcceleratorId, getURLForSearchResult, isCustomizationDisabled, isSearchEnabled, isStandardAcceleratorInfo, isTextAcceleratorInfo, SHORTCUTS_APP_URL} from 'chrome://shortcut-customization/js/shortcut_utils.js';
 import {assertArrayEquals, assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 import {createStandardAcceleratorInfo, createTextAcceleratorInfo} from './shortcut_customization_test_util.js';
@@ -277,4 +277,12 @@
     initialOrder.sort(compareAcceleratorInfos);
     areStandardAcceleratorInfosEqual(expectedOrder, initialOrder);
   });
+
+  test('getSourceAndActionFromAcceleratorId', async () => {
+    const result1 = getSourceAndActionFromAcceleratorId('3-45');
+    assertDeepEquals(result1, {source: 3, action: 45});
+
+    const result2 = getSourceAndActionFromAcceleratorId('0-33');
+    assertDeepEquals(result2, {source: 0, action: 33});
+  });
 });
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/text_accelerator_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/text_accelerator_test.ts
index 3da9cc7..7dd867d 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/text_accelerator_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/text_accelerator_test.ts
@@ -14,7 +14,6 @@
 import {InputKeyElement, KeyInputState} from 'chrome://shortcut-customization/js/input_key.js';
 import {mojoString16ToString, stringToMojoString16} from 'chrome://shortcut-customization/js/mojo_utils.js';
 import {AcceleratorSource, LayoutStyle, TextAcceleratorPart, TextAcceleratorPartType} from 'chrome://shortcut-customization/js/shortcut_types.js';
-import {isCategoryLocked} from 'chrome://shortcut-customization/js/shortcut_utils.js';
 import {TextAcceleratorElement} from 'chrome://shortcut-customization/js/text_accelerator.js';
 import {assertEquals} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
@@ -173,9 +172,10 @@
         // replicate getCategory() logic.
         const category = manager!.getAcceleratorCategory(
             layoutInfo.source, layoutInfo.action);
+        const categoryIsUnlocked = !manager!.isCategoryLocked(category);
         // replicate shouldShowLockIcon() logic.
         const expectLockIconVisible =
-            scenario.customizationEnabled && !isCategoryLocked(category);
+            scenario.customizationEnabled && categoryIsUnlocked;
         testCases.push({
           ...scenario,
           layoutInfo: layoutInfo,
diff --git a/chrome/test/data/webui/nearby_share/nearby_discovery_page_test.js b/chrome/test/data/webui/nearby_share/nearby_discovery_page_test.js
index 31a9de48..1dcd51c5 100644
--- a/chrome/test/data/webui/nearby_share/nearby_discovery_page_test.js
+++ b/chrome/test/data/webui/nearby_share/nearby_discovery_page_test.js
@@ -9,12 +9,13 @@
 import {SelectShareTargetResult, ShareTargetListenerRemote, StartDiscoveryResult} from 'chrome://nearby/shared/nearby_share.mojom-webui.js';
 import {ShareType} from 'chrome://nearby/shared/nearby_share_share_type.mojom-webui.js';
 import {getDeepActiveElement} from 'chrome://resources/ash/common/util.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {ShareTargetType} from 'chrome://resources/mojo/chromeos/ash/services/nearby/public/mojom/nearby_share_target_types.mojom-webui.js';
 import {UnguessableToken} from 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-webui.js';
 import {keyEventOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {assertEquals, assertFalse, assertTrue} from '../chromeos/chai_assert.js';
+import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../chromeos/chai_assert.js';
 import {isVisible} from '../chromeos/test_util.js';
 
 import {FakeConfirmationManagerRemote, FakeDiscoveryManagerRemote} from './fake_mojo_interfaces.js';
@@ -197,9 +198,10 @@
 
   /**
    * @param {!string} name Device name
+   * @param {!boolean} for_self_share
    * @return {!ShareTarget}
    */
-  function createShareTarget(name) {
+  function createShareTarget(name, for_self_share = false) {
     return {
       id: {high: BigInt(0), low: BigInt(nextId++)},
       name,
@@ -212,6 +214,7 @@
         fileCount: 0,
         shareType: /** @type {!ShareType} */ (0),
       },
+      forSelfShare: for_self_share,
     };
   }
 
@@ -259,8 +262,21 @@
 
   teardown(function() {
     discoveryPageElement.remove();
+    loadTimeData.overrideValues({'isSelfShareEnabled': false});
   });
 
+  /**
+   * Sets up self share tests which need isSelfShareEnabled enabled.
+   */
+  async function setupSelfShare() {
+    discoveryPageElement.remove();
+    PolymerTest.clearBody();
+    loadTimeData.overrideValues({'isSelfShareEnabled': true});
+    discoveryPageElement = /** @type {!NearbyDiscoveryPageElement} */ (
+        document.createElement('nearby-discovery-page'));
+    document.body.appendChild(discoveryPageElement);
+  }
+
   test('renders component', async function() {
     assertEquals('NEARBY-DISCOVERY-PAGE', discoveryPageElement.tagName);
     fireViewEnterStart();
@@ -584,4 +600,112 @@
         assertEquals(getNearbyDeviceElementAt(1), getDeepActiveElement());
       });
 
+  test(
+      'self share targets top device list when self share is enabled',
+      async function() {
+        setupSelfShare();
+        const listener = await startDiscovery();
+
+        // Add 2 non-self share targets.
+        let targets = [
+          createShareTarget('Device 1', /*for_self_share=*/ false),
+          createShareTarget('Device 2', /*for_self_share=*/ false),
+        ];
+        targets.forEach((target) => listener.onShareTargetDiscovered(target));
+        await listener.$.flushForTesting();
+
+        // Add 2 self share targets.
+        targets = [
+          createShareTarget('Device 3', /*for_self_share=*/ true),
+          createShareTarget('Device 4', /*for_self_share=*/ true),
+        ];
+        targets.forEach((target) => listener.onShareTargetDiscovered(target));
+        await listener.$.flushForTesting();
+        flush();
+
+        assertEquals(getNearbyDeviceElementAt(0).$.name.innerHTML, 'Device 3');
+        assertEquals(getNearbyDeviceElementAt(1).$.name.innerHTML, 'Device 4');
+        assertEquals(getNearbyDeviceElementAt(2).$.name.innerHTML, 'Device 1');
+        assertEquals(getNearbyDeviceElementAt(3).$.name.innerHTML, 'Device 2');
+      });
+
+  test(
+      'share targets ordered by earliest discovery when self share disabled',
+      async function() {
+        const listener = await startDiscovery();
+
+        // Add 2 non-self share targets.
+        let targets = [
+          createShareTarget('Device 1', /*for_self_share=*/ false),
+          createShareTarget('Device 2', /*for_self_share=*/ false),
+        ];
+        targets.forEach((target) => listener.onShareTargetDiscovered(target));
+        await listener.$.flushForTesting();
+
+        // Add 2 self share targets.
+        targets = [
+          createShareTarget('Device 3', /*for_self_share=*/ true),
+          createShareTarget('Device 4', /*for_self_share=*/ true),
+        ];
+        targets.forEach((target) => listener.onShareTargetDiscovered(target));
+        await listener.$.flushForTesting();
+        flush();
+
+        assertEquals(getNearbyDeviceElementAt(0).$.name.innerHTML, 'Device 1');
+        assertEquals(getNearbyDeviceElementAt(1).$.name.innerHTML, 'Device 2');
+        assertEquals(getNearbyDeviceElementAt(2).$.name.innerHTML, 'Device 3');
+        assertEquals(getNearbyDeviceElementAt(3).$.name.innerHTML, 'Device 4');
+      });
+
+  test('one self share target in device list', async function() {
+    setupSelfShare();
+    const listener = await startDiscovery();
+
+    // Add a self share target.
+    const target = createShareTarget('Device 1', /*for_self_share=*/ true);
+    listener.onShareTargetDiscovered(target);
+    await listener.$.flushForTesting();
+
+    assertEquals(getNearbyDeviceElementAt(0).$.name.innerHTML, 'Device 1');
+  });
+
+  test('one non-self share target in device list', async function() {
+    setupSelfShare();
+    const listener = await startDiscovery();
+
+    // Add a non-self share target.
+    const target = createShareTarget('Device 1', /*for_self_share=*/ false);
+    listener.onShareTargetDiscovered(target);
+    await listener.$.flushForTesting();
+
+    assertEquals(getNearbyDeviceElementAt(0).$.name.innerHTML, 'Device 1');
+  });
+
+  test('add and remove share targets to/from device list', async function() {
+    setupSelfShare();
+    const listener = await startDiscovery();
+
+    // Add self, non-self share targets.
+    const selfShareTarget =
+        createShareTarget('self share target', /*for_self_share=*/ true);
+    listener.onShareTargetDiscovered(selfShareTarget);
+    const nonSelfShareTarget =
+        createShareTarget('non self share target', /*for_self_share=*/ false);
+    listener.onShareTargetDiscovered(nonSelfShareTarget);
+    await listener.$.flushForTesting();
+    assertEquals(
+        getNearbyDeviceElementAt(0).$.name.innerHTML, 'self share target');
+    assertEquals(
+        getNearbyDeviceElementAt(1).$.name.innerHTML, 'non self share target');
+
+    // Remove share targets.
+    listener.onShareTargetLost(selfShareTarget);
+    listener.onShareTargetLost(nonSelfShareTarget);
+    await listener.$.flushForTesting();
+    const container =
+        discoveryPageElement.shadowRoot.querySelector('.device-list-container');
+    const nearbyDeviceElements = container.querySelectorAll('nearby-device');
+    assertEquals(nearbyDeviceElements.length, 0);
+  });
+
 });
diff --git a/chrome/test/data/webui/new_tab_page/app_test.ts b/chrome/test/data/webui/new_tab_page/app_test.ts
index db7a446..76b0363 100644
--- a/chrome/test/data/webui/new_tab_page/app_test.ts
+++ b/chrome/test/data/webui/new_tab_page/app_test.ts
@@ -205,6 +205,51 @@
     });
   });
 
+  suite('ogb scrim', () => {
+    suiteSetup(() => {
+      loadTimeData.overrideValues({removeScrim: true});
+    });
+
+    test('scroll bounce', async () => {
+      // Arrange.
+
+      // Set theme that triggers the scrim.
+      const theme = createTheme(true);
+      theme.backgroundImage = createBackgroundImage('https://foo.com');
+      callbackRouterRemote.setTheme(theme);
+      await callbackRouterRemote.$.flushForTesting();
+
+      // Make sure page is scrollable.
+      const spacer = document.createElement('div');
+      spacer.style.width = '100%';
+      spacer.style.height = '10000px';
+      spacer.style.flexShrink = '0';
+      $$(app, '#content')!.append(spacer);
+
+      // Simulates a vertical scroll.
+      const scrollY = async (y: number) => {
+        window.scroll(0, y);
+        // `window.scroll` doesn't automatically trigger scroll event.
+        window.dispatchEvent(new Event('scroll'));
+        // Wait for position update to propagate.
+        await new Promise<void>(
+            resolve => requestAnimationFrame(() => resolve()));
+      };
+
+      // Act (no bounce).
+      await scrollY(0);
+
+      // Assert (no bounce).
+      assertStyle($$(app, '#oneGoogleBarScrim')!, 'position', 'fixed');
+
+      // Act (scroll).
+      await scrollY(10);
+
+      // Assert (scroll).
+      assertStyle($$(app, '#oneGoogleBarScrim')!, 'position', 'absolute');
+    });
+  });
+
   suite('theming', () => {
     test('setting theme updates ntp', async () => {
       // Act.
diff --git a/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js b/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js
index 34430d5..e5490fbd 100644
--- a/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js
+++ b/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js
@@ -37,6 +37,10 @@
   runMochaSuite('NewTabPageAppTest ogb theming removeScrim is true');
 });
 
+TEST_F('NewTabPageAppTest', 'OgbScrim', function() {
+  runMochaSuite('NewTabPageAppTest ogb scrim');
+});
+
 TEST_F('NewTabPageAppTest', 'Theming', function() {
   runMochaSuite('NewTabPageAppTest theming');
 });
diff --git a/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts b/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts
index d0e638a3c..148bdc9 100644
--- a/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts
+++ b/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts
@@ -766,8 +766,6 @@
   });
 
   test('validDialog', async function() {
-    // Asserting very basic functionality for now.
-    // TODO(b/277180677): add more tests as functionality is implemented.
     await verifyActionOccured(
         browserProxy, PrivacySandboxPromptAction.NOTICE_SHOWN);
     assertTrue(!!page.shadowRoot!.querySelector('div'));
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn
index b45b92f..5e1228a 100644
--- a/chrome/test/data/webui/settings/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -112,7 +112,6 @@
     "a11y/tts_subpage_a11y_test.js",
 
     "app_management/app_details_item_test.js",
-    "app_management/app_detail_view_test.js",
     "app_management/app_item_test.js",
     "app_management/app_management_page_tests.js",
     "app_management/app_test.js",
@@ -168,6 +167,7 @@
     "internet_page/tether_connection_dialog_test.ts",
 
     "kerberos_page/kerberos_accounts_subpage_test.js",
+    "kerberos_page/kerberos_add_account_dialog_test.js",
     "kerberos_page/kerberos_page_test.ts",
     "kerberos_page/test_kerberos_accounts_browser_proxy.ts",
 
@@ -204,6 +204,8 @@
     "os_a11y_page/text_to_speech_subpage_test.ts",
     "os_a11y_page/tts_voice_subpage_test.ts",
 
+    "os_apps_page/app_management_page/app_detail_view_test.ts",
+
     "os_bluetooth_page/os_bluetooth_change_device_name_dialog_tests.js",
     "os_bluetooth_page/os_bluetooth_device_detail_subpage_tests.js",
     "os_bluetooth_page/os_bluetooth_devices_subpage_tests.js",
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/app_detail_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/app_detail_view_test.js
deleted file mode 100644
index b03703c..0000000
--- a/chrome/test/data/webui/settings/chromeos/app_management/app_detail_view_test.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-import {AppManagementStore, updateSelectedAppId} from 'chrome://os-settings/os_settings.js';
-import {setupFakeHandler, replaceStore, replaceBody} from './test_util.js';
-import {AppType} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js';
-
-suite('<app-management-app-detail-view>', () => {
-  let appDetailView;
-  let fakeHandler;
-  let arcApp;
-
-  setup(async () => {
-    fakeHandler = setupFakeHandler();
-    replaceStore();
-
-    // Create an ARC app.
-    const arcOptions = {type: AppType.kArc};
-
-    // Add an app, and make it the currently selected app.
-    arcApp = await fakeHandler.addApp('app1_id', arcOptions);
-    AppManagementStore.getInstance().dispatch(updateSelectedAppId(arcApp.id));
-
-    appDetailView = document.createElement('app-management-app-detail-view');
-
-    replaceBody(appDetailView);
-    await fakeHandler.flushPipesForTesting();
-  });
-
-  test('Change selected app', async () => {
-    assertEquals(
-        AppManagementStore.getInstance().data.selectedAppId,
-        appDetailView.app_.id);
-    assertEquals(arcApp.id, appDetailView.app_.id);
-    assertTrue(!!appDetailView.shadowRoot.querySelector(
-        'app-management-arc-detail-view'));
-    assertFalse(!!appDetailView.shadowRoot.querySelector(
-        'app-management-pwa-detail-view'));
-    const pwaOptions = {type: AppType.kWeb};
-    // Add an second pwa app, and make it the currently selected app.
-    const pwaApp = await fakeHandler.addApp('app2_id', pwaOptions);
-    AppManagementStore.getInstance().dispatch(updateSelectedAppId(pwaApp.id));
-    await fakeHandler.flushPipesForTesting();
-
-    assertEquals(
-        AppManagementStore.getInstance().data.selectedAppId,
-        appDetailView.app_.id);
-    assertEquals(pwaApp.id, appDetailView.app_.id);
-    assertFalse(!!appDetailView.shadowRoot.querySelector(
-        'app-management-arc-detail-view'));
-    assertTrue(!!appDetailView.shadowRoot.querySelector(
-        'app-management-pwa-detail-view'));
-  });
-});
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/arc_detail_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/arc_detail_view_test.js
index 9cb18c5..4132be1 100644
--- a/chrome/test/data/webui/settings/chromeos/app_management/arc_detail_view_test.js
+++ b/chrome/test/data/webui/settings/chromeos/app_management/arc_detail_view_test.js
@@ -77,57 +77,6 @@
         isHidden(getPermissionItemByType(arcPermissionView, 'kCamera')));
   });
 
-  test('Toggle works correctly', async () => {
-    const checkPermissionToggle = async (permissionType) => {
-      assertTrue(getPermissionBoolByType(permissionType));
-      assertTrue(getPermissionCrToggleByType(arcPermissionView, permissionType)
-                     .checked);
-
-      // Toggle Off.
-      await clickPermissionToggle(permissionType);
-      assertFalse(getPermissionBoolByType(permissionType));
-      assertFalse(getPermissionCrToggleByType(arcPermissionView, permissionType)
-                      .checked);
-
-      // Toggle On.
-      await clickPermissionToggle(permissionType);
-      assertTrue(getPermissionBoolByType(permissionType));
-      assertTrue(getPermissionCrToggleByType(arcPermissionView, permissionType)
-                     .checked);
-    };
-
-    await checkPermissionToggle('kLocation');
-    await checkPermissionToggle('kCamera');
-    await checkPermissionToggle('kNotifications');
-  });
-
-
-  test('OnClick handler for permission item works correctly', async () => {
-    const checkPermissionItemOnClick = async (permissionType) => {
-      assertTrue(getPermissionBoolByType(permissionType));
-      assertTrue(getPermissionCrToggleByType(arcPermissionView, permissionType)
-                     .checked);
-
-      // Toggle Off.
-      await clickPermissionItem(permissionType);
-      assertFalse(getPermissionBoolByType(permissionType));
-      assertFalse(getPermissionCrToggleByType(arcPermissionView, permissionType)
-                      .checked);
-
-      // Toggle On.
-      await clickPermissionItem(permissionType);
-      assertTrue(getPermissionBoolByType(permissionType));
-      assertTrue(getPermissionCrToggleByType(arcPermissionView, permissionType)
-                     .checked);
-    };
-
-    await checkPermissionItemOnClick('kLocation');
-    await checkPermissionItemOnClick('kCamera');
-    await checkPermissionItemOnClick('kNotifications');
-    await checkPermissionItemOnClick('kContacts');
-    await checkPermissionItemOnClick('kStorage');
-  });
-
   test('No permissions requested label', async () => {
     assertTrue(isHiddenByDomIf(
         arcPermissionView.shadowRoot.querySelector('#noPermissions')));
@@ -147,6 +96,75 @@
         arcPermissionView.shadowRoot.querySelector('#noPermissions')));
   });
 
+  suite('Read-write permissions', () => {
+    setup(async () => {
+      loadTimeData.overrideValues(
+          {'appManagementArcReadOnlyPermissions': false});
+
+      // Re-render with the new loadTimeData.
+      arcPermissionView =
+          document.createElement('app-management-arc-detail-view');
+      replaceBody(arcPermissionView);
+      await flushTasks();
+    });
+
+    test('Toggle works correctly', async () => {
+      const checkPermissionToggle = async (permissionType) => {
+        assertTrue(getPermissionBoolByType(permissionType));
+        assertTrue(
+            getPermissionCrToggleByType(arcPermissionView, permissionType)
+                .checked);
+
+        // Toggle Off.
+        await clickPermissionToggle(permissionType);
+        assertFalse(getPermissionBoolByType(permissionType));
+        assertFalse(
+            getPermissionCrToggleByType(arcPermissionView, permissionType)
+                .checked);
+
+        // Toggle On.
+        await clickPermissionToggle(permissionType);
+        assertTrue(getPermissionBoolByType(permissionType));
+        assertTrue(
+            getPermissionCrToggleByType(arcPermissionView, permissionType)
+                .checked);
+      };
+
+      await checkPermissionToggle('kLocation');
+      await checkPermissionToggle('kCamera');
+      await checkPermissionToggle('kNotifications');
+    });
+
+    test('OnClick handler for permission item works correctly', async () => {
+      const checkPermissionItemOnClick = async (permissionType) => {
+        assertTrue(getPermissionBoolByType(permissionType));
+        assertTrue(
+            getPermissionCrToggleByType(arcPermissionView, permissionType)
+                .checked);
+
+        // Toggle Off.
+        await clickPermissionItem(permissionType);
+        assertFalse(getPermissionBoolByType(permissionType));
+        assertFalse(
+            getPermissionCrToggleByType(arcPermissionView, permissionType)
+                .checked);
+
+        // Toggle On.
+        await clickPermissionItem(permissionType);
+        assertTrue(getPermissionBoolByType(permissionType));
+        assertTrue(
+            getPermissionCrToggleByType(arcPermissionView, permissionType)
+                .checked);
+      };
+
+      await checkPermissionItemOnClick('kLocation');
+      await checkPermissionItemOnClick('kCamera');
+      await checkPermissionItemOnClick('kNotifications');
+      await checkPermissionItemOnClick('kContacts');
+      await checkPermissionItemOnClick('kStorage');
+    });
+  });
+
   suite('Read-only permissions', () => {
     setup(async () => {
       loadTimeData.overrideValues(
diff --git a/chrome/test/data/webui/settings/chromeos/kerberos_page/kerberos_accounts_subpage_test.js b/chrome/test/data/webui/settings/chromeos/kerberos_page/kerberos_accounts_subpage_test.js
index ae0d73d..4eaa945 100644
--- a/chrome/test/data/webui/settings/chromeos/kerberos_page/kerberos_accounts_subpage_test.js
+++ b/chrome/test/data/webui/settings/chromeos/kerberos_page/kerberos_accounts_subpage_test.js
@@ -14,21 +14,14 @@
 import {getDeepActiveElement} from 'chrome://resources/ash/common/util.js';
 import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
 import {webUIListenerCallback} from 'chrome://resources/ash/common/cr.m.js';
-import {TestKerberosAccountsBrowserProxy, TEST_KERBEROS_ACCOUNTS} from './test_kerberos_accounts_browser_proxy.js';
+import {AccountIndex, TestKerberosAccountsBrowserProxy, TEST_KERBEROS_ACCOUNTS} from './test_kerberos_accounts_browser_proxy.js';
 
 // Tests for the Kerberos Accounts settings subpage.
-suite('KerberosAccountsTests', function() {
+suite('Kerberos accounts subpage tests', function() {
   let browserProxy = null;
   let kerberosAccounts = null;
   let accountList = null;
 
-  // Account indices (to help readability).
-  const Account = {
-    FIRST: 0,
-    SECOND: 1,
-    THIRD: 1,
-  };
-
   // Indices of 'More Actions' buttons.
   const MoreActions = {
     REFRESH_NOW: 0,
@@ -47,6 +40,10 @@
     browserProxy = new TestKerberosAccountsBrowserProxy();
     KerberosAccountsBrowserProxyImpl.setInstanceForTesting(browserProxy);
     PolymerTest.clearBody();
+
+    // Setting the default value of the relevant load time data.
+    loadTimeData.overrideValues({kerberosAddAccountsAllowed: true});
+
     createDialog();
   });
 
@@ -63,6 +60,7 @@
     kerberosAccounts =
         document.createElement('settings-kerberos-accounts-subpage');
     document.body.appendChild(kerberosAccounts);
+    flush();
 
     accountList = kerberosAccounts.shadowRoot.querySelector('#account-list');
     assertTrue(!!accountList);
@@ -89,14 +87,14 @@
     });
   }
 
-  test('AccountListIsPopulatedAtStartup', async () => {
+  test('Account list is populated at startup', async () => {
     await browserProxy.whenCalled('getAccounts');
     flush();
     // The test accounts were added in |getAccounts()| mock above.
     assertEquals(TEST_KERBEROS_ACCOUNTS.length, accountList.items.length);
   });
 
-  test('AccountListSignedInSignedOutLabels', async () => {
+  test('Account list signed-in signed-out labels', async () => {
     await browserProxy.whenCalled('getAccounts');
     flush();
     accountList =
@@ -106,23 +104,24 @@
     // Show 'Valid for <duration>' for accounts that are signed in.
     let signedIn = accountList[0].querySelector('.signed-in');
     let signedOut = accountList[0].querySelector('.signed-out');
-    assertTrue(TEST_KERBEROS_ACCOUNTS[0].isSignedIn);
+    assertTrue(TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].isSignedIn);
     assertFalse(signedIn.hidden);
     assertTrue(signedOut.hidden);
     assertEquals(
-        'Valid for ' + TEST_KERBEROS_ACCOUNTS[0].validForDuration,
+        'Valid for ' +
+            TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].validForDuration,
         signedIn.innerText);
 
     // Show 'Expired' for accounts that are not signed in.
     signedIn = accountList[1].querySelector('.signed-in');
     signedOut = accountList[1].querySelector('.signed-out');
-    assertFalse(TEST_KERBEROS_ACCOUNTS[1].isSignedIn);
+    assertFalse(TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND].isSignedIn);
     assertTrue(signedIn.hidden);
     assertFalse(signedOut.hidden);
     assertEquals('Expired', signedOut.innerText);
   });
 
-  test('AddAccount', function() {
+  test('Add account', function() {
     // The kerberos-add-account-dialog shouldn't be open yet.
     assertTrue(!kerberosAccounts.shadowRoot.querySelector(
         'kerberos-add-account-dialog'));
@@ -136,7 +135,7 @@
     assertEquals('', addDialog.$.username.value);
   });
 
-  test('ReauthenticateAccount', async () => {
+  test('Reauthenticate account', async () => {
     // Wait until accounts are loaded.
     await browserProxy.whenCalled('getAccounts');
     flush();
@@ -150,7 +149,7 @@
     // hidden, so click the second one (clicking a hidden button works, but
     // it feels weird).
     kerberosAccounts.shadowRoot
-        .querySelectorAll('.reauth-button')[Account.SECOND]
+        .querySelectorAll('.reauth-button')[AccountIndex.SECOND]
         .click();
     flush();
 
@@ -160,14 +159,15 @@
         'kerberos-add-account-dialog');
     assertTrue(!!addDialog);
     assertEquals(
-        TEST_KERBEROS_ACCOUNTS[Account.SECOND].principalName,
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND].principalName,
         addDialog.$.username.value);
   });
 
   // Appending '?kerberos_reauth=<principal>' to the URL opens the reauth
   // dialog for that account.
-  test('HandleReauthQueryParameter', async () => {
-    const principal_name = TEST_KERBEROS_ACCOUNTS[Account.FIRST].principalName;
+  test('Handle reauth query parameter', async () => {
+    const principal_name =
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].principalName;
     const params = new URLSearchParams();
     params.append('kerberos_reauth', principal_name);
     Router.getInstance().navigateTo(routes.KERBEROS_ACCOUNTS_V2, params);
@@ -183,28 +183,28 @@
     assertEquals(principal_name, addDialog.$.username.value);
   });
 
-  test('RefreshNow', async () => {
+  test('Refresh now', async () => {
     await browserProxy.whenCalled('getAccounts');
     flush();
-    clickMoreActions(Account.FIRST, MoreActions.REFRESH_NOW);
+    clickMoreActions(AccountIndex.FIRST, MoreActions.REFRESH_NOW);
     flush();
 
     const addDialog = kerberosAccounts.shadowRoot.querySelector(
         'kerberos-add-account-dialog');
     assertTrue(!!addDialog);
     assertEquals(
-        TEST_KERBEROS_ACCOUNTS[Account.FIRST].principalName,
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].principalName,
         addDialog.$.username.value);
   });
 
-  test('RefreshAccountShowsToast', async () => {
+  test('Refresh account shows toast', async () => {
     const toast = kerberosAccounts.shadowRoot.querySelector('#account-toast');
     assertTrue(!!toast);
     assertFalse(toast.open);
 
     await browserProxy.whenCalled('getAccounts');
     flush();
-    clickMoreActions(Account.FIRST, MoreActions.REFRESH_NOW);
+    clickMoreActions(AccountIndex.FIRST, MoreActions.REFRESH_NOW);
     flush();
 
     const addDialog = kerberosAccounts.shadowRoot.querySelector(
@@ -221,13 +221,13 @@
                    .innerHTML.includes('refreshed'));
   });
 
-  test('RemoveAccount', async () => {
+  test('Remove account', async () => {
     await browserProxy.whenCalled('getAccounts');
     flush();
-    clickMoreActions(Account.FIRST, MoreActions.REMOVE_ACCOUNT);
+    clickMoreActions(AccountIndex.FIRST, MoreActions.REMOVE_ACCOUNT);
     const account = await browserProxy.whenCalled('removeAccount');
     assertEquals(
-        TEST_KERBEROS_ACCOUNTS[Account.FIRST].principalName,
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].principalName,
         account.principalName);
   });
 
@@ -249,14 +249,14 @@
         'Kebab menu should be focused for settingId=1801.');
   });
 
-  test('RemoveAccountShowsToast', async () => {
+  test('Remove account shows toast', async () => {
     const toast = kerberosAccounts.shadowRoot.querySelector('#account-toast');
     assertTrue(!!toast);
     assertFalse(toast.open);
 
     await browserProxy.whenCalled('getAccounts');
     flush();
-    clickMoreActions(Account.FIRST, MoreActions.REMOVE_ACCOUNT);
+    clickMoreActions(AccountIndex.FIRST, MoreActions.REMOVE_ACCOUNT);
     await browserProxy.whenCalled('removeAccount');
     await flushTasks();
     flush();
@@ -265,26 +265,26 @@
                    .innerHTML.includes('removed'));
   });
 
-  test('AccountListIsUpdatedWhenKerberosAccountsUpdates', function() {
+  test('Account list is updated when Kerberos accounts updates', function() {
     assertEquals(1, browserProxy.getCallCount('getAccounts'));
     webUIListenerCallback('kerberos-accounts-changed');
     assertEquals(2, browserProxy.getCallCount('getAccounts'));
   });
 
-  test('SetAsActiveAccount', async () => {
+  test('Set as active account', async () => {
     await browserProxy.whenCalled('getAccounts');
     flush();
-    clickMoreActions(Account.SECOND, MoreActions.SET_AS_ACTIVE_ACCOUNT);
+    clickMoreActions(AccountIndex.SECOND, MoreActions.SET_AS_ACTIVE_ACCOUNT);
     const account = await browserProxy.whenCalled('setAsActiveAccount');
     assertEquals(
-        TEST_KERBEROS_ACCOUNTS[Account.SECOND].principalName,
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND].principalName,
         account.principalName);
   });
 
-  test('ShowPolicyIndicatorForManagedAccounts', async () => {
+  test('Show policy indicator for managed accounts', async () => {
     // Make sure we have at least one managed and one unmanaged account.
-    assertFalse(TEST_KERBEROS_ACCOUNTS[0].isManaged);
-    assertTrue(TEST_KERBEROS_ACCOUNTS[2].isManaged);
+    assertFalse(TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].isManaged);
+    assertTrue(TEST_KERBEROS_ACCOUNTS[AccountIndex.THIRD].isManaged);
 
     await browserProxy.whenCalled('getAccounts');
     flush();
@@ -319,576 +319,23 @@
     }
   });
 
-  test('AddAccountsAllowed', function() {
+  test('Add accounts allowed', function() {
     assertTrue(loadTimeData.getBoolean('kerberosAddAccountsAllowed'));
     createDialog();
+
     assertTrue(!kerberosAccounts.shadowRoot.querySelector(
         '#add-account-policy-indicator'));
     assertFalse(kerberosAccounts.shadowRoot.querySelector('#add-account-button')
                     .disabled);
   });
 
-  test('AddAccountsNotAllowed', function() {
+  test('Add accounts not allowed', function() {
     loadTimeData.overrideValues({kerberosAddAccountsAllowed: false});
     createDialog();
-    flush();
+
     assertTrue(!!kerberosAccounts.shadowRoot.querySelector(
         '#add-account-policy-indicator'));
     assertTrue(kerberosAccounts.shadowRoot.querySelector('#add-account-button')
                    .disabled);
-
-    // Reset for further tests.
-    loadTimeData.overrideValues({kerberosAddAccountsAllowed: true});
-  });
-});
-
-// Tests for the kerberos-add-account-dialog element.
-suite('KerberosAddAccountTests', function() {
-  let browserProxy = null;
-
-  let dialog = null;
-  let addDialog = null;
-
-  let username = null;
-  let password = null;
-  let rememberPassword = null;
-  let advancedConfigButton = null;
-  let actionButton = null;
-  let generalError = null;
-  let title = null;
-
-  // Indices of 'addAccount' params.
-  const AddParams = {
-    PRINCIPAL_NAME: 0,
-    PASSWORD: 1,
-    REMEMBER_PASSWORD: 2,
-    CONFIG: 3,
-    ALLOW_EXISTING: 4,
-  };
-
-  setup(function() {
-    browserProxy = new TestKerberosAccountsBrowserProxy();
-    KerberosAccountsBrowserProxyImpl.setInstanceForTesting(browserProxy);
-    PolymerTest.clearBody();
-
-    // Start test with the "Remember password by default" feature enabled.
-    loadTimeData.overrideValues({kerberosRememberPasswordByDefault: true});
-    createDialog(null);
-  });
-
-  teardown(function() {
-    dialog.remove();
-    KerberosAccountsBrowserProxyImpl.setInstanceForTesting(undefined);
-  });
-
-  function createDialog(presetAccount) {
-    if (dialog) {
-      dialog.remove();
-    }
-
-    dialog = document.createElement('kerberos-add-account-dialog');
-    dialog.presetAccount = presetAccount;
-    document.body.appendChild(dialog);
-
-    addDialog = dialog.$.addDialog;
-    assertTrue(!!addDialog);
-
-    username = dialog.$.username;
-    assertTrue(!!username);
-
-    password = dialog.$.password;
-    assertTrue(!!password);
-
-    rememberPassword = dialog.$.rememberPassword;
-    assertTrue(!!rememberPassword);
-
-    advancedConfigButton = dialog.$.advancedConfigButton;
-    assertTrue(!!advancedConfigButton);
-
-    actionButton = addDialog.querySelector('.action-button');
-    assertTrue(!!actionButton);
-
-    generalError = dialog.$['general-error-message'];
-    assertTrue(!!generalError);
-
-    title = dialog.shadowRoot.querySelector('[slot=title]').innerText;
-    assertTrue(!!title);
-  }
-
-  // Sets |error| as error result for addAccount(), simulates a click on the
-  // addAccount button and checks that |errorElement| has an non-empty
-  // innerText value afterwards.
-  async function checkAddAccountError(error, errorElement) {
-    flush();
-    assertEquals(0, errorElement.innerText.length);
-    browserProxy.addAccountError = error;
-    actionButton.click();
-    await browserProxy.whenCalled('addAccount');
-    flush();
-    assertNotEquals(0, errorElement.innerText.length);
-  }
-
-  // Opens the Advanced Config dialog, sets |config| as Kerberos configuration
-  // and clicks 'Save'. Returns a promise with the validation result.
-  async function setConfig(config) {
-    advancedConfigButton.click();
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-    const advancedConfigDialog =
-        dialog.shadowRoot.querySelector('#advancedConfigDialog');
-    const configElement = advancedConfigDialog.querySelector('#config');
-    assertFalse(configElement.disabled);
-    configElement.value = config;
-    advancedConfigDialog.querySelector('.action-button').click();
-    flush();
-    return browserProxy.whenCalled('validateConfig');
-  }
-
-  // Opens the Advanced Config dialog, asserts that |config| is set as
-  // Kerberos configuration and clicks 'Cancel'.
-  async function assertConfig(config) {
-    advancedConfigButton.click();
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-    const advancedConfigDialog =
-        dialog.shadowRoot.querySelector('#advancedConfigDialog');
-    assertEquals(config, advancedConfigDialog.querySelector('#config').value);
-    advancedConfigDialog.querySelector('.cancel-button').click();
-    flush();
-  }
-
-  // Verifies expected states if no account is preset and password should be
-  // remembered by default.
-  test('StatesWithoutPresetAccountPasswordRemembered', async () => {
-    assertTrue(title.startsWith('Add'));
-    assertEquals('Add', actionButton.innerText);
-    assertFalse(username.disabled);
-    assertEquals('', username.value);
-    assertEquals('', password.value);
-    assertConfig(loadTimeData.getString('defaultKerberosConfig'));
-    assertTrue(rememberPassword.checked);
-  });
-
-  // Verifies the rememberPassword state if no account is preset and password
-  // should not be remembered by default.
-  test('StatesWithoutPresetAccountPasswordNotRemembered', async () => {
-    loadTimeData.overrideValues({kerberosRememberPasswordByDefault: false});
-    createDialog(null);
-    flush();
-
-    assertFalse(rememberPassword.checked);
-  });
-
-  // Verifies expected states if an account is preset.
-  test('StatesWithPresetAccount', async () => {
-    createDialog(TEST_KERBEROS_ACCOUNTS[0]);
-    assertTrue(title.startsWith('Refresh'));
-    assertEquals('Refresh', actionButton.innerText);
-    assertTrue(username.readonly);
-    assertEquals(TEST_KERBEROS_ACCOUNTS[0].principalName, username.value);
-    assertConfig(TEST_KERBEROS_ACCOUNTS[0].config);
-    // Password and remember password are tested below since the contents
-    // depends on the passwordWasRemembered property of the account.
-  });
-
-  // The password input field is empty and 'Remember password' is checked if
-  // |passwordWasRemembered| is false and the password should be remembered by
-  // default.
-  test('PasswordNotPresetIfPasswordWasNotRemembered', function() {
-    assertFalse(TEST_KERBEROS_ACCOUNTS[0].passwordWasRemembered);
-    createDialog(TEST_KERBEROS_ACCOUNTS[0]);
-    assertEquals('', password.value);
-    assertTrue(rememberPassword.checked);
-  });
-
-  // The password input field is empty and 'Remember password' is not checked if
-  // |passwordWasRemembered| is false and the password should not be remembered
-  // by default.
-  test('PasswordPresetIfPasswordWasNotRememberedAndFeatureEnabled', function() {
-    loadTimeData.overrideValues({kerberosRememberPasswordByDefault: false});
-    createDialog(null);
-    flush();
-
-    assertFalse(TEST_KERBEROS_ACCOUNTS[0].passwordWasRemembered);
-    createDialog(TEST_KERBEROS_ACCOUNTS[0]);
-    assertEquals('', password.value);
-    assertFalse(rememberPassword.checked);
-  });
-
-  // The password input field is not empty and 'Remember password' is checked
-  // if |passwordWasRemembered| is true.
-  test('PasswordPresetIfPasswordWasRemembered', function() {
-    assertTrue(TEST_KERBEROS_ACCOUNTS[1].passwordWasRemembered);
-    createDialog(TEST_KERBEROS_ACCOUNTS[1]);
-    assertNotEquals('', password.value);
-    assertTrue(rememberPassword.checked);
-  });
-
-  test('RememberPasswordEnabled', function() {
-    assertTrue(loadTimeData.getBoolean('kerberosRememberPasswordEnabled'));
-    assertTrue(TEST_KERBEROS_ACCOUNTS[1].passwordWasRemembered);
-    createDialog(TEST_KERBEROS_ACCOUNTS[1]);
-
-    assertTrue(
-        !dialog.shadowRoot.querySelector('#rememberPasswordPolicyIndicator'));
-    assertFalse(rememberPassword.disabled);
-    assertTrue(rememberPassword.checked);
-    assertNotEquals('', password.value);
-  });
-
-  test('RememberPasswordDisabled', function() {
-    loadTimeData.overrideValues({kerberosRememberPasswordEnabled: false});
-    assertTrue(TEST_KERBEROS_ACCOUNTS[1].passwordWasRemembered);
-    createDialog(TEST_KERBEROS_ACCOUNTS[1]);
-    flush();
-
-    assertTrue(
-        !!dialog.shadowRoot.querySelector('#rememberPasswordPolicyIndicator'));
-    assertTrue(rememberPassword.disabled);
-    assertFalse(rememberPassword.checked);
-    assertEquals('', password.value);
-
-    // Reset for further tests.
-    loadTimeData.overrideValues({kerberosRememberPasswordEnabled: true});
-  });
-
-  test('RememberPasswordVisibleAndCheckedOnUserSessions', function() {
-    assertFalse(loadTimeData.getBoolean('isGuest'));
-    createDialog(null);
-    flush();
-
-    assertFalse(
-        dialog.shadowRoot.querySelector('#rememberPasswordContainer').hidden);
-    assertTrue(rememberPassword.checked);
-  });
-
-  test('RememberPasswordHiddenAndNotCheckedOnMgs', function() {
-    loadTimeData.overrideValues({isGuest: true});
-    createDialog(null);
-    flush();
-
-    assertTrue(
-        dialog.shadowRoot.querySelector('#rememberPasswordContainer').hidden);
-    assertFalse(rememberPassword.checked);
-
-    // Reset for further tests.
-    loadTimeData.overrideValues({isGuest: false});
-  });
-
-  // By clicking the action button, all field values are passed to the
-  // 'addAccount' browser proxy method.
-  test('ActionButtonPassesFieldValues', async () => {
-    const EXPECTED_USER = 'testuser';
-    const EXPECTED_PASS = 'testpass';
-    const EXPECTED_REMEMBER_PASS = true;
-    const EXPECTED_CONFIG = 'testconf';
-
-    username.value = EXPECTED_USER;
-    password.value = EXPECTED_PASS;
-    const result = await setConfig(EXPECTED_CONFIG);
-    rememberPassword.checked = EXPECTED_REMEMBER_PASS;
-
-    assertFalse(actionButton.disabled);
-    actionButton.click();
-    const args = await browserProxy.whenCalled('addAccount');
-    assertEquals(EXPECTED_USER, args[AddParams.PRINCIPAL_NAME]);
-    assertEquals(EXPECTED_PASS, args[AddParams.PASSWORD]);
-    assertEquals(EXPECTED_REMEMBER_PASS, args[AddParams.REMEMBER_PASSWORD]);
-    assertEquals(EXPECTED_CONFIG, args[AddParams.CONFIG]);
-
-    // Should be false if a new account is added. See also
-    // AllowExistingIsTrueForPresetAccounts test.
-    assertFalse(args[AddParams.ALLOW_EXISTING]);
-  });
-
-  // If an account is preset, overwriting that account should be allowed.
-  test('AllowExistingIsTrueForPresetAccounts', async () => {
-    // Populate dialog with preset account.
-    createDialog(TEST_KERBEROS_ACCOUNTS[1]);
-    actionButton.click();
-    const args = await browserProxy.whenCalled('addAccount');
-    assertTrue(args[AddParams.ALLOW_EXISTING]);
-  });
-
-  // While an account is being added, the action button is disabled.
-  test('ActionButtonDisableWhileInProgress', async () => {
-    assertFalse(actionButton.disabled);
-    actionButton.click();
-    assertTrue(actionButton.disabled);
-    await browserProxy.whenCalled('addAccount');
-    assertFalse(actionButton.disabled);
-  });
-
-  // If the account has passwordWasRemembered === true and the user just
-  // clicks the 'Add' button, an empty password is submitted.
-  test('SubmitsEmptyPasswordIfRememberedPasswordIsUsed', async () => {
-    assertTrue(TEST_KERBEROS_ACCOUNTS[1].passwordWasRemembered);
-    createDialog(TEST_KERBEROS_ACCOUNTS[1]);
-    actionButton.click();
-    const args = await browserProxy.whenCalled('addAccount');
-    assertEquals('', args[AddParams.PASSWORD]);
-    assertTrue(args[AddParams.REMEMBER_PASSWORD]);
-  });
-
-  // If the account has passwordWasRemembered === true and the user changes
-  // the password before clicking the action button, the changed password is
-  // submitted.
-  test('SubmitsChangedPasswordIfRememberedPasswordIsChanged', async () => {
-    assertTrue(TEST_KERBEROS_ACCOUNTS[1].passwordWasRemembered);
-    createDialog(TEST_KERBEROS_ACCOUNTS[1]);
-    password.inputElement.value = 'some edit';
-    password.dispatchEvent(new CustomEvent('input'));
-    actionButton.click();
-    const args = await browserProxy.whenCalled('addAccount');
-    assertNotEquals('', args[AddParams.PASSWORD]);
-    assertTrue(args[AddParams.REMEMBER_PASSWORD]);
-  });
-
-  test('AdvancedConfigOpenClose', async () => {
-    assertTrue(!dialog.shadowRoot.querySelector('#advancedConfigDialog'));
-    assertFalse(addDialog.hidden);
-    advancedConfigButton.click();
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-
-    const advancedConfigDialog =
-        dialog.shadowRoot.querySelector('#advancedConfigDialog');
-    assertTrue(!!advancedConfigDialog);
-    assertTrue(advancedConfigDialog.open);
-    assertTrue(addDialog.hidden);
-    const saveButton = advancedConfigDialog.querySelector('.action-button');
-    assertFalse(saveButton.disabled);
-    saveButton.click();
-    flush();
-    assertTrue(saveButton.disabled);
-
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-    assertFalse(saveButton.disabled);
-    assertTrue(!dialog.shadowRoot.querySelector('#advancedConfigDialog'));
-    assertFalse(addDialog.hidden);
-    assertTrue(addDialog.open);
-  });
-
-  test('AdvancedConfigurationSaveKeepsConfig', async () => {
-    advancedConfigButton.click();
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-    const advancedConfigDialog =
-        dialog.shadowRoot.querySelector('#advancedConfigDialog');
-    assertTrue(!!advancedConfigDialog);
-
-    // Change config and save.
-    const modifiedConfig = 'modified';
-    advancedConfigDialog.querySelector('#config').value = modifiedConfig;
-    advancedConfigDialog.querySelector('.action-button').click();
-
-    // Changed value should stick.
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-    assertConfig(modifiedConfig);
-  });
-
-  test('AdvancedConfigurationCancelResetsConfig', async () => {
-    advancedConfigButton.click();
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-    const advancedConfigDialog =
-        dialog.shadowRoot.querySelector('#advancedConfigDialog');
-    assertTrue(!!advancedConfigDialog);
-
-    // Change config and cancel.
-    const prevConfig = advancedConfigDialog.querySelector('#config').value;
-    advancedConfigDialog.querySelector('#config').value = 'modified';
-    advancedConfigDialog.querySelector('.cancel-button').click();
-    flush();
-
-    // Changed value should NOT stick.
-    assertConfig(prevConfig);
-  });
-
-  test('AdvancedConfigurationDisabledByPolicy', async () => {
-    assertTrue(TEST_KERBEROS_ACCOUNTS[2].isManaged);
-    createDialog(TEST_KERBEROS_ACCOUNTS[2]);
-    advancedConfigButton.click();
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-    const advancedConfigDialog =
-        dialog.shadowRoot.querySelector('#advancedConfigDialog');
-    assertTrue(!!advancedConfigDialog);
-    assertTrue(
-        !!advancedConfigDialog.querySelector('#advancedConfigPolicyIndicator'));
-    assertTrue(advancedConfigDialog.querySelector('#config').disabled);
-  });
-
-  test('AdvancedConfigurationValidationError', async () => {
-    advancedConfigButton.click();
-    await browserProxy.whenCalled('validateConfig');
-    flush();
-    const advancedConfigDialog =
-        dialog.shadowRoot.querySelector('#advancedConfigDialog');
-    assertTrue(!!advancedConfigDialog);
-
-    // Cause a validation error.
-    browserProxy.validateConfigResult = {
-      error: KerberosErrorType.BAD_CONFIG,
-      errorInfo:
-          {code: KerberosConfigErrorCode.KEY_NOT_SUPPORTED, lineIndex: 0},
-    };
-
-    // Clicking the action button (aka 'Save') validates the config.
-    advancedConfigDialog.querySelector('.action-button').click();
-
-    await browserProxy.whenCalled('validateConfig');
-
-    // Wait for dialog to process the 'validateConfig' result (sets error
-    // message etc.).
-    await flushTasks();
-
-    // Is some error text set?
-    const configError =
-        advancedConfigDialog.querySelector('#config-error-message');
-    assertTrue(!!configError);
-    assertNotEquals(0, configError.innerText.length);
-
-    // Is something selected?
-    const configElement = advancedConfigDialog.querySelector('#config');
-    const textArea = configElement.$.input;
-    assertEquals(0, textArea.selectionStart);
-    assertNotEquals(0, textArea.selectionEnd);
-
-    // Is the config dialog still open?
-    assertTrue(advancedConfigDialog.open);
-    assertTrue(addDialog.hidden);
-
-    // Was the config not accepted?
-    advancedConfigDialog.querySelector('.cancel-button').click();
-    flush();
-    assertConfig(loadTimeData.getString('defaultKerberosConfig'));
-  });
-
-  test('ValidateConfigurationOnAdvancedClick', async () => {
-    // Cause a validation error.
-    browserProxy.validateConfigResult = {
-      error: KerberosErrorType.BAD_CONFIG,
-      errorInfo:
-          {code: KerberosConfigErrorCode.KEY_NOT_SUPPORTED, lineIndex: 0},
-    };
-
-    // Validating happens on "Advanced" click.
-    advancedConfigButton.click();
-    await browserProxy.whenCalled('validateConfig');
-
-    // Wait for dialog to process the 'validateConfig' result (sets error
-    // message etc.).
-    await flushTasks();
-
-    const advancedConfigDialog =
-        dialog.shadowRoot.querySelector('#advancedConfigDialog');
-    assertTrue(!!advancedConfigDialog);
-
-    // Is some error text set?
-    const configError =
-        advancedConfigDialog.querySelector('#config-error-message');
-    assertTrue(!!configError);
-    assertNotEquals(0, configError.innerText.length);
-
-    // Is something selected?
-    const configElement = advancedConfigDialog.querySelector('#config');
-    const textArea = configElement.$.input;
-    assertEquals(0, textArea.selectionStart);
-    assertNotEquals(0, textArea.selectionEnd);
-  });
-
-  test('DomainAutocompleteEnabled', function() {
-    loadTimeData.overrideValues({kerberosDomainAutocomplete: 'domain.com'});
-    createDialog();
-    flush();
-
-    // '@' should be automatically added to the policy value.
-    assertEquals(
-        '@domain.com',
-        dialog.shadowRoot.querySelector('#kerberosDomain').innerText);
-
-    // Reset for further tests.
-    loadTimeData.overrideValues({kerberosDomainAutocomplete: ''});
-  });
-
-  test('DomainAutocompleteEnabledOverride', function() {
-    loadTimeData.overrideValues({kerberosDomainAutocomplete: 'domain.com'});
-    assertTrue(
-        TEST_KERBEROS_ACCOUNTS[0].principalName &&
-        TEST_KERBEROS_ACCOUNTS[0].principalName.indexOf('@') !== -1);
-    createDialog(TEST_KERBEROS_ACCOUNTS[0]);
-    flush();
-
-    // If inserted principal contains '@', nothing should be shown.
-    assertEquals(
-        '', dialog.shadowRoot.querySelector('#kerberosDomain').innerText);
-
-    // Reset for further tests.
-    loadTimeData.overrideValues({kerberosDomainAutocomplete: ''});
-  });
-
-  test('DomainAutocompleteDisabled', function() {
-    assertEquals('', loadTimeData.getString('kerberosDomainAutocomplete'));
-    assertEquals(
-        '', dialog.shadowRoot.querySelector('#kerberosDomain').innerText);
-  });
-
-  // addAccount: KerberosErrorType.kNetworkProblem spawns a general error.
-  test('AddAccountError_NetworkProblem', async () => {
-    await checkAddAccountError(KerberosErrorType.NETWORK_PROBLEM, generalError);
-  });
-
-  // addAccount: KerberosErrorType.kParsePrincipalFailed spawns a username
-  // error.
-  test('AddAccountError_ParsePrincipalFailed', async () => {
-    await checkAddAccountError(
-        KerberosErrorType.PARSE_PRINCIPAL_FAILED, username.$.error);
-  });
-
-  // addAccount: KerberosErrorType.BAD_PRINCIPAL spawns a username error.
-  test('AddAccountError_BadPrincipal', async () => {
-    await checkAddAccountError(
-        KerberosErrorType.BAD_PRINCIPAL, username.$.error);
-  });
-
-  // addAccount: KerberosErrorType.DUPLICATE_PRINCIPAL_NAME spawns a username
-  // error.
-  test('AddAccountError_DuplicatePrincipalName', async () => {
-    await checkAddAccountError(
-        KerberosErrorType.DUPLICATE_PRINCIPAL_NAME, username.$.error);
-  });
-
-  // addAccount: KerberosErrorType.CONTACTING_KDC_FAILED spawns a username
-  // error.
-  test('AddAccountError_ContactingKdcFailed', async () => {
-    await checkAddAccountError(
-        KerberosErrorType.CONTACTING_KDC_FAILED, username.$.error);
-  });
-
-  // addAccount: KerberosErrorType.BAD_PASSWORD spawns a password error.
-  test('AddAccountError_BadPassword', async () => {
-    await checkAddAccountError(
-        KerberosErrorType.BAD_PASSWORD, password.$.error);
-  });
-
-  // addAccount: KerberosErrorType.PASSWORD_EXPIRED spawns a password error.
-  test('AddAccountError_PasswordExpired', async () => {
-    await checkAddAccountError(
-        KerberosErrorType.PASSWORD_EXPIRED, password.$.error);
-  });
-
-  // addAccount: KerberosErrorType.KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE spawns
-  // a general error.
-  test('AddAccountError_KdcDoesNotSupportEncryptionType', async () => {
-    await checkAddAccountError(
-        KerberosErrorType.KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE, generalError);
-  });
-
-  // addAccount: KerberosErrorType.UNKNOWN spawns a general error.
-  test('AddAccountError_Unknown', async () => {
-    await checkAddAccountError(KerberosErrorType.UNKNOWN, generalError);
   });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/kerberos_page/kerberos_add_account_dialog_test.js b/chrome/test/data/webui/settings/chromeos/kerberos_page/kerberos_add_account_dialog_test.js
new file mode 100644
index 0000000..6e59ea0f
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/kerberos_page/kerberos_add_account_dialog_test.js
@@ -0,0 +1,569 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+import 'chrome://os-settings/lazy_load.js';
+
+import {KerberosAccountsBrowserProxyImpl, KerberosConfigErrorCode, KerberosErrorType} from 'chrome://os-settings/lazy_load.js';
+import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
+import {AccountIndex, TestKerberosAccountsBrowserProxy, TEST_KERBEROS_ACCOUNTS} from './test_kerberos_accounts_browser_proxy.js';
+
+// Tests for the kerberos-add-account-dialog element.
+suite('Kerberos add account dialog tests', function() {
+  let browserProxy = null;
+
+  let dialog = null;
+  let addDialog = null;
+
+  let username = null;
+  let password = null;
+  let rememberPassword = null;
+  let advancedConfigButton = null;
+  let actionButton = null;
+  let generalError = null;
+  let title = null;
+
+  // Indices of 'addAccount' params.
+  const AddParams = {
+    PRINCIPAL_NAME: 0,
+    PASSWORD: 1,
+    REMEMBER_PASSWORD: 2,
+    CONFIG: 3,
+    ALLOW_EXISTING: 4,
+  };
+
+  setup(function() {
+    browserProxy = new TestKerberosAccountsBrowserProxy();
+    KerberosAccountsBrowserProxyImpl.setInstanceForTesting(browserProxy);
+    PolymerTest.clearBody();
+
+    // Setting the default value of the relevant load time data.
+    loadTimeData.overrideValues({kerberosRememberPasswordByDefault: true});
+    loadTimeData.overrideValues({kerberosRememberPasswordEnabled: true});
+    loadTimeData.overrideValues({isGuest: false});
+    loadTimeData.overrideValues({kerberosDomainAutocomplete: ''});
+
+    createDialog(null);
+  });
+
+  teardown(function() {
+    dialog.remove();
+    KerberosAccountsBrowserProxyImpl.setInstanceForTesting(undefined);
+  });
+
+  function createDialog(presetAccount) {
+    if (dialog) {
+      dialog.remove();
+    }
+
+    dialog = document.createElement('kerberos-add-account-dialog');
+    dialog.presetAccount = presetAccount;
+    document.body.appendChild(dialog);
+    flush();
+
+    addDialog = dialog.$.addDialog;
+    assertTrue(!!addDialog);
+
+    username = dialog.$.username;
+    assertTrue(!!username);
+
+    password = dialog.$.password;
+    assertTrue(!!password);
+
+    rememberPassword = dialog.$.rememberPassword;
+    assertTrue(!!rememberPassword);
+
+    advancedConfigButton = dialog.$.advancedConfigButton;
+    assertTrue(!!advancedConfigButton);
+
+    actionButton = addDialog.querySelector('.action-button');
+    assertTrue(!!actionButton);
+
+    generalError = dialog.$['general-error-message'];
+    assertTrue(!!generalError);
+
+    title = dialog.shadowRoot.querySelector('[slot=title]').innerText;
+    assertTrue(!!title);
+  }
+
+  // Sets |error| as error result for addAccount(), simulates a click on the
+  // addAccount button and checks that |errorElement| has an non-empty
+  // innerText value afterwards.
+  async function checkAddAccountError(error, errorElement) {
+    flush();
+    assertEquals(0, errorElement.innerText.length);
+    browserProxy.addAccountError = error;
+    actionButton.click();
+    await browserProxy.whenCalled('addAccount');
+    flush();
+    assertNotEquals(0, errorElement.innerText.length);
+  }
+
+  // Opens the Advanced Config dialog, sets |config| as Kerberos configuration
+  // and clicks 'Save'. Returns a promise with the validation result.
+  async function setConfig(config) {
+    advancedConfigButton.click();
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
+    const configElement = advancedConfigDialog.querySelector('#config');
+    assertFalse(configElement.disabled);
+    configElement.value = config;
+    advancedConfigDialog.querySelector('.action-button').click();
+    flush();
+    return browserProxy.whenCalled('validateConfig');
+  }
+
+  // Opens the Advanced Config dialog, asserts that |config| is set as
+  // Kerberos configuration and clicks 'Cancel'.
+  async function assertConfig(config) {
+    advancedConfigButton.click();
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
+    assertEquals(config, advancedConfigDialog.querySelector('#config').value);
+    advancedConfigDialog.querySelector('.cancel-button').click();
+    flush();
+  }
+
+  // Verifies expected states if no account is preset and password should be
+  // remembered by default.
+  test('State without preset account and remember password check', async () => {
+    assertTrue(loadTimeData.getBoolean('kerberosRememberPasswordByDefault'));
+
+    assertTrue(title.startsWith('Add'));
+    assertEquals('Add', actionButton.innerText);
+    assertFalse(username.disabled);
+    assertEquals('', username.value);
+    assertEquals('', password.value);
+    assertConfig(loadTimeData.getString('defaultKerberosConfig'));
+    assertTrue(rememberPassword.checked);
+  });
+
+  // Verifies the rememberPassword state if no account is preset and password
+  // should not be remembered by default.
+  test('State without preset account and password not remembered', async () => {
+    loadTimeData.overrideValues({kerberosRememberPasswordByDefault: false});
+    createDialog(null);
+
+    assertFalse(rememberPassword.checked);
+  });
+
+  // Verifies expected state if an account is preset.
+  test('State with preset account', async () => {
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST]);
+    assertTrue(title.startsWith('Refresh'));
+    assertEquals('Refresh', actionButton.innerText);
+    assertTrue(username.readonly);
+    assertEquals(
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].principalName,
+        username.value);
+    assertConfig(TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].config);
+    // Password and remember password are tested below since the contents
+    // depends on the passwordWasRemembered property of the account.
+  });
+
+  // The password input field is empty and 'Remember password' is checked if
+  // |passwordWasRemembered| is false and the password should be remembered by
+  // default.
+  test('Password not preset if password was not remembered', function() {
+    assertTrue(loadTimeData.getBoolean('kerberosRememberPasswordByDefault'));
+    assertFalse(TEST_KERBEROS_ACCOUNTS[0].passwordWasRemembered);
+    createDialog(TEST_KERBEROS_ACCOUNTS[0]);
+
+    assertEquals('', password.value);
+    assertTrue(rememberPassword.checked);
+  });
+
+  // The password input field is empty and 'Remember password' is not checked if
+  // |passwordWasRemembered| is false and the password should not be remembered
+  // by default.
+  test(
+      'Checkbox unchecked if password was not remembered and feature disabled',
+      function() {
+        loadTimeData.overrideValues({kerberosRememberPasswordByDefault: false});
+        createDialog(null);
+
+        assertFalse(
+            TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].passwordWasRemembered);
+        createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST]);
+        assertEquals('', password.value);
+        assertFalse(rememberPassword.checked);
+      });
+
+  // The password input field is not empty and 'Remember password' is checked
+  // if |passwordWasRemembered| is true.
+  test('Password preset if password was remembered', function() {
+    assertTrue(
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND].passwordWasRemembered);
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND]);
+    assertNotEquals('', password.value);
+    assertTrue(rememberPassword.checked);
+  });
+
+  test('Remember password enabled', function() {
+    assertTrue(loadTimeData.getBoolean('kerberosRememberPasswordEnabled'));
+    assertTrue(
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND].passwordWasRemembered);
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND]);
+
+    assertTrue(
+        !dialog.shadowRoot.querySelector('#rememberPasswordPolicyIndicator'));
+    assertFalse(rememberPassword.disabled);
+    assertTrue(rememberPassword.checked);
+    assertNotEquals('', password.value);
+  });
+
+  test('Remember password disabled', function() {
+    loadTimeData.overrideValues({kerberosRememberPasswordEnabled: false});
+    assertTrue(
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND].passwordWasRemembered);
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND]);
+
+    assertTrue(
+        !!dialog.shadowRoot.querySelector('#rememberPasswordPolicyIndicator'));
+    assertTrue(rememberPassword.disabled);
+    assertFalse(rememberPassword.checked);
+    assertEquals('', password.value);
+  });
+
+  test('Remember password visible and checked on user sessions', function() {
+    assertFalse(loadTimeData.getBoolean('isGuest'));
+    createDialog(null);
+
+    assertFalse(
+        dialog.shadowRoot.querySelector('#rememberPasswordContainer').hidden);
+    assertTrue(rememberPassword.checked);
+  });
+
+  test('Remember password hidden and not checked on MGS', function() {
+    loadTimeData.overrideValues({isGuest: true});
+    createDialog(null);
+
+    assertTrue(
+        dialog.shadowRoot.querySelector('#rememberPasswordContainer').hidden);
+    assertFalse(rememberPassword.checked);
+  });
+
+  // By clicking the action button, all field values are passed to the
+  // 'addAccount' browser proxy method.
+  test('Action button passes field values', async () => {
+    const EXPECTED_USER = 'testuser';
+    const EXPECTED_PASS = 'testpass';
+    const EXPECTED_REMEMBER_PASS = true;
+    const EXPECTED_CONFIG = 'testconf';
+
+    username.value = EXPECTED_USER;
+    password.value = EXPECTED_PASS;
+    const result = await setConfig(EXPECTED_CONFIG);
+    rememberPassword.checked = EXPECTED_REMEMBER_PASS;
+
+    assertFalse(actionButton.disabled);
+    actionButton.click();
+    const args = await browserProxy.whenCalled('addAccount');
+    assertEquals(EXPECTED_USER, args[AddParams.PRINCIPAL_NAME]);
+    assertEquals(EXPECTED_PASS, args[AddParams.PASSWORD]);
+    assertEquals(EXPECTED_REMEMBER_PASS, args[AddParams.REMEMBER_PASSWORD]);
+    assertEquals(EXPECTED_CONFIG, args[AddParams.CONFIG]);
+
+    // Should be false if a new account is added. See also
+    // AllowExistingIsTrueForPresetAccounts test.
+    assertFalse(args[AddParams.ALLOW_EXISTING]);
+  });
+
+  // If an account is preset, overwriting that account should be allowed.
+  test('Allow existing is true for preset accounts', async () => {
+    // Populate dialog with preset account.
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND]);
+    actionButton.click();
+    const args = await browserProxy.whenCalled('addAccount');
+    assertTrue(args[AddParams.ALLOW_EXISTING]);
+  });
+
+  // While an account is being added, the action button is disabled.
+  test('Action button disable while in progress', async () => {
+    assertFalse(actionButton.disabled);
+    actionButton.click();
+    assertTrue(actionButton.disabled);
+    await browserProxy.whenCalled('addAccount');
+    assertFalse(actionButton.disabled);
+  });
+
+  // If the account has passwordWasRemembered === true and the user just
+  // clicks the 'Add' button, an empty password is submitted.
+  test('Submits empty password if remembered password is used', async () => {
+    assertTrue(
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND].passwordWasRemembered);
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND]);
+    actionButton.click();
+    const args = await browserProxy.whenCalled('addAccount');
+    assertEquals('', args[AddParams.PASSWORD]);
+    assertTrue(args[AddParams.REMEMBER_PASSWORD]);
+  });
+
+  // If the account has passwordWasRemembered === true and the user changes
+  // the password before clicking the action button, the changed password is
+  // submitted.
+  test('Submits changed password if password field was changed', async () => {
+    assertTrue(
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND].passwordWasRemembered);
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.SECOND]);
+    password.inputElement.value = 'some edit';
+    password.dispatchEvent(new CustomEvent('input'));
+    actionButton.click();
+    const args = await browserProxy.whenCalled('addAccount');
+    assertNotEquals('', args[AddParams.PASSWORD]);
+    assertTrue(args[AddParams.REMEMBER_PASSWORD]);
+  });
+
+  test('Advanced config open and close', async () => {
+    assertTrue(!dialog.shadowRoot.querySelector('#advancedConfigDialog'));
+    assertFalse(addDialog.hidden);
+    advancedConfigButton.click();
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
+    assertTrue(!!advancedConfigDialog);
+    assertTrue(advancedConfigDialog.open);
+    assertTrue(addDialog.hidden);
+    const saveButton = advancedConfigDialog.querySelector('.action-button');
+    assertFalse(saveButton.disabled);
+    saveButton.click();
+    flush();
+    assertTrue(saveButton.disabled);
+
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+    assertFalse(saveButton.disabled);
+    assertTrue(!dialog.shadowRoot.querySelector('#advancedConfigDialog'));
+    assertFalse(addDialog.hidden);
+    assertTrue(addDialog.open);
+  });
+
+  test('Advanced configuration save keeps config', async () => {
+    advancedConfigButton.click();
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
+    assertTrue(!!advancedConfigDialog);
+
+    // Change config and save.
+    const modifiedConfig = 'modified';
+    advancedConfigDialog.querySelector('#config').value = modifiedConfig;
+    advancedConfigDialog.querySelector('.action-button').click();
+
+    // Changed value should stick.
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+    assertConfig(modifiedConfig);
+  });
+
+  test('Advanced configuration cancel resets config', async () => {
+    advancedConfigButton.click();
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
+    assertTrue(!!advancedConfigDialog);
+
+    // Change config and cancel.
+    const prevConfig = advancedConfigDialog.querySelector('#config').value;
+    advancedConfigDialog.querySelector('#config').value = 'modified';
+    advancedConfigDialog.querySelector('.cancel-button').click();
+    flush();
+
+    // Changed value should NOT stick.
+    assertConfig(prevConfig);
+  });
+
+  test('Advanced configuration disabled by policy', async () => {
+    assertTrue(TEST_KERBEROS_ACCOUNTS[AccountIndex.THIRD].isManaged);
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.THIRD]);
+    advancedConfigButton.click();
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
+    assertTrue(!!advancedConfigDialog);
+    assertTrue(
+        !!advancedConfigDialog.querySelector('#advancedConfigPolicyIndicator'));
+    assertTrue(advancedConfigDialog.querySelector('#config').disabled);
+  });
+
+  test('Advanced configuration validation error', async () => {
+    advancedConfigButton.click();
+    await browserProxy.whenCalled('validateConfig');
+    flush();
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
+    assertTrue(!!advancedConfigDialog);
+
+    // Cause a validation error.
+    browserProxy.validateConfigResult = {
+      error: KerberosErrorType.BAD_CONFIG,
+      errorInfo:
+          {code: KerberosConfigErrorCode.KEY_NOT_SUPPORTED, lineIndex: 0},
+    };
+
+    // Clicking the action button (aka 'Save') validates the config.
+    advancedConfigDialog.querySelector('.action-button').click();
+
+    await browserProxy.whenCalled('validateConfig');
+
+    // Wait for dialog to process the 'validateConfig' result (sets error
+    // message etc.).
+    await flushTasks();
+
+    // Is some error text set?
+    const configError =
+        advancedConfigDialog.querySelector('#config-error-message');
+    assertTrue(!!configError);
+    assertNotEquals(0, configError.innerText.length);
+
+    // Is something selected?
+    const configElement = advancedConfigDialog.querySelector('#config');
+    const textArea = configElement.$.input;
+    assertEquals(0, textArea.selectionStart);
+    assertNotEquals(0, textArea.selectionEnd);
+
+    // Is the config dialog still open?
+    assertTrue(advancedConfigDialog.open);
+    assertTrue(addDialog.hidden);
+
+    // Was the config not accepted?
+    advancedConfigDialog.querySelector('.cancel-button').click();
+    flush();
+    assertConfig(loadTimeData.getString('defaultKerberosConfig'));
+  });
+
+  test('Validate configuration on advanced click', async () => {
+    // Cause a validation error.
+    browserProxy.validateConfigResult = {
+      error: KerberosErrorType.BAD_CONFIG,
+      errorInfo:
+          {code: KerberosConfigErrorCode.KEY_NOT_SUPPORTED, lineIndex: 0},
+    };
+
+    // Validating happens on "Advanced" click.
+    advancedConfigButton.click();
+    await browserProxy.whenCalled('validateConfig');
+
+    // Wait for dialog to process the 'validateConfig' result (sets error
+    // message etc.).
+    await flushTasks();
+
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
+    assertTrue(!!advancedConfigDialog);
+
+    // Is some error text set?
+    const configError =
+        advancedConfigDialog.querySelector('#config-error-message');
+    assertTrue(!!configError);
+    assertNotEquals(0, configError.innerText.length);
+
+    // Is something selected?
+    const configElement = advancedConfigDialog.querySelector('#config');
+    const textArea = configElement.$.input;
+    assertEquals(0, textArea.selectionStart);
+    assertNotEquals(0, textArea.selectionEnd);
+  });
+
+  test('Domain autocomplete enabled', function() {
+    loadTimeData.overrideValues({kerberosDomainAutocomplete: 'domain.com'});
+    createDialog(null);
+
+    // '@' should be automatically added to the policy value.
+    assertEquals(
+        '@domain.com',
+        dialog.shadowRoot.querySelector('#kerberosDomain').innerText);
+  });
+
+  test('Domain autocomplete enabled override', function() {
+    loadTimeData.overrideValues({kerberosDomainAutocomplete: 'domain.com'});
+    assertTrue(
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].principalName &&
+        TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST].principalName.indexOf(
+            '@') !== -1);
+    createDialog(TEST_KERBEROS_ACCOUNTS[AccountIndex.FIRST]);
+
+    // If inserted principal contains '@', nothing should be shown.
+    assertEquals(
+        '', dialog.shadowRoot.querySelector('#kerberosDomain').innerText);
+  });
+
+  test('Domain autocomplete disabled', function() {
+    assertEquals('', loadTimeData.getString('kerberosDomainAutocomplete'));
+    assertEquals(
+        '', dialog.shadowRoot.querySelector('#kerberosDomain').innerText);
+  });
+
+  // Testing how `addAccount` error types are handled by the UI:
+
+  // KerberosErrorType.PARSE_PRINCIPAL_FAILED spawns a username error.
+  test('Add account error - parse principal failed', async () => {
+    await checkAddAccountError(
+        KerberosErrorType.PARSE_PRINCIPAL_FAILED, username.$.error);
+  });
+
+  // KerberosErrorType.BAD_PRINCIPAL spawns a username error.
+  test('Add account error - bad principal', async () => {
+    await checkAddAccountError(
+        KerberosErrorType.BAD_PRINCIPAL, username.$.error);
+  });
+
+  // KerberosErrorType.DUPLICATE_PRINCIPAL_NAME spawns a username error.
+  test('Add account error - duplicate principal name', async () => {
+    await checkAddAccountError(
+        KerberosErrorType.DUPLICATE_PRINCIPAL_NAME, username.$.error);
+  });
+
+  // KerberosErrorType.CONTACTING_KDC_FAILED spawns a username error.
+  test('Add account error - contacting KDC failed', async () => {
+    await checkAddAccountError(
+        KerberosErrorType.CONTACTING_KDC_FAILED, username.$.error);
+  });
+
+  // KerberosErrorType.BAD_PASSWORD spawns a password error.
+  test('Add account error - bad password', async () => {
+    await checkAddAccountError(
+        KerberosErrorType.BAD_PASSWORD, password.$.error);
+  });
+
+  // KerberosErrorType.PASSWORD_EXPIRED spawns a password error.
+  test('Add account error - password expired', async () => {
+    await checkAddAccountError(
+        KerberosErrorType.PASSWORD_EXPIRED, password.$.error);
+  });
+
+  // KerberosErrorType.NETWORK_PROBLEM spawns a general error.
+  test('Add account error - network problem', async () => {
+    await checkAddAccountError(KerberosErrorType.NETWORK_PROBLEM, generalError);
+  });
+
+  // KerberosErrorType.KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE spawns a general
+  // error.
+  test('Add account error - KDC does not support encryption type', async () => {
+    await checkAddAccountError(
+        KerberosErrorType.KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE, generalError);
+  });
+
+  // KerberosErrorType.UNKNOWN spawns a general error.
+  test('Add account error - unknown', async () => {
+    await checkAddAccountError(KerberosErrorType.UNKNOWN, generalError);
+  });
+
+  // KerberosErrorType.BAD_CONFIG spawns a general error.
+  test('Add account error - bad config', async () => {
+    await checkAddAccountError(KerberosErrorType.BAD_CONFIG, generalError);
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/kerberos_page/test_kerberos_accounts_browser_proxy.ts b/chrome/test/data/webui/settings/chromeos/kerberos_page/test_kerberos_accounts_browser_proxy.ts
index 2fd8925..8353512 100644
--- a/chrome/test/data/webui/settings/chromeos/kerberos_page/test_kerberos_accounts_browser_proxy.ts
+++ b/chrome/test/data/webui/settings/chromeos/kerberos_page/test_kerberos_accounts_browser_proxy.ts
@@ -39,10 +39,18 @@
   },
 ];
 
+// Account indices (to help readability).
+export const AccountIndex = {
+  FIRST: 0,
+  SECOND: 1,
+  THIRD: 2,
+};
+
 export class TestKerberosAccountsBrowserProxy extends TestBrowserProxy
     implements KerberosAccountsBrowserProxy {
   addAccountError: KerberosErrorType;
   validateConfigResult: ValidateKerberosConfigResult;
+
   constructor() {
     super([
       'getAccounts',
diff --git a/chrome/test/data/webui/settings/chromeos/os_a11y_page/keyboard_and_text_input_page_test.ts b/chrome/test/data/webui/settings/chromeos/os_a11y_page/keyboard_and_text_input_page_test.ts
index b40846e1..de922041 100644
--- a/chrome/test/data/webui/settings/chromeos/os_a11y_page/keyboard_and_text_input_page_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/os_a11y_page/keyboard_and_text_input_page_test.ts
@@ -244,22 +244,26 @@
     {
       id: 'stickyKeysToggle',
       prefKey: 'settings.a11y.sticky_keys_enabled',
+      cvoxTooltipId: 'stickyKeysDisabledTooltip',
     },
     {
       id: 'focusHighlightToggle',
       prefKey: 'settings.a11y.focus_highlight',
+      cvoxTooltipId: 'focusHighlightDisabledTooltip',
     },
     {
       id: 'caretHighlightToggle',
       prefKey: 'settings.a11y.caret_highlight',
+      cvoxTooltipId: '',
     },
     {
       id: 'caretBrowsingToggle',
       prefKey: 'settings.a11y.caretbrowsing.enabled',
+      cvoxTooltipId: '',
     },
   ];
 
-  settingsToggleButtons.forEach(({id, prefKey}) => {
+  settingsToggleButtons.forEach(({id, prefKey, cvoxTooltipId}) => {
     test(`Accessibility toggle button syncs to prefs: ${id}`, async () => {
       await initPage();
       // Find the toggle and ensure that it's:
@@ -279,6 +283,27 @@
       assertTrue(toggle.checked);
       pref = page.getPref(prefKey);
       assertTrue(pref.value);
+
+      if (cvoxTooltipId === '') {
+        return;
+      }
+
+      const disabledTooltipIcon =
+          page.shadowRoot!.querySelector(`#${cvoxTooltipId}`);
+      assert(disabledTooltipIcon);
+      assertFalse(isVisible(disabledTooltipIcon));
+
+      // Turn on ChromeVox.
+      page.setPrefValue('settings.accessibility', true);
+      assertTrue(toggle.disabled);
+      assertTrue(isVisible(disabledTooltipIcon));
+      assertFalse(toggle.checked);
+
+      // Turn off ChromeVox again.
+      page.setPrefValue('settings.accessibility', false);
+      assertFalse(toggle.disabled);
+      assertFalse(isVisible(disabledTooltipIcon));
+      assertTrue(toggle.checked);
     });
   });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/os_apps_page/app_management_page/app_detail_view_test.ts b/chrome/test/data/webui/settings/chromeos/os_apps_page/app_management_page/app_detail_view_test.ts
new file mode 100644
index 0000000..335e3c1
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/os_apps_page/app_management_page/app_detail_view_test.ts
@@ -0,0 +1,61 @@
+// Copyright 2021 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://os-settings/lazy_load.js';
+
+import {AppManagementAppDetailViewElement} from 'chrome://os-settings/lazy_load.js';
+import {AppManagementStore, updateSelectedAppId} from 'chrome://os-settings/os_settings.js';
+import {App, AppType} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js';
+import {assertEquals, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js';
+
+import {FakePageHandler} from '../../app_management/fake_page_handler.js';
+import {replaceBody, replaceStore, setupFakeHandler} from '../../app_management/test_util.js';
+
+suite('<app-management-app-detail-view>', () => {
+  let appDetailView: AppManagementAppDetailViewElement;
+  let fakeHandler: FakePageHandler;
+  let arcApp: App;
+
+  setup(async () => {
+    fakeHandler = setupFakeHandler();
+    replaceStore();
+
+    // Create an ARC app.
+    const arcOptions = {type: AppType.kArc};
+
+    // Add an app, and make it the currently selected app.
+    arcApp = await fakeHandler.addApp('app1_id', arcOptions);
+    AppManagementStore.getInstance().dispatch(updateSelectedAppId(arcApp.id));
+
+    appDetailView = document.createElement('app-management-app-detail-view');
+
+    replaceBody(appDetailView);
+    await fakeHandler.flushPipesForTesting();
+  });
+
+  test('Change selected app', async () => {
+    assertEquals(
+        AppManagementStore.getInstance().data.selectedAppId,
+        appDetailView.get('app_').id);
+    assertEquals(arcApp.id, appDetailView.get('app_').id);
+    assertTrue(!!appDetailView.shadowRoot!.querySelector(
+        'app-management-arc-detail-view'));
+    assertNull(appDetailView.shadowRoot!.querySelector(
+        'app-management-pwa-detail-view'));
+    const pwaOptions = {type: AppType.kWeb};
+    // Add an second pwa app, and make it the currently selected app.
+    const pwaApp = await fakeHandler.addApp('app2_id', pwaOptions);
+    AppManagementStore.getInstance().dispatch(updateSelectedAppId(pwaApp.id));
+    await fakeHandler.flushPipesForTesting();
+
+    assertEquals(
+        AppManagementStore.getInstance().data.selectedAppId,
+        appDetailView.get('app_').id);
+    assertEquals(pwaApp.id, appDetailView.get('app_').id);
+    assertNull(appDetailView.shadowRoot!.querySelector(
+        'app-management-arc-detail-view'));
+    assertTrue(!!appDetailView.shadowRoot!.querySelector(
+        'app-management-pwa-detail-view'));
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
index 2c70e01..475dc77e 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -209,7 +209,6 @@
  ['AppsPage', 'apps_page_test.js'],
  ['AppNotificationsSubpage', 'app_notifications_subpage_tests.js'],
  ['AppManagementAppDetailsItem', 'app_management/app_details_item_test.js'],
- ['AppManagementAppDetailView', 'app_management/app_detail_view_test.js'],
  ['AppManagementAppItem', 'app_management/app_item_test.js'],
  ['AppManagementArcDetailView', 'app_management/arc_detail_view_test.js'],
  [
@@ -384,6 +383,10 @@
    'kerberos_page/kerberos_accounts_subpage_test.js',
  ],
  [
+   'KerberosPageKerberosAddAccountDialog',
+   'kerberos_page/kerberos_add_account_dialog_test.js',
+ ],
+ [
    'KeyboardShortcutBanner',
    'keyboard_shortcut_banner/keyboard_shortcut_banner_test.js'
  ],
@@ -502,6 +505,10 @@
    'OsA11yPageTtsVoiceSubpage',
    'os_a11y_page/tts_voice_subpage_test.js',
  ],
+ [
+   'OsAppsPageAppManagementPageAppDetailView',
+   'os_apps_page/app_management_page/app_detail_view_test.js'
+ ],
  ['OsBluetoothPage', 'os_bluetooth_page/os_bluetooth_page_tests.js'],
  [
    'OsBluetoothPageOsBluetoothChangeDeviceNameDialog',
diff --git a/chrome/test/data/webui/settings/performance_page_test.ts b/chrome/test/data/webui/settings/performance_page_test.ts
index 813087a..ce95ad8 100644
--- a/chrome/test/data/webui/settings/performance_page_test.ts
+++ b/chrome/test/data/webui/settings/performance_page_test.ts
@@ -385,9 +385,9 @@
       dialog: TabDiscardExceptionAddDialogElement|
       TabDiscardExceptionEditDialogElement,
       input: string) {
-    const inputEvent = eventToPromise('input', dialog.$.input);
-    dialog.$.input.value = input;
-    dialog.$.input.dispatchEvent(new CustomEvent('input'));
+    const inputEvent = eventToPromise('input', dialog.$.input.$.input);
+    dialog.$.input.$.input.value = input;
+    dialog.$.input.$.input.dispatchEvent(new CustomEvent('input'));
     await inputEvent;
     dialog.$.actionButton.click();
     await performanceBrowserProxy.whenCalled('validateTabDiscardExceptionRule');
@@ -404,7 +404,7 @@
     addDialog = getAddDialog();
     assertTrue(!!addDialog);
     assertTrue(addDialog.$.dialog.open);
-    assertEquals('', addDialog.$.input.value);
+    assertEquals('', addDialog.$.input.$.input.value);
     await inputDialog(addDialog, 'bar');
     assertExceptionListEquals(['foo', 'bar']);
   });
@@ -422,7 +422,7 @@
     editDialog = getEditDialog();
     assertTrue(!!editDialog);
     assertTrue(editDialog.$.dialog.open);
-    assertEquals(entry.entry.site, editDialog.$.input.value);
+    assertEquals(entry.entry.site, editDialog.$.input.$.input.value);
     await inputDialog(editDialog, 'baz');
     assertExceptionListEquals(['foo', 'baz']);
   });
@@ -435,7 +435,7 @@
 
     const dialog = getAddDialog();
     assertTrue(!!dialog);
-    assertEquals('', dialog.$.input.value);
+    assertEquals('', dialog.$.input.$.input.value);
   });
 
   test('testTabDiscardExceptionsListOverflow', async function() {
@@ -477,7 +477,7 @@
     flush();
     const editDialog = getEditDialog();
     assertTrue(!!editDialog);
-    assertEquals(entry.entry.site, editDialog.$.input.value);
+    assertEquals(entry.entry.site, editDialog.$.input.$.input.value);
     await inputDialog(editDialog, 'foo');
     assertExceptionListEquals([...entries.slice(0, -1), 'foo']);
 
diff --git a/chrome/test/data/webui/settings/tab_discard_exception_dialog_test.ts b/chrome/test/data/webui/settings/tab_discard_exception_dialog_test.ts
index e2087a8031..a506b42e 100644
--- a/chrome/test/data/webui/settings/tab_discard_exception_dialog_test.ts
+++ b/chrome/test/data/webui/settings/tab_discard_exception_dialog_test.ts
@@ -55,15 +55,15 @@
 
   function setupEditDialog() {
     dialog = document.createElement('tab-discard-exception-edit-dialog');
-    dialog.setRuleToEditForTesting(EXISTING_RULE);
     setupDialog();
+    dialog.setRuleToEditForTesting(EXISTING_RULE);
   }
 
   async function assertUserInputValidated(rule: string) {
     performanceBrowserProxy.reset();
     const trimmedRule = rule.trim();
-    dialog.$.input.value = rule;
-    dialog.$.input.dispatchEvent(
+    dialog.$.input.$.input.value = rule;
+    dialog.$.input.$.input.dispatchEvent(
         new CustomEvent('input', {bubbles: true, composed: true}));
     if (trimmedRule &&
         trimmedRule.length <= MAX_TAB_DISCARD_EXCEPTION_RULE_LENGTH) {
@@ -76,7 +76,7 @@
   async function testValidation() {
     await assertUserInputValidated('   ');
     assertFalse(
-        dialog.$.input.invalid,
+        dialog.$.input.$.input.invalid,
         'error mesasge should be hidden on empty input');
     assertTrue(
         dialog.$.actionButton.disabled,
@@ -85,14 +85,15 @@
     await assertUserInputValidated(
         'a'.repeat(MAX_TAB_DISCARD_EXCEPTION_RULE_LENGTH + 1));
     assertTrue(
-        dialog.$.input.invalid, 'error mesasge should be shown on long input');
+        dialog.$.input.$.input.invalid,
+        'error mesasge should be shown on long input');
     assertTrue(
         dialog.$.actionButton.disabled,
         'submit button should be disabled on long input');
 
     await assertUserInputValidated(VALID_RULE);
     assertFalse(
-        dialog.$.input.invalid,
+        dialog.$.input.$.input.invalid,
         'error mesasge should be hidden on valid input');
     assertFalse(
         dialog.$.actionButton.disabled,
@@ -101,7 +102,7 @@
     performanceBrowserProxy.setValidationResult(false);
     await assertUserInputValidated(INVALID_RULE);
     assertTrue(
-        dialog.$.input.invalid,
+        dialog.$.input.$.input.invalid,
         'error mesasge should be shown on invalid input');
     assertTrue(
         dialog.$.actionButton.disabled,
@@ -112,7 +113,8 @@
     setupAddDialog();
     assertTrue(dialog.$.dialog.open, 'dialog should be open initially');
     assertFalse(
-        dialog.$.input.invalid, 'error mesasge should be hidden initially');
+        dialog.$.input.$.input.invalid,
+        'error mesasge should be hidden initially');
     assertTrue(
         dialog.$.actionButton.disabled,
         'submit button should be disabled initially');
@@ -124,7 +126,8 @@
     setupEditDialog();
     assertTrue(dialog.$.dialog.open, 'dialog should be open initially');
     assertFalse(
-        dialog.$.input.invalid, 'error mesasge should be hidden initially');
+        dialog.$.input.$.input.invalid,
+        'error mesasge should be hidden initially');
     assertFalse(
         dialog.$.actionButton.disabled,
         'submit button should be enabled initially');
@@ -154,11 +157,8 @@
     await assertCancel();
   });
 
-  async function assertSubmit(
-      expectedRules: string[], validationResult = true) {
-    performanceBrowserProxy.setValidationResult(validationResult);
+  async function assertSubmit(expectedRules: string[]) {
     dialog.$.actionButton.click();
-    await performanceBrowserProxy.whenCalled('validateTabDiscardExceptionRule');
     await flushTasks();
 
     assertFalse(
@@ -182,13 +182,6 @@
     await assertSubmit([EXISTING_RULE]);
   });
 
-  test('testTabDiscardExceptionsAddDialogSubmitInvalid', async function() {
-    setupAddDialog();
-    await assertUserInputValidated(INVALID_RULE);
-    dialog.$.actionButton.disabled = false;
-    await assertSubmit([EXISTING_RULE], false);
-  });
-
   test('testTabDiscardExceptionsEditDialogSubmit', async function() {
     setupEditDialog();
     await assertUserInputValidated(VALID_RULE);
@@ -205,11 +198,4 @@
     await assertUserInputValidated(VALID_RULE);
     await assertSubmit([VALID_RULE]);
   });
-
-  test('testTabDiscardExceptionsEditDialogSubmitInvalid', async function() {
-    setupEditDialog();
-    await assertUserInputValidated(INVALID_RULE);
-    dialog.$.actionButton.disabled = false;
-    await assertSubmit([EXISTING_RULE], false);
-  });
 });
diff --git a/chrome/test/data/webui/side_panel/reading_list/reading_list_app_test.ts b/chrome/test/data/webui/side_panel/reading_list/reading_list_app_test.ts
index 59a28b3..21a38f6 100644
--- a/chrome/test/data/webui/side_panel/reading_list/reading_list_app_test.ts
+++ b/chrome/test/data/webui/side_panel/reading_list/reading_list_app_test.ts
@@ -211,24 +211,23 @@
       'https://www.bing.com',
       'https://www.yahoo.com',
     ];
-    const selector = readingListApp.shadowRoot!.querySelector('iron-selector')!;
 
     // Select first item.
-    selector.selected =
+    readingListApp.selected =
         readingListApp.shadowRoot!.querySelector(
                                       'reading-list-item')!.dataset['url']!;
 
-    keyDownOn(selector, 0, [], 'ArrowUp');
-    assertEquals(urls[3], selector.selected);
+    keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowUp');
+    assertEquals(urls[3], readingListApp.selected);
 
-    keyDownOn(selector, 0, [], 'ArrowDown');
-    assertEquals(urls[0], selector.selected);
+    keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowDown');
+    assertEquals(urls[0], readingListApp.selected);
 
-    keyDownOn(selector, 0, [], 'ArrowDown');
-    assertEquals(urls[1], selector.selected);
+    keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowDown');
+    assertEquals(urls[1], readingListApp.selected);
 
-    keyDownOn(selector, 0, [], 'ArrowUp');
-    assertEquals(urls[0], selector.selected);
+    keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowUp');
+    assertEquals(urls[0], readingListApp.selected);
   });
 
   test(
diff --git a/chrome/test/fuzzing/kombucha_in_process_fuzzer.cc b/chrome/test/fuzzing/kombucha_in_process_fuzzer.cc
index cdde0590..2d108c35 100644
--- a/chrome/test/fuzzing/kombucha_in_process_fuzzer.cc
+++ b/chrome/test/fuzzing/kombucha_in_process_fuzzer.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/functional/bind.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/browser_element_identifiers.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chrome/test/fuzzing/in_process_fuzzer.h"
@@ -26,10 +28,11 @@
   void SetUpOnMainThread() override;
   int Fuzz(const uint8_t* data, size_t size) override;
   static std::unique_ptr<net::test_server::HttpResponse> HandleHTTPRequest(
-      std::string response_body,
+      base::WeakPtr<KombuchaInProcessFuzzer> fuzzer_weak,
       const net::test_server::HttpRequest& request);
 
   std::string current_fuzz_case_;
+  base::WeakPtrFactory<KombuchaInProcessFuzzer> weak_ptr_factory_{this};
 };
 
 REGISTER_IN_PROCESS_FUZZER(KombuchaInProcessFuzzer)
@@ -38,18 +41,35 @@
   InteractiveBrowserTestT::SetUpOnMainThread();
   host_resolver()->AddRule("*", "127.0.0.1");
   embedded_test_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
-  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
-      &KombuchaInProcessFuzzer::HandleHTTPRequest, current_fuzz_case_));
+  embedded_test_server()->RegisterRequestHandler(
+      base::BindRepeating(&KombuchaInProcessFuzzer::HandleHTTPRequest,
+                          weak_ptr_factory_.GetWeakPtr()));
   ASSERT_TRUE(embedded_test_server()->Start());
 }
 
 std::unique_ptr<net::test_server::HttpResponse>
 KombuchaInProcessFuzzer::HandleHTTPRequest(
-    std::string response_body,
+    base::WeakPtr<KombuchaInProcessFuzzer> fuzzer_weak,
     const net::test_server::HttpRequest& request) {
   std::unique_ptr<net::test_server::BasicHttpResponse> response;
   response = std::make_unique<net::test_server::BasicHttpResponse>();
   response->set_content_type("text/html");
+  std::string response_body = "";
+  // We are running on the embedded test server's thread. We want to
+  // ask the fuzzer thread for the latest HTML payload, but there's a
+  // risk of UaF if it's being destroyed. We use a weak pointer, but
+  // we have to dereference that on the originating thread.
+  base::RunLoop run_loop;
+  base::RepeatingCallback<void()> get_payload_lambda =
+      base::BindLambdaForTesting([&]() {
+        KombuchaInProcessFuzzer* fuzzer = fuzzer_weak.get();
+        if (fuzzer) {
+          response_body = fuzzer->current_fuzz_case_;
+        }
+        run_loop.Quit();
+      });
+  content::GetUIThreadTaskRunner()->PostTask(FROM_HERE, get_payload_lambda);
+  run_loop.Run();
   response->set_content(response_body);
   response->set_code(net::HTTP_OK);
   return response;
diff --git a/chrome/test/interaction/interaction_test_util_browser.cc b/chrome/test/interaction/interaction_test_util_browser.cc
index d736baa..b39d168 100644
--- a/chrome/test/interaction/interaction_test_util_browser.cc
+++ b/chrome/test/interaction/interaction_test_util_browser.cc
@@ -21,6 +21,7 @@
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/interaction/tracked_element_webcontents.h"
 #include "chrome/test/interaction/webcontents_interaction_test_util.h"
+#include "content/public/common/content_switches.h"
 #include "ui/base/interaction/element_tracker.h"
 #include "ui/base/interaction/interaction_test_util.h"
 #include "ui/base/test/ui_controls.h"
@@ -244,7 +245,7 @@
   // line, which is checked by TestBrowserUi before attempting any screen
   // capture; otherwise screenshotting is a silent no-op.
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-          "browser-ui-tests-verify-pixels")) {
+          switches::kVerifyPixels)) {
     LOG(WARNING)
         << "Cannot take screenshot: pixel test command line not set. This is "
            "normal for non-pixel-test jobs such as vanilla browser_tests.";
diff --git a/chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.cc b/chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.cc
index 2f55418e..c40a40b1e 100644
--- a/chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.cc
+++ b/chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.cc
@@ -36,6 +36,7 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_host_resolver.h"
 #include "net/dns/mock_host_resolver.h"
@@ -112,7 +113,7 @@
   // This command removes the verify pixels switch so that our TestDialog code
   // does not automatically take pixel screenshots.
   base::CommandLine::ForCurrentProcess()->RemoveSwitch(
-      "browser-ui-tests-verify-pixels");
+      ::switches::kVerifyPixels);
 }
 
 void AccessCodeCastIntegrationBrowserTest::SetUpInProcessBrowserTestFixture() {
diff --git a/chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc b/chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc
index 5e09f04..4bf254f 100644
--- a/chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc
+++ b/chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc
@@ -42,9 +42,6 @@
 // by Skia Gold. If any pixels differ, the test will fail and output a link
 // for the author to triage the new image.
 IN_PROC_BROWSER_TEST_F(SkiaGoldDemoPixelTest, TestOmnibox) {
-  // Always disable animation for stability.
-  ui::ScopedAnimationDurationScaleMode disable_animation(
-      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
   GURL url("chrome://bookmarks");
   ASSERT_TRUE(AddTabAtIndex(0, url, ui::PageTransition::PAGE_TRANSITION_FIRST));
   auto* const browser_view = static_cast<BrowserView*>(browser()->window());
diff --git a/chrome/updater/mac/BUILD.gn b/chrome/updater/mac/BUILD.gn
index 39c93a41..645783b 100644
--- a/chrome/updater/mac/BUILD.gn
+++ b/chrome/updater/mac/BUILD.gn
@@ -9,6 +9,7 @@
 import("//build/symlink.gni")
 import("//build/util/process_version.gni")
 import("//chrome/updater/branding.gni")
+import("//chrome/updater/mac/signing/signing_sources.gni")
 import("//chrome/updater/zip.gni")
 import("//chrome/version.gni")
 
@@ -605,25 +606,16 @@
     "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Info.plist",
     "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/launcher",
     "$root_build_dir/${updater_product_full_name}_test.app/Contents/PkgInfo",
-    "$root_build_dir/Updater Packaging/signing/signing.py",
-    "$root_build_dir/Updater Packaging/signing/config.py",
-    "$root_build_dir/Updater Packaging/signing/modification.py",
-    "$root_build_dir/Updater Packaging/signing/notarize.py",
-    "$root_build_dir/Updater Packaging/signing/pkg-dmg",
-    "$root_build_dir/Updater Packaging/signing/__init__.py",
-    "$root_build_dir/Updater Packaging/signing/driver.py",
-    "$root_build_dir/Updater Packaging/signing/model.py",
-    "$root_build_dir/Updater Packaging/signing/unbranded_config.py",
-    "$root_build_dir/Updater Packaging/signing/pipeline.py",
-    "$root_build_dir/Updater Packaging/signing/parts.py",
-    "$root_build_dir/Updater Packaging/signing/config_factory.py",
-    "$root_build_dir/Updater Packaging/signing/build_props_config.py",
-    "$root_build_dir/Updater Packaging/signing/commands.py",
     "$root_build_dir/Updater Packaging/sign_updater.py",
+    "$root_build_dir/Updater Packaging/signing/build_props_config.py",
+    "$root_build_dir/Updater Packaging/signing/pkg-dmg",
     "$root_build_dir/chrome/updater/.install",
     "$root_build_dir/UpdaterSetup",
     "$root_build_dir/qualification_app",
   ]
+  inputs += rebase_path(get_path_info(updater_signing_sources, "file"),
+                        "",
+                        "$root_build_dir/Updater Packaging/signing")
   deps = [
     ":updater_bundle",
     ":updater_bundle_test",
diff --git a/chrome/updater/mac/signing/BUILD.gn b/chrome/updater/mac/signing/BUILD.gn
index 5402a007..42370f95 100644
--- a/chrome/updater/mac/signing/BUILD.gn
+++ b/chrome/updater/mac/signing/BUILD.gn
@@ -4,9 +4,9 @@
 
 import("//build/config/features.gni")
 import("//build/util/branding.gni")
-import("//chrome/installer/mac/mac_signing_sources.gni")
 import("//chrome/process_version_rc_template.gni")
 import("//chrome/updater/branding.gni")
+import("//chrome/updater/mac/signing/signing_sources.gni")
 import("//chrome/version.gni")
 
 group("signing") {
@@ -51,23 +51,7 @@
 
   public_deps = [ ":sign_config" ]
 
-  adjusted_mac_signing_sources = mac_signing_sources - [
-                                   "signing/chromium_config.py",
-                                   "signing/config_factory.py",
-                                   "signing/parts.py",
-                                   "signing/pipeline.py",
-                                 ]
-
-  sources =
-      rebase_path(adjusted_mac_signing_sources, ".", "//chrome/installer/mac/")
-
-  sources += [
-    "//chrome/installer/mac/pkg-dmg",
-    "config_factory.py",
-    "parts.py",
-    "pipeline.py",
-    "unbranded_config.py",
-  ]
+  sources = updater_signing_sources + [ "//chrome/installer/mac/pkg-dmg" ]
 
   outputs = [ "$_packaging_dir/signing/{{source_file_part}}" ]
 }
diff --git a/chrome/updater/mac/signing/config_factory.py b/chrome/updater/mac/signing/config_factory.py
index c14b293..6d7ffc1d 100644
--- a/chrome/updater/mac/signing/config_factory.py
+++ b/chrome/updater/mac/signing/config_factory.py
@@ -5,5 +5,5 @@
 
 def get_class():
     """Returns the subclass of |model.CodeSignConfig| to use."""
-    from .unbranded_config import UnbrandedCodeSignConfig
+    from signing.unbranded_config import UnbrandedCodeSignConfig
     return UnbrandedCodeSignConfig
diff --git a/chrome/updater/mac/signing/parts.py b/chrome/updater/mac/signing/parts.py
index 501b31f..22d8ea7 100644
--- a/chrome/updater/mac/signing/parts.py
+++ b/chrome/updater/mac/signing/parts.py
@@ -8,8 +8,8 @@
 
 import os.path
 
-from . import commands, signing
-from .model import CodeSignOptions, CodeSignedProduct, VerifyOptions
+from signing import commands, signing
+from signing.model import CodeSignOptions, CodeSignedProduct, VerifyOptions
 
 
 def get_parts(config):
diff --git a/chrome/updater/mac/signing/pipeline.py b/chrome/updater/mac/signing/pipeline.py
index 6d3b842..d301b6fa 100644
--- a/chrome/updater/mac/signing/pipeline.py
+++ b/chrome/updater/mac/signing/pipeline.py
@@ -10,7 +10,7 @@
 
 import os.path
 
-from . import commands, model, notarize, parts, signing
+from signing import commands, model, notarize, parts, signing
 
 
 def _sign_app(paths, config, dest_dir):
diff --git a/chrome/updater/mac/signing/signing_sources.gni b/chrome/updater/mac/signing/signing_sources.gni
new file mode 100644
index 0000000..0476f21
--- /dev/null
+++ b/chrome/updater/mac/signing/signing_sources.gni
@@ -0,0 +1,27 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//chrome/installer/mac/mac_signing_sources.gni")
+
+# Remove from `mac_signing_sources` any files that are overridden by the updater
+# signing script. Rebase those paths which are relative to chrome/installer/mac,
+# and then add the updater-specific signing sources.
+#
+# NOTE: build_props_config.py is generated by :sign_config and is not listed
+# here.
+updater_signing_sources = rebase_path(mac_signing_sources - [
+                                            "signing/chromium_config.py",
+                                            "signing/config_factory.py",
+                                            "signing/parts.py",
+                                            "signing/pipeline.py",
+                                          ],
+                                      ".",
+                                      "//chrome/installer/mac/") +
+                          rebase_path([
+                                        "config_factory.py",
+                                        "parts.py",
+                                        "pipeline.py",
+                                        "unbranded_config.py",
+                                      ],
+                                      ".")
diff --git a/chrome/updater/mac/signing/unbranded_config.py b/chrome/updater/mac/signing/unbranded_config.py
index f0505a27..3892b4f 100644
--- a/chrome/updater/mac/signing/unbranded_config.py
+++ b/chrome/updater/mac/signing/unbranded_config.py
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-from .build_props_config import BuildPropsCodeSignConfig
+from signing.build_props_config import BuildPropsCodeSignConfig
 
 
 class UnbrandedCodeSignConfig(BuildPropsCodeSignConfig):
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn
index e44e868..6d1927f 100644
--- a/chromecast/android/BUILD.gn
+++ b/chromecast/android/BUILD.gn
@@ -57,7 +57,7 @@
 
   deps = [
     ":common_apk_deps",
-    "//chromecast:cast_shell_lib",
+    "//chromecast/cast_core:core_runtime_lib_simple",
   ]
 }
 
@@ -72,7 +72,7 @@
 
   deps = [
     ":common_apk_deps",
-    "//chromecast:cast_shell_lib_simple",
+    "//chromecast/cast_core:core_runtime_lib_simple",
     "//components/module_installer/android:native",
   ]
 }
diff --git a/chromecast/build/args/cast_shell_android.gn b/chromecast/build/args/cast_shell_android.gn
deleted file mode 100644
index 6347884..0000000
--- a/chromecast/build/args/cast_shell_android.gn
+++ /dev/null
@@ -1,12 +0,0 @@
-debuggable_apks = false
-enable_cast_receiver = true
-cast_streaming_enable_remoting = true
-ffmpeg_branding = "Chrome"
-is_cast_android = true
-is_clang = true
-is_component_build = false
-proprietary_codecs = true
-symbol_level = 0
-target_os = "android"
-use_goma = true
-use_message_port_core = true
diff --git a/chromecast/build/args/config/all.gni b/chromecast/build/args/config/all.gni
new file mode 100644
index 0000000..0af74813
--- /dev/null
+++ b/chromecast/build/args/config/all.gni
@@ -0,0 +1,12 @@
+# Args common to all Chromecast browser builds.
+enable_cast_receiver = true
+
+# Used with streaming application.
+cast_streaming_enable_remoting = true
+proprietary_codecs = true
+
+ffmpeg_branding = "Chrome"
+
+enable_arcore = false
+enable_vr = false
+enable_printing = false
diff --git a/chromecast/build/args/config/android.gni b/chromecast/build/args/config/android.gni
new file mode 100644
index 0000000..24d19c3
--- /dev/null
+++ b/chromecast/build/args/config/android.gni
@@ -0,0 +1,10 @@
+# Args common to ALL Android builds.
+is_cast_android = true
+is_clang = true
+is_component_build = false
+symbol_level = 1  # This is a workaround to facilitate APKs >4GB
+target_os = "android"
+
+enable_playready = false
+device_user_agent_suffix = "DeviceType/AndroidTV"
+use_chromecast_cdms = false
diff --git a/chromecast/build/args/config/archs/arm.gni b/chromecast/build/args/config/archs/arm.gni
new file mode 100644
index 0000000..cf5f19c
--- /dev/null
+++ b/chromecast/build/args/config/archs/arm.gni
@@ -0,0 +1,2 @@
+# Args common to ALL arm (32bit) builds.
+target_cpu = "arm"
diff --git a/chromecast/build/args/config/archs/arm64.gni b/chromecast/build/args/config/archs/arm64.gni
new file mode 100644
index 0000000..0f2e753
--- /dev/null
+++ b/chromecast/build/args/config/archs/arm64.gni
@@ -0,0 +1,2 @@
+# Args common to ALL arm (64bit) builds.
+target_cpu = "arm64"
diff --git a/chromecast/build/args/config/flavor/eng.gni b/chromecast/build/args/config/flavor/eng.gni
new file mode 100644
index 0000000..a790086
--- /dev/null
+++ b/chromecast/build/args/config/flavor/eng.gni
@@ -0,0 +1,4 @@
+# Args for ALL Eng builds.
+cast_is_debug = true
+dcheck_always_on = true
+is_debug = false
diff --git a/chromecast/build/args/config/flavor/release.gni b/chromecast/build/args/config/flavor/release.gni
new file mode 100644
index 0000000..3d8d3d4
--- /dev/null
+++ b/chromecast/build/args/config/flavor/release.gni
@@ -0,0 +1,4 @@
+# Args for all Release builds.
+cast_is_debug = false
+is_debug = false
+is_official_build = true
diff --git a/chromecast/build/args/product/atv_arm64_eng.gn b/chromecast/build/args/product/atv_arm64_eng.gn
new file mode 100644
index 0000000..867f182
--- /dev/null
+++ b/chromecast/build/args/product/atv_arm64_eng.gn
@@ -0,0 +1,4 @@
+import("//chromecast/build/args/config/all.gni")
+import("//chromecast/build/args/config/android.gni")
+import("//chromecast/build/args/config/archs/arm64.gni")
+import("//chromecast/build/args/config/flavor/eng.gni")
diff --git a/chromecast/build/args/product/atv_arm64_user.gn b/chromecast/build/args/product/atv_arm64_user.gn
new file mode 100644
index 0000000..3fbac2a8
--- /dev/null
+++ b/chromecast/build/args/product/atv_arm64_user.gn
@@ -0,0 +1,4 @@
+import("//chromecast/build/args/config/all.gni")
+import("//chromecast/build/args/config/android.gni")
+import("//chromecast/build/args/config/archs/arm64.gni")
+import("//chromecast/build/args/config/flavor/release.gni")
diff --git a/chromecast/build/args/product/atv_arm_eng.gn b/chromecast/build/args/product/atv_arm_eng.gn
new file mode 100644
index 0000000..1659b26
--- /dev/null
+++ b/chromecast/build/args/product/atv_arm_eng.gn
@@ -0,0 +1,4 @@
+import("//chromecast/build/args/config/all.gni")
+import("//chromecast/build/args/config/android.gni")
+import("//chromecast/build/args/config/archs/arm.gni")
+import("//chromecast/build/args/config/flavor/eng.gni")
diff --git a/chromecast/build/args/product/atv_arm_user.gn b/chromecast/build/args/product/atv_arm_user.gn
new file mode 100644
index 0000000..3259826
--- /dev/null
+++ b/chromecast/build/args/product/atv_arm_user.gn
@@ -0,0 +1,4 @@
+import("//chromecast/build/args/config/all.gni")
+import("//chromecast/build/args/config/android.gni")
+import("//chromecast/build/args/config/archs/arm.gni")
+import("//chromecast/build/args/config/flavor/release.gni")
diff --git a/chromeos/ash/components/BUILD.gn b/chromeos/ash/components/BUILD.gn
index c3a489ea..d87bfdb 100644
--- a/chromeos/ash/components/BUILD.gn
+++ b/chromeos/ash/components/BUILD.gn
@@ -26,7 +26,7 @@
     "//chromeos/ash/components/hid_detection:unit_tests",
     "//chromeos/ash/components/human_presence:unit_tests",
     "//chromeos/ash/components/install_attributes:unit_tests",
-    "//chromeos/ash/components/language/language_packs:unit_tests",
+    "//chromeos/ash/components/language_packs:unit_tests",
     "//chromeos/ash/components/local_search_service:unit_tests",
     "//chromeos/ash/components/local_search_service/public/mojom:unit_tests",
     "//chromeos/ash/components/login/auth:unit_tests",
diff --git a/chromeos/ash/components/dbus/hermes/README.md b/chromeos/ash/components/dbus/hermes/README.md
new file mode 100644
index 0000000..d4d26f2
--- /dev/null
+++ b/chromeos/ash/components/dbus/hermes/README.md
@@ -0,0 +1,38 @@
+# Hermes' D-Bus Client Library
+
+Hermes' D-Bus client library allows Chrome to make API calls to
+[Hermes](https://osscs.corp.google.com/chromium/chromium/src/+/main:chromeos/ash/components/network/README.md;l=64;drc=4a50d13fc73268ef4a27cf67dc1eff40ea6f997a),
+ChromeOS' eSIM configuration manager.
+
+This document describes the various D-Bus clients that utilize Hermes' D-Bus
+interfaces, the **Manager Client**, **EUICC Client**, and **Profile Client**.
+
+### Initialization and Shutdown
+
+The D-Bus clients are initialized in the order of Profile client, EUICC client,
+then Manager client when Ash D-Bus clients are initialized after
+[Chrome's early initialization](https://osscs.corp.google.com/chromium/chromium/src/+/refs/heads/main:chrome/app/chrome_main_delegate.cc;l=755;drc=90b428dcab63b652cc91107b81d2758270e92ac0).
+
+For extensions, the clients are initialized after the Shell Browser's
+[main message loop is created](https://osscs.corp.google.com/chromium/chromium/src/+/refs/heads/main:extensions/shell/browser/shell_browser_main_parts.cc;l=129;drc=90b428dcab63b652cc91107b81d2758270e92ac0).
+
+The clients are shutdown with the rest of the Ash D-Bus clients after Chrome
+[destroys its threads](https://osscs.corp.google.com/chromium/chromium/src/+/refs/heads/main:chrome/browser/ash/chrome_browser_main_parts_ash.cc;l=1706;drc=90b428dcab63b652cc91107b81d2758270e92ac0).
+
+### Constants
+
+Success and error codes, along with helpful utility functions related to these
+codes can be found in [hermes_response_status.h](https://osscs.corp.google.com/chromium/chromium/src/+/main:chromeos/ash/components/dbus/hermes/hermes_response_status.h;l=14;drc=07384a913575f611a42f063e7e273ac499af9ef1).
+
+There are also [several constants](https://osscs.corp.google.com/chromium/chromium/src/+/main:chromeos/ash/components/dbus/hermes/constants.h;l=10;drc=789bec586d89e87ccb30ba132a12da2dd99b42e3)
+which are shared between the D-Bus clients to implement a consistent timeout
+for D-Bus calls.
+
+### Hermes Manager Client
+TODO
+
+### Hermes EUICC Client
+TODO
+
+### Hermes Profile Client
+TODO
diff --git a/chromeos/ash/components/language/language_packs/DEPS b/chromeos/ash/components/language/language_packs/DEPS
deleted file mode 100644
index 6129fd5..0000000
--- a/chromeos/ash/components/language/language_packs/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+components/session_manager",
-]
diff --git a/chromeos/ash/components/language/language_packs/BUILD.gn b/chromeos/ash/components/language_packs/BUILD.gn
similarity index 95%
rename from chromeos/ash/components/language/language_packs/BUILD.gn
rename to chromeos/ash/components/language_packs/BUILD.gn
index 481b941..41770fe7 100644
--- a/chromeos/ash/components/language/language_packs/BUILD.gn
+++ b/chromeos/ash/components/language_packs/BUILD.gn
@@ -19,7 +19,7 @@
     "//base",
     "//chromeos/ash/components/dbus/dlcservice",
     "//chromeos/ash/components/dbus/dlcservice:dlcservice_proto",
-    "//chromeos/ash/components/language/public/mojom",
+    "//chromeos/ash/components/language_packs/public/mojom",
     "//components/language/core/common",
     "//components/session_manager:base",
     "//components/session_manager/core:core",
diff --git a/chromeos/ash/components/language/DEPS b/chromeos/ash/components/language_packs/DEPS
similarity index 75%
rename from chromeos/ash/components/language/DEPS
rename to chromeos/ash/components/language_packs/DEPS
index 903a1a2..b07e8bd 100644
--- a/chromeos/ash/components/language/DEPS
+++ b/chromeos/ash/components/language_packs/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+chromeos/ash/components/dbus/dlcservice",
   "+components/language/core/common",
+  "+components/session_manager",
 ]
diff --git a/chromeos/ash/components/language/DIR_METADATA b/chromeos/ash/components/language_packs/DIR_METADATA
similarity index 100%
rename from chromeos/ash/components/language/DIR_METADATA
rename to chromeos/ash/components/language_packs/DIR_METADATA
diff --git a/chromeos/ash/components/language/OWNERS b/chromeos/ash/components/language_packs/OWNERS
similarity index 100%
rename from chromeos/ash/components/language/OWNERS
rename to chromeos/ash/components/language_packs/OWNERS
diff --git a/chromeos/ash/components/language/language_packs/README.md b/chromeos/ash/components/language_packs/README.md
similarity index 100%
rename from chromeos/ash/components/language/language_packs/README.md
rename to chromeos/ash/components/language_packs/README.md
diff --git a/chromeos/ash/components/language/language_packs/language_pack_manager.cc b/chromeos/ash/components/language_packs/language_pack_manager.cc
similarity index 98%
rename from chromeos/ash/components/language/language_packs/language_pack_manager.cc
rename to chromeos/ash/components/language_packs/language_pack_manager.cc
index 671d7d0..50c1da0 100644
--- a/chromeos/ash/components/language/language_packs/language_pack_manager.cc
+++ b/chromeos/ash/components/language_packs/language_pack_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/ash/components/language/language_packs/language_pack_manager.h"
+#include "chromeos/ash/components/language_packs/language_pack_manager.h"
 
 #include "base/containers/contains.h"
 #include "base/containers/flat_map.h"
@@ -15,7 +15,7 @@
 #include "base/no_destructor.h"
 #include "chromeos/ash/components/dbus/dlcservice/dlcservice.pb.h"
 #include "chromeos/ash/components/dbus/dlcservice/dlcservice_client.h"
-#include "chromeos/ash/components/language/language_packs/language_packs_util.h"
+#include "chromeos/ash/components/language_packs/language_packs_util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cros_system_api/dbus/dlcservice/dbus-constants.h"
 
diff --git a/chromeos/ash/components/language/language_packs/language_pack_manager.h b/chromeos/ash/components/language_packs/language_pack_manager.h
similarity index 96%
rename from chromeos/ash/components/language/language_packs/language_pack_manager.h
rename to chromeos/ash/components/language_packs/language_pack_manager.h
index 6c8c67b..871f932 100644
--- a/chromeos/ash/components/language/language_packs/language_pack_manager.h
+++ b/chromeos/ash/components/language_packs/language_pack_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_
-#define CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_
+#define CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_
 
 #include <string>
 
@@ -217,4 +217,4 @@
 
 }  // namespace ash::language_packs
 
-#endif  // CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_
diff --git a/chromeos/ash/components/language/language_packs/language_pack_manager_unittest.cc b/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc
similarity index 99%
rename from chromeos/ash/components/language/language_packs/language_pack_manager_unittest.cc
rename to chromeos/ash/components/language_packs/language_pack_manager_unittest.cc
index 6862b1c..e6a50d27 100644
--- a/chromeos/ash/components/language/language_packs/language_pack_manager_unittest.cc
+++ b/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/ash/components/language/language_packs/language_pack_manager.h"
+#include "chromeos/ash/components/language_packs/language_pack_manager.h"
 
 #include "base/functional/bind.h"
 #include "base/logging.h"
diff --git a/chromeos/ash/components/language/language_packs/language_packs_impl.cc b/chromeos/ash/components/language_packs/language_packs_impl.cc
similarity index 98%
rename from chromeos/ash/components/language/language_packs/language_packs_impl.cc
rename to chromeos/ash/components/language_packs/language_packs_impl.cc
index 69fb240..5532cfa65 100644
--- a/chromeos/ash/components/language/language_packs/language_packs_impl.cc
+++ b/chromeos/ash/components/language_packs/language_packs_impl.cc
@@ -5,7 +5,7 @@
 #include <string>
 
 #include "base/metrics/histogram_functions.h"
-#include "chromeos/ash/components/language/language_packs/language_packs_impl.h"
+#include "chromeos/ash/components/language_packs/language_packs_impl.h"
 
 #include "base/no_destructor.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chromeos/ash/components/language/language_packs/language_packs_impl.h b/chromeos/ash/components/language_packs/language_packs_impl.h
similarity index 79%
rename from chromeos/ash/components/language/language_packs/language_packs_impl.h
rename to chromeos/ash/components/language_packs/language_packs_impl.h
index a71055b..4591c02 100644
--- a/chromeos/ash/components/language/language_packs/language_packs_impl.h
+++ b/chromeos/ash/components/language_packs/language_packs_impl.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACKS_IMPL_H_
-#define CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACKS_IMPL_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACKS_IMPL_H_
+#define CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACKS_IMPL_H_
 
 #include <string>
 
-#include "chromeos/ash/components/language/language_packs/language_pack_manager.h"
-#include "chromeos/ash/components/language/public/mojom/language_packs.mojom.h"
+#include "chromeos/ash/components/language_packs/language_pack_manager.h"
+#include "chromeos/ash/components/language_packs/public/mojom/language_packs.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 
@@ -47,4 +47,4 @@
 
 }  // namespace ash::language_packs
 
-#endif  // CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACKS_IMPL_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACKS_IMPL_H_
diff --git a/chromeos/ash/components/language/language_packs/language_packs_util.cc b/chromeos/ash/components/language_packs/language_packs_util.cc
similarity index 97%
rename from chromeos/ash/components/language/language_packs/language_packs_util.cc
rename to chromeos/ash/components/language_packs/language_packs_util.cc
index 84dbaa6..6994b2f1 100644
--- a/chromeos/ash/components/language/language_packs/language_packs_util.cc
+++ b/chromeos/ash/components/language_packs/language_packs_util.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/ash/components/language/language_packs/language_packs_util.h"
+#include "chromeos/ash/components/language_packs/language_packs_util.h"
 
 #include "base/logging.h"
 #include "base/strings/string_util.h"
diff --git a/chromeos/ash/components/language/language_packs/language_packs_util.h b/chromeos/ash/components/language_packs/language_packs_util.h
similarity index 82%
rename from chromeos/ash/components/language/language_packs/language_packs_util.h
rename to chromeos/ash/components/language_packs/language_packs_util.h
index af1589c..837d43d 100644
--- a/chromeos/ash/components/language/language_packs/language_packs_util.h
+++ b/chromeos/ash/components/language_packs/language_packs_util.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACKS_UTIL_H_
-#define CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACKS_UTIL_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACKS_UTIL_H_
+#define CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACKS_UTIL_H_
 
 #include <string>
 
 #include "chromeos/ash/components/dbus/dlcservice/dlcservice.pb.h"
-#include "chromeos/ash/components/language/language_packs/language_pack_manager.h"
+#include "chromeos/ash/components/language_packs/language_pack_manager.h"
 
 namespace ash::language_packs {
 
@@ -41,4 +41,4 @@
 
 }  // namespace ash::language_packs
 
-#endif  // CHROMEOS_ASH_COMPONENTS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACKS_UTIL_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_LANGUAGE_PACKS_LANGUAGE_PACKS_UTIL_H_
diff --git a/chromeos/ash/components/language/language_packs/language_packs_util_unittest.cc b/chromeos/ash/components/language_packs/language_packs_util_unittest.cc
similarity index 95%
rename from chromeos/ash/components/language/language_packs/language_packs_util_unittest.cc
rename to chromeos/ash/components/language_packs/language_packs_util_unittest.cc
index dc37302d..2fc1266 100644
--- a/chromeos/ash/components/language/language_packs/language_packs_util_unittest.cc
+++ b/chromeos/ash/components/language_packs/language_packs_util_unittest.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/ash/components/language/language_packs/language_packs_util.h"
+#include "chromeos/ash/components/language_packs/language_packs_util.h"
 
-#include "chromeos/ash/components/language/language_packs/language_pack_manager.h"
+#include "chromeos/ash/components/language_packs/language_pack_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/cros_system_api/dbus/dlcservice/dbus-constants.h"
 
diff --git a/chromeos/ash/components/language/language_packs/metrics_unittest.cc b/chromeos/ash/components/language_packs/metrics_unittest.cc
similarity index 100%
rename from chromeos/ash/components/language/language_packs/metrics_unittest.cc
rename to chromeos/ash/components/language_packs/metrics_unittest.cc
diff --git a/chromeos/ash/components/language/public/mojom/BUILD.gn b/chromeos/ash/components/language_packs/public/mojom/BUILD.gn
similarity index 100%
rename from chromeos/ash/components/language/public/mojom/BUILD.gn
rename to chromeos/ash/components/language_packs/public/mojom/BUILD.gn
diff --git a/chromeos/ash/components/language/public/mojom/OWNERS b/chromeos/ash/components/language_packs/public/mojom/OWNERS
similarity index 100%
rename from chromeos/ash/components/language/public/mojom/OWNERS
rename to chromeos/ash/components/language_packs/public/mojom/OWNERS
diff --git a/chromeos/ash/components/language/public/mojom/language_packs.mojom b/chromeos/ash/components/language_packs/public/mojom/language_packs.mojom
similarity index 100%
rename from chromeos/ash/components/language/public/mojom/language_packs.mojom
rename to chromeos/ash/components/language_packs/public/mojom/language_packs.mojom
diff --git a/chromeos/ash/components/memory/swap_configuration.cc b/chromeos/ash/components/memory/swap_configuration.cc
index b9e4ae4..59f11a47 100644
--- a/chromeos/ash/components/memory/swap_configuration.cc
+++ b/chromeos/ash/components/memory/swap_configuration.cc
@@ -8,32 +8,10 @@
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/metrics/field_trial_params.h"
-#include "chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.h"
 #include "chromeos/ash/components/dbus/resourced/resourced_client.h"
 
 namespace ash {
 
-BASE_FEATURE(kCrOSTuneMinFilelist,
-             "CrOSTuneMinFilelist",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-const base::FeatureParam<int> kCrOSMinFilelistMb{&kCrOSTuneMinFilelist,
-                                                 "CrOSMinFilelistMb", -1};
-
-BASE_FEATURE(kCrOSTuneRamVsSwapWeight,
-             "CrOSTuneRamVsSwapWeight",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-const base::FeatureParam<int> kCrOSRamVsSwapWeight{&kCrOSTuneRamVsSwapWeight,
-                                                   "CrOSRamVsSwapWeight", -1};
-
-BASE_FEATURE(kCrOSTuneExtraFree,
-             "CrOSTuneExtraFree",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-const base::FeatureParam<int> kCrOSExtraFreeMb{&kCrOSTuneExtraFree,
-                                               "CrOSExtraFreeMb", -1};
-
 // There are going to be 2 separate experiments for memory pressure signal, one
 // for ARC enabled users and one for ARC disabled users.
 BASE_FEATURE(kCrOSMemoryPressureSignalStudyNonArc,
@@ -106,80 +84,6 @@
 
 namespace {
 
-constexpr const char kMinFilelist[] = "min_filelist";
-constexpr const char kRamVsSwapWeight[] = "ram_vs_swap_weight";
-constexpr const char kExtraFree[] = "extra_free";
-
-void OnSwapParameterSet(std::string parameter,
-                        absl::optional<std::string> res) {
-  LOG_IF(ERROR, !res.has_value())
-      << "Setting swap paramter " << parameter << " failed.";
-  LOG_IF(ERROR, res.has_value() && !res.value().empty())
-      << "Setting swap parameter " << parameter
-      << " returned error: " << res.value();
-}
-
-void ConfigureMinFilelistIfEnabled() {
-  if (!base::FeatureList::IsEnabled(kCrOSTuneMinFilelist)) {
-    return;
-  }
-
-  DebugDaemonClient* debugd_client = DebugDaemonClient::Get();
-  CHECK(debugd_client);
-
-  int min_mb = kCrOSMinFilelistMb.Get();
-  if (min_mb < 0) {
-    LOG(ERROR) << "Min Filelist MB is enabled with an invalid value: "
-               << min_mb;
-    return;
-  }
-
-  VLOG(1) << "Setting min filelist to " << min_mb << "MB";
-  debugd_client->SetSwapParameter(
-      kMinFilelist, min_mb, base::BindOnce(&OnSwapParameterSet, kMinFilelist));
-}
-
-void ConfigureRamVsSwapWeightIfEnabled() {
-  if (!base::FeatureList::IsEnabled(kCrOSTuneRamVsSwapWeight))
-    return;
-
-  DebugDaemonClient* debugd_client = DebugDaemonClient::Get();
-  CHECK(debugd_client);
-
-  int swap_weight = kCrOSRamVsSwapWeight.Get();
-  if (swap_weight < 0) {
-    LOG(ERROR) << "Ram vs Swap weight must be greater than or equal to 0, "
-                  "invalid value: "
-               << swap_weight;
-    return;
-  }
-
-  VLOG(1) << "Setting ram vs swap weight to: " << swap_weight;
-  debugd_client->SetSwapParameter(
-      kRamVsSwapWeight, swap_weight,
-      base::BindOnce(&OnSwapParameterSet, kRamVsSwapWeight));
-}
-
-void ConfigureExtraFreeIfEnabled() {
-  if (!base::FeatureList::IsEnabled(kCrOSTuneExtraFree))
-    return;
-
-  DebugDaemonClient* debugd_client = DebugDaemonClient::Get();
-  CHECK(debugd_client);
-
-  int extra_free = kCrOSExtraFreeMb.Get();
-  if (extra_free < 0) {
-    LOG(ERROR)
-        << "Extra free must be greater than or equal to 0, invalid value: "
-        << extra_free;
-    return;
-  }
-
-  VLOG(1) << "Setting extra_free mb to: " << extra_free;
-  debugd_client->SetSwapParameter(
-      kExtraFree, extra_free, base::BindOnce(&OnSwapParameterSet, kExtraFree));
-}
-
 void OnMemoryMarginsSet(bool result, uint64_t critical, uint64_t moderate) {
   if (!result) {
     LOG(ERROR) << "Unable to set critical memory margins via resourced";
@@ -239,9 +143,6 @@
 
 void ConfigureSwap(bool arc_enabled) {
   ConfigureResourcedPressureThreshold(arc_enabled);
-  ConfigureExtraFreeIfEnabled();
-  ConfigureRamVsSwapWeightIfEnabled();
-  ConfigureMinFilelistIfEnabled();
 }
 
 }  // namespace ash
diff --git a/chromeos/ash/components/memory/swap_configuration.h b/chromeos/ash/components/memory/swap_configuration.h
index 6dccbc4..c9782db7 100644
--- a/chromeos/ash/components/memory/swap_configuration.h
+++ b/chromeos/ash/components/memory/swap_configuration.h
@@ -11,24 +11,6 @@
 
 namespace ash {
 
-// Controls the ChromeOS /proc/sys/vm/min_filelist_kb swap tunable, if the
-// feature is enabled it will use the value (in MB) from the feature param.
-BASE_DECLARE_FEATURE(kCrOSTuneMinFilelist);
-extern const base::FeatureParam<int> kCrOSTuneMinFilelistMb;
-
-// Controls the ChromeOS /sys/kernel/mm/chromeos-low_mem/ram_vs_swap_weight
-// tunable. The number is a zero or positive number which represents how well
-// zram based swap is compressed in physical ram.
-BASE_DECLARE_FEATURE(kCrOSTuneRamVsSwapWeight);
-extern const base::FeatureParam<int> kCrOSRamVsSwapWeight;
-
-// Controls the ChromeOS /proc/sys/vm/extra_free_kbytes tunable. The number is a
-// zero or positive number which represents how much additional memory the
-// kernel will keep around. Raising this number has the affect of causing
-// swapping earlier.
-BASE_DECLARE_FEATURE(kCrOSTuneExtraFree);
-extern const base::FeatureParam<int> kCrOSExtraFreeMb;
-
 // Controls the threshold at which memory pressure signals are sent for
 // arc-disabled devices.
 COMPONENT_EXPORT(ASH_MEMORY)
diff --git a/chromeos/ash/components/network/cellular_esim_profile_handler_impl_unittest.cc b/chromeos/ash/components/network/cellular_esim_profile_handler_impl_unittest.cc
index 66d20b06..0f16e3d 100644
--- a/chromeos/ash/components/network/cellular_esim_profile_handler_impl_unittest.cc
+++ b/chromeos/ash/components/network/cellular_esim_profile_handler_impl_unittest.cc
@@ -318,7 +318,8 @@
   CellularESimProfileHandlerImplTest_SmdsSupportEnabled()
       : CellularESimProfileHandlerImplTest(
             /*enabled_features=*/{ash::features::kSmdsDbusMigration,
-                                  ash::features::kSmdsSupport},
+                                  ash::features::kSmdsSupport,
+                                  ash::features::kSmdsSupportEuiccUpload},
             /*disabled_features=*/{}) {}
   ~CellularESimProfileHandlerImplTest_SmdsSupportEnabled() override = default;
 };
@@ -338,6 +339,7 @@
       : CellularESimProfileHandlerImplTest(
             /*enabled_features=*/{ash::features::kSmdsDbusMigration,
                                   ash::features::kSmdsSupport,
+                                  ash::features::kSmdsSupportEuiccUpload,
                                   ash::features::kUseStorkSmdsServerAddress},
             /*disabled_features=*/{}) {}
   ~CellularESimProfileHandlerImplTest_SmdsSupportAndStorkEnabled() override =
diff --git a/chromeos/ash/components/quick_start/BUILD.gn b/chromeos/ash/components/quick_start/BUILD.gn
index e71e67c..e3bb4231 100644
--- a/chromeos/ash/components/quick_start/BUILD.gn
+++ b/chromeos/ash/components/quick_start/BUILD.gn
@@ -15,7 +15,6 @@
     "quick_start_requests.h",
   ]
   deps = [
-    "proto",
     "//base",
     "//components/cbor",
     "//crypto",
@@ -28,7 +27,6 @@
   testonly = true
   public_deps = [ ":quick_start" ]
   deps = [
-    "proto",
     "//base",
     "//chrome/browser/nearby_sharing/public/cpp",
     "//chromeos/ash/services/nearby/public/mojom:mojom",
diff --git a/chromeos/ash/components/quick_start/quick_start_requests.cc b/chromeos/ash/components/quick_start/quick_start_requests.cc
index 70bc624..4b20e45 100644
--- a/chromeos/ash/components/quick_start/quick_start_requests.cc
+++ b/chromeos/ash/components/quick_start/quick_start_requests.cc
@@ -5,7 +5,6 @@
 #include "quick_start_requests.h"
 #include "base/base64.h"
 #include "base/json/json_writer.h"
-#include "chromeos/ash/components/quick_start/proto/aes_gcm_authentication_message.pb.h"
 #include "chromeos/ash/components/quick_start/quick_start_message.h"
 #include "chromeos/ash/components/quick_start/quick_start_message_type.h"
 #include "components/cbor/values.h"
@@ -19,8 +18,6 @@
 
 namespace {
 
-namespace proto = ::quick_start::proto;
-
 // bootstrapOptions key telling the phone how to handle
 // challenge UI in case of fallback.
 constexpr char kFlowTypeKey[] = "flowType";
@@ -67,10 +64,6 @@
 // ID
 constexpr char kSessionIdKey[] = "SESSION_ID";
 
-// The role that should be used for the target device. See this enum:
-// http://google3/java/com/google/android/gms/smartdevice/d2d/proto/aes_gcm_authentication_message.proto;l=26;rcl=489093041
-constexpr int32_t kAuthPayloadTargetDeviceRole = 1;
-
 // Boolean in NotifySourceOfUpdateMessage indicating target device requires an
 // update.
 constexpr char kNotifySourceOfUpdateMessageKey[] = "forced_update_required";
@@ -171,7 +164,7 @@
   // Encode the CtapGetAssertionRequest into cbor bytes vector.
   absl::optional<std::vector<uint8_t>> cbor_bytes =
       cbor::Writer::Write(request);
-  DCHECK(cbor_bytes);
+  CHECK(cbor_bytes);
   std::vector<uint8_t> request_bytes = std::move(*cbor_bytes);
   // Add the command byte to the beginning of this now fully encoded cbor bytes
   // vector.
@@ -180,41 +173,9 @@
   return request_bytes;
 }
 
-std::vector<uint8_t> BuildTargetDeviceHandshakeMessage(
-    const std::string& authentication_token,
-    std::array<uint8_t, 32> secret,
-    std::array<uint8_t, 12> nonce) {
-  proto::V1Message::AuthenticationPayload auth_payload;
-  auth_payload.set_role(kAuthPayloadTargetDeviceRole);
-  auth_payload.set_auth_string(authentication_token);
-
-  std::string unencrypted_payload;
-  auth_payload.SerializeToString(&unencrypted_payload);
-
-  crypto::Aead aead(crypto::Aead::AeadAlgorithm::AES_256_GCM);
-  aead.Init(secret);
-  std::vector<uint8_t> encrypted_payload =
-      aead.Seal(std::vector<uint8_t>(unencrypted_payload.begin(),
-                                     unencrypted_payload.end()),
-                nonce, /*additional_data=*/std::vector<uint8_t>());
-
-  proto::AesGcmAuthenticationMessage auth_message;
-  auth_message.set_version(proto::AesGcmAuthenticationMessage::V1);
-  proto::V1Message* v1_message = auth_message.mutable_v1();
-  v1_message->set_nonce(std::string(nonce.begin(), nonce.end()));
-  v1_message->set_payload(
-      std::string(encrypted_payload.begin(), encrypted_payload.end()));
-
-  std::string auth_message_serialized;
-  auth_message.SerializeToString(&auth_message_serialized);
-
-  return std::vector<uint8_t>(auth_message_serialized.begin(),
-                              auth_message_serialized.end());
-}
-
 std::unique_ptr<QuickStartMessage> BuildNotifySourceOfUpdateMessage(
     int32_t session_id,
-    std::string& shared_secret) {
+    const base::span<uint8_t, 32> shared_secret) {
   std::unique_ptr<QuickStartMessage> message =
       std::make_unique<QuickStartMessage>(
           QuickStartMessageType::kQuickStartPayload);
diff --git a/chromeos/ash/components/quick_start/quick_start_requests.h b/chromeos/ash/components/quick_start/quick_start_requests.h
index 50461d3..ebeaa1a 100644
--- a/chromeos/ash/components/quick_start/quick_start_requests.h
+++ b/chromeos/ash/components/quick_start/quick_start_requests.h
@@ -33,14 +33,9 @@
 
 cbor::Value GenerateGetAssertionRequest(const std::string& challenge_b64url);
 
-std::vector<uint8_t> BuildTargetDeviceHandshakeMessage(
-    const std::string& authentication_token,
-    std::array<uint8_t, 32> secret,
-    std::array<uint8_t, 12> nonce);
-
 std::unique_ptr<QuickStartMessage> BuildNotifySourceOfUpdateMessage(
     int32_t session_id,
-    std::string& shared_secret);
+    const base::span<uint8_t, 32> shared_secret);
 }  // namespace ash::quick_start::requests
 
 #endif  // CHROMEOS_ASH_COMPONENTS_QUICK_START_QUICK_START_REQUESTS_H
diff --git a/chromeos/ash/resources/BUILD.gn b/chromeos/ash/resources/BUILD.gn
index 64a9322..3ce4a2bbc 100644
--- a/chromeos/ash/resources/BUILD.gn
+++ b/chromeos/ash/resources/BUILD.gn
@@ -28,7 +28,7 @@
 
   deps = [
     "//chromeos/ash/components/human_presence:human_presence_internals_ts",
-    "//chromeos/ash/components/language/public/mojom:mojom_js",
+    "//chromeos/ash/components/language_packs/public/mojom:mojom_js",
     "//chromeos/ash/components/multidevice/mojom:mojom_js",
     "//chromeos/ash/services/device_sync/public/mojom:mojom_js",
     "//chromeos/ash/services/multidevice_setup/public/mojom:mojom_js",
diff --git a/chromeos/ash/services/cellular_setup/euicc_unittest.cc b/chromeos/ash/services/cellular_setup/euicc_unittest.cc
index 298f45ff..c5bbf66c 100644
--- a/chromeos/ash/services/cellular_setup/euicc_unittest.cc
+++ b/chromeos/ash/services/cellular_setup/euicc_unittest.cc
@@ -332,7 +332,9 @@
 TEST_F(EuiccTest, RequestAvailableProfiles) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitWithFeatures(
-      {ash::features::kSmdsDbusMigration, ash::features::kSmdsSupport}, {});
+      {ash::features::kSmdsDbusMigration, ash::features::kSmdsSupport,
+       ash::features::kSmdsSupportEuiccUpload},
+      {});
 
   mojo::Remote<mojom::Euicc> euicc = GetEuiccForEid(ESimTestBase::kTestEid);
   ASSERT_TRUE(euicc.is_bound());
@@ -373,7 +375,9 @@
 TEST_F(EuiccTest, RequestAvailableProfiles_FailToInhibit) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitWithFeatures(
-      {ash::features::kSmdsDbusMigration, ash::features::kSmdsSupport}, {});
+      {ash::features::kSmdsDbusMigration, ash::features::kSmdsSupport,
+       ash::features::kSmdsSupportEuiccUpload},
+      {});
 
   mojo::Remote<mojom::Euicc> euicc = GetEuiccForEid(ESimTestBase::kTestEid);
   ASSERT_TRUE(euicc.is_bound());
diff --git a/chromeos/ash/services/ime/ime_service.cc b/chromeos/ash/services/ime/ime_service.cc
index 4752b345..ae472e6 100644
--- a/chromeos/ash/services/ime/ime_service.cc
+++ b/chromeos/ash/services/ime/ime_service.cc
@@ -136,48 +136,26 @@
   main_task_runner_->PostTask(FROM_HERE, base::BindOnce(task, task_id));
 }
 
-// TODO(b/218815885): Use consistent feature flag names as in CrOS
-// base::Feature::name (instead of slightly-different bespoke names), and always
-// wire 1:1 to CrOS feature flags (instead of having any extra logic).
 bool ImeService::IsFeatureEnabled(const char* feature_name) {
-  // TODO(b/218815885): Replace refs of AssistiveEmojiEnhanced with
-  // AssistEmojiEnhanced in internal code for consistency.
-  // Then remove the AssistiveEmojiEnhanced check.
-  if (strcmp(feature_name, "AssistiveEmojiEnhanced") == 0 ||
-      strcmp(feature_name, features::kAssistEmojiEnhanced.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kAssistEmojiEnhanced);
-  }
-  // TODO(b/218815885): Replace refs of AssistiveMultiWord with
-  // AssistMultiWord in internal code for consistency.
-  // Then remove the AssistiveMultiWord check.
-  if (strcmp(feature_name, "AssistiveMultiWord") == 0 ||
-      strcmp(feature_name, features::kAssistMultiWord.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kAssistMultiWord);
-  }
-  if (strcmp(feature_name, features::kAutocorrectParamsTuning.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kAutocorrectParamsTuning);
-  }
-  if (strcmp(feature_name, features::kFirstPartyVietnameseInput.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kFirstPartyVietnameseInput);
-  }
-  if (strcmp(feature_name, features::kLacrosSupport.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kLacrosSupport);
-  }
-  if (strcmp(feature_name, features::kSystemJapanesePhysicalTyping.name) == 0) {
-    return base::FeatureList::IsEnabled(
-        features::kSystemJapanesePhysicalTyping);
-  }
-  if (strcmp(feature_name, features::kImeDownloaderUpdate.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kImeDownloaderUpdate);
-  }
-  if (strcmp(feature_name, features::kImeUsEnglishModelUpdate.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kImeUsEnglishModelUpdate);
-  }
-  if (strcmp(feature_name, features::kImeFstDecoderParamsUpdate.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kImeFstDecoderParamsUpdate);
-  }
-  if (strcmp(feature_name, features::kAutocorrectByDefault.name) == 0) {
-    return base::FeatureList::IsEnabled(features::kAutocorrectByDefault);
+  static const base::Feature* kConsideredFeatures[] = {
+      &features::kAssistEmojiEnhanced,
+      &features::kAssistMultiWord,
+      &features::kAutocorrectParamsTuning,
+      &features::kFirstPartyVietnameseInput,
+      &features::kLacrosSupport,
+      &features::kSystemJapanesePhysicalTyping,
+      &features::kImeDownloaderUpdate,
+      &features::kImeUsEnglishModelUpdate,
+      &features::kImeFstDecoderParamsUpdate,
+      &features::kAutocorrectByDefault,
+  };
+
+  // Use consistent feature flag names as in CrOS base::Feature::name and always
+  // wire 1:1 to CrOS feature flags without extra logic.
+  for (const base::Feature* feature : kConsideredFeatures) {
+    if (strcmp(feature_name, feature->name) == 0) {
+      return base::FeatureList::IsEnabled(*feature);
+    }
   }
   return false;
 }
diff --git a/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h b/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h
index 952fd75..615581e 100644
--- a/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h
+++ b/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h
@@ -121,13 +121,10 @@
   // required to run in the thread creating its remote.
   virtual void RunInMainSequence(ImeSequencedTask task, int task_id) = 0;
 
-  // Returns whether a Chrome OS experimental feature is enabled or not. Only a
-  // subset of CrOS features are considered (features not considered appear as
-  // disabled), |feature_name| may or may not correspond to base::Feature::name
-  // of the CrOS feature, and there could be extra logic (see impl for details).
-  // TODO(b/218815885): Use consistent feature flag names as in CrOS
-  // base::Feature::name (instead of slightly-different bespoke names), and
-  // always wire 1:1 to CrOS feature flags (instead of having any extra logic).
+  // Returns whether a CrOS experimental feature is enabled. Only a subset of
+  // CrOS features are considered (features not considered appear as disabled).
+  // |feature_name| corresponds to base::Feature::name of the CrOS feature as
+  // defined in ash/constants/ash_features.cc in the Chromium repo.
   virtual bool IsFeatureEnabled(const char* feature_name) = 0;
 
   // Start a download using |SimpleURLLoader|. Each SimpleDownloadToFileV2 can
diff --git a/chromeos/crosapi/mojom/web_app_service.mojom b/chromeos/crosapi/mojom/web_app_service.mojom
index cab6fbd..3f5c68d 100644
--- a/chromeos/crosapi/mojom/web_app_service.mojom
+++ b/chromeos/crosapi/mojom/web_app_service.mojom
@@ -30,8 +30,8 @@
 
 // Implemented in lacros-chrome. Allows ash-chrome to modify web app state in
 // lacros-chrome.
-// Next version: 6
-// Next method id: 7
+// Next version: 7
+// Next method id: 8
 [Stable, Uuid="84eb46eb-76fe-439c-9fcb-3388492e141d"]
 interface WebAppProviderBridge {
   // Called when a web app described by |info| is installed in ARC (Android
@@ -76,6 +76,12 @@
   // ID.
   [MinVersion=5]
   GetSubAppToParentMap@6() => (map<string, string> parent_apps);
+
+  // Called when a web app described by |preload_install_info| is preloaded and
+  // installs this web app in the primary profile of Lacros.
+  [MinVersion=6]
+  InstallPreloadWebApp@7(PreloadWebAppInstallInfo preload_install_info)
+    => (string app_id, WebAppInstallResultCode install_result);
 };
 
 // An interface implemented in ash-chrome. Allows lacros-chrome:
diff --git a/chromeos/crosapi/mojom/web_app_types.mojom b/chromeos/crosapi/mojom/web_app_types.mojom
index baf34e5..d0aaf8c4 100644
--- a/chromeos/crosapi/mojom/web_app_types.mojom
+++ b/chromeos/crosapi/mojom/web_app_types.mojom
@@ -61,3 +61,19 @@
   gfx.mojom.ImageSkia icon@4;
   [MinVersion=1] array<string>? additional_policy_ids@5;
 };
+
+// The set of information necessary to install a preloaded web app in Lacros.
+[Stable]
+struct PreloadWebAppInstallInfo {
+  // The url from which the web app is installed.
+  url.mojom.Url document_url@0;
+
+  // The url from which the manifest is fetched.
+  url.mojom.Url manifest_url@1;
+
+  // The expected app id for the installed web app.
+  string expected_app_id@2;
+
+  // The standard web app manifest, encoded as a JSON string.
+  string manifest@3;
+};
diff --git a/chromeos/services/machine_learning/public/mojom/model.mojom b/chromeos/services/machine_learning/public/mojom/model.mojom
index 7ac35c9..94fec3e8 100644
--- a/chromeos/services/machine_learning/public/mojom/model.mojom
+++ b/chromeos/services/machine_learning/public/mojom/model.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Next MinVersion: 3
+// Next MinVersion: 4
 
 // Datatypes and interfaces of models for the Machine Learning API.
 
@@ -43,9 +43,11 @@
   // The Search Ranker (20190923) ML model.
   UNSUPPORTED_SEARCH_RANKER_20190923 = 6,
   // The Adaptive Charging (20211105) ML model.
-  [MinVersion=1] ADAPTIVE_CHARGING_20211105 = 7,
+  [MinVersion=1] UNSUPPORTED_ADAPTIVE_CHARGING_20211105 = 7,
   // The Poncho Palm Rejection ML model.
   [MinVersion=2] PONCHO_PALM_REJECTION_20230213 = 8,
+  // The Adaptive Charging (20230314) ML model.
+  [MinVersion=3] ADAPTIVE_CHARGING_20230314= 9,
 };
 
 // Graphics API to use with the GPU delegate.
diff --git a/chromeos/services/machine_learning/public/mojom/soda.mojom b/chromeos/services/machine_learning/public/mojom/soda.mojom
index bfb5f44..dedfac27 100644
--- a/chromeos/services/machine_learning/public/mojom/soda.mojom
+++ b/chromeos/services/machine_learning/public/mojom/soda.mojom
@@ -192,7 +192,7 @@
   OnSpeechRecognizerEvent@2(SpeechRecognizerEvent event);
 };
 
-// The mojom interface for performing the recognition of handwritten text.
+// The mojom interface for performing the recognition of spoken text.
 // Next ordinal: 4
 [Stable]
 interface SodaRecognizer {
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index ef60504..e40827ce 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -3578,7 +3578,7 @@
   // Get the set of profiles persisted in the db.
   std::vector<std::unique_ptr<AutofillProfile>> db_profiles;
   profile_autofill_table_->GetAutofillProfiles(
-      &db_profiles, AutofillProfile::Source::kLocalOrSyncable);
+      AutofillProfile::Source::kLocalOrSyncable, &db_profiles);
 
   // Expect the profiles held in-memory by PersonalDataManager and the db
   // profiles to be the same.
@@ -4964,7 +4964,7 @@
   std::vector<std::unique_ptr<AutofillProfile>> profiles;
   // Expect that a profile is stored in the profile autofill table.
   profile_autofill_table_->GetAutofillProfiles(
-      &profiles, AutofillProfile::Source::kLocalOrSyncable);
+      AutofillProfile::Source::kLocalOrSyncable, &profiles);
   EXPECT_EQ(1U, profiles.size());
   EXPECT_EQ(profile, *profiles[0]);
 }
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
index ab92f539..162c932 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
@@ -167,7 +167,7 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   std::vector<std::unique_ptr<AutofillProfile>> entries;
   if (!GetAutofillTable()->GetAutofillProfiles(
-          &entries, AutofillProfile::Source::kLocalOrSyncable)) {
+          AutofillProfile::Source::kLocalOrSyncable, &entries)) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed to load entries from table."});
     return;
@@ -190,7 +190,7 @@
 
   std::vector<std::unique_ptr<AutofillProfile>> entries;
   if (!GetAutofillTable()->GetAutofillProfiles(
-          &entries, AutofillProfile::Source::kLocalOrSyncable)) {
+          AutofillProfile::Source::kLocalOrSyncable, &entries)) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed to load entries from table."});
     return;
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.cc
index b4730ac..6eed2b9e 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.cc
@@ -218,8 +218,8 @@
   }
 
   std::vector<std::unique_ptr<AutofillProfile>> entries;
-  if (!table_->GetAutofillProfiles(&entries,
-                                   AutofillProfile::Source::kLocalOrSyncable)) {
+  if (!table_->GetAutofillProfiles(AutofillProfile::Source::kLocalOrSyncable,
+                                   &entries)) {
     return false;
   }
 
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker_unittest.cc
index 1218a0ae..38329d6 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker_unittest.cc
@@ -100,7 +100,7 @@
     std::vector<std::unique_ptr<AutofillProfile>> vector_of_unique_ptrs;
     // Meant as an assertion but I cannot use ASSERT_TRUE in non-void function.
     EXPECT_TRUE(table()->GetAutofillProfiles(
-        &vector_of_unique_ptrs, AutofillProfile::Source::kLocalOrSyncable));
+        AutofillProfile::Source::kLocalOrSyncable, &vector_of_unique_ptrs));
 
     // Copy all the elements by value so that we have a vector that is easier to
     // work with in the test.
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index 34e8e0ee..5b98829 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -1599,8 +1599,8 @@
 }
 
 bool AutofillTable::GetAutofillProfiles(
-    std::vector<std::unique_ptr<AutofillProfile>>* profiles,
-    AutofillProfile::Source profile_source) const {
+    AutofillProfile::Source profile_source,
+    std::vector<std::unique_ptr<AutofillProfile>>* profiles) const {
   CHECK(profiles);
   profiles->clear();
 
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h
index af04cff..437d053 100644
--- a/components/autofill/core/browser/webdata/autofill_table.h
+++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -618,8 +618,8 @@
   // The `profile_source` specifies if profiles from the legacy or the remote
   // backend should be retrieved.
   virtual bool GetAutofillProfiles(
-      std::vector<std::unique_ptr<AutofillProfile>>* profiles,
-      AutofillProfile::Source profile_source) const;
+      AutofillProfile::Source profile_source,
+      std::vector<std::unique_ptr<AutofillProfile>>* profiles) const;
   virtual bool GetServerProfiles(
       std::vector<std::unique_ptr<AutofillProfile>>* profiles) const;
 
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
index da26c6c..75307d66 100644
--- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -996,11 +996,11 @@
   EXPECT_TRUE(
       table_->RemoveAutofillProfile(home_profile.guid(), profile_source()));
   std::vector<std::unique_ptr<AutofillProfile>> profiles;
-  EXPECT_TRUE(table_->GetAutofillProfiles(&profiles, profile_source()));
+  EXPECT_TRUE(table_->GetAutofillProfiles(profile_source(), &profiles));
   EXPECT_TRUE(profiles.empty());
 }
 
-// Tests that `GetAutofillProfiles(profiles, source)` cleares `profiles` and
+// Tests that `GetAutofillProfiles(source, profiles)` clears `profiles` and
 // only returns profiles from the correct `source`.
 // Not part of the `AutofillTableProfileTest` fixture, as it doesn't benefit
 // from parameterization on the `profile_source()`.
@@ -1012,10 +1012,10 @@
 
   std::vector<std::unique_ptr<AutofillProfile>> profiles;
   EXPECT_TRUE(table_->GetAutofillProfiles(
-      &profiles, AutofillProfile::Source::kLocalOrSyncable));
+      AutofillProfile::Source::kLocalOrSyncable, &profiles));
   EXPECT_THAT(profiles, ElementsAre(testing::Pointee(local_profile)));
-  EXPECT_TRUE(table_->GetAutofillProfiles(&profiles,
-                                          AutofillProfile::Source::kAccount));
+  EXPECT_TRUE(table_->GetAutofillProfiles(AutofillProfile::Source::kAccount,
+                                          &profiles));
   EXPECT_THAT(profiles, ElementsAre(testing::Pointee(account_profile)));
 }
 
@@ -1031,7 +1031,7 @@
 
   // Expect that the profiles from `profile_source()` are gone.
   std::vector<std::unique_ptr<AutofillProfile>> profiles;
-  ASSERT_TRUE(table_->GetAutofillProfiles(&profiles, profile_source()));
+  ASSERT_TRUE(table_->GetAutofillProfiles(profile_source(), &profiles));
   EXPECT_TRUE(profiles.empty());
 
   // Expect that the profile from the opposite source remains.
@@ -1039,7 +1039,7 @@
       profile_source() == AutofillProfile::Source::kAccount
           ? AutofillProfile::Source::kLocalOrSyncable
           : AutofillProfile::Source::kAccount;
-  ASSERT_TRUE(table_->GetAutofillProfiles(&profiles, other_source));
+  ASSERT_TRUE(table_->GetAutofillProfiles(other_source, &profiles));
   EXPECT_EQ(profiles.size(), 1u);
 }
 
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
index 336188d5..ac720aa 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
+++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
@@ -339,8 +339,8 @@
     WebDatabase* db) {
   DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
   std::vector<std::unique_ptr<AutofillProfile>> profiles;
-  AutofillTable::FromWebDatabase(db)->GetAutofillProfiles(&profiles,
-                                                          profile_source);
+  AutofillTable::FromWebDatabase(db)->GetAutofillProfiles(profile_source,
+                                                          &profiles);
   return std::unique_ptr<WDTypedResult>(
       new WDResult<std::vector<std::unique_ptr<AutofillProfile>>>(
           AUTOFILL_PROFILES_RESULT, std::move(profiles)));
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_util.cc b/components/autofill/core/browser/webdata/autofill_webdata_backend_util.cc
index af43771..60392e8 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_backend_util.cc
+++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_util.cc
@@ -213,8 +213,8 @@
   std::vector<std::unique_ptr<AutofillProfile>> local_profiles;
   std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
   std::vector<std::unique_ptr<CreditCard>> server_cards;
-  if (!table->GetAutofillProfiles(&local_profiles,
-                                  AutofillProfile::Source::kLocalOrSyncable) ||
+  if (!table->GetAutofillProfiles(AutofillProfile::Source::kLocalOrSyncable,
+                                  &local_profiles) ||
       !table->GetServerProfiles(&server_profiles) ||
       !table->GetServerCreditCards(&server_cards)) {
     return WebDatabase::COMMIT_NOT_NEEDED;
diff --git a/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc b/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc
index 60892c5..eb93ec9 100644
--- a/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc
@@ -290,7 +290,7 @@
     base::RepeatingCallback<bool(const std::string&)> filter) {
   std::vector<std::unique_ptr<AutofillProfile>> profiles;
   if (!GetAutofillTable()->GetAutofillProfiles(
-          &profiles, AutofillProfile::Source::kAccount)) {
+          AutofillProfile::Source::kAccount, &profiles)) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed to load profiles from table."});
     return nullptr;
diff --git a/components/autofill/core/browser/webdata/contact_info_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/contact_info_sync_bridge_unittest.cc
index 1a2f2aa..b46343d 100644
--- a/components/autofill/core/browser/webdata/contact_info_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/contact_info_sync_bridge_unittest.cc
@@ -115,8 +115,8 @@
   // how the PersonalDataManager will access the profiles.
   std::vector<AutofillProfile> GetAllDataFromTable() {
     std::vector<std::unique_ptr<AutofillProfile>> profile_ptrs;
-    EXPECT_TRUE(table_.GetAutofillProfiles(&profile_ptrs,
-                                           AutofillProfile::Source::kAccount));
+    EXPECT_TRUE(table_.GetAutofillProfiles(AutofillProfile::Source::kAccount,
+                                           &profile_ptrs));
     // In tests, it's more convenient to work without `std::unique_ptr`.
     std::vector<AutofillProfile> profiles;
     for (const std::unique_ptr<AutofillProfile>& profile_ptr : profile_ptrs) {
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc
index 96ab9c1..1ba152dc 100644
--- a/components/bookmarks/browser/bookmark_model.cc
+++ b/components/bookmarks/browser/bookmark_model.cc
@@ -871,7 +871,8 @@
   if (meta_info) {
     new_node->SetMetaInfoMap(*meta_info);
   }
-  metrics::RecordBookmarkFolderAdded(GetFolderType(parent));
+  metrics::RecordBookmarkFolderAdded(GetFolderType(parent),
+                                     client_->GetStorageStateForUma());
   return AddNode(AsMutable(parent), index, std::move(new_node));
 }
 
@@ -1138,7 +1139,8 @@
 
   const base::TimeDelta load_duration =
       base::TimeTicks::Now() - details->load_start();
-  metrics::RecordTimeToLoadAtStartup(load_duration);
+  metrics::RecordTimeToLoadAtStartup(load_duration,
+                                     client_->GetStorageStateForUma());
 
   // Notify our direct observers.
   for (BookmarkModelObserver& observer : observers_) {
diff --git a/components/bookmarks/browser/bookmark_model_unittest.cc b/components/bookmarks/browser/bookmark_model_unittest.cc
index a446c46..da40766 100644
--- a/components/bookmarks/browser/bookmark_model_unittest.cc
+++ b/components/bookmarks/browser/bookmark_model_unittest.cc
@@ -557,6 +557,45 @@
   EXPECT_TRUE(other_node->id() != mobile_node->id());
 }
 
+// Tests recording Bookmarks.Storage.TimeToLoadAtStartup2 histogram for account
+// storage.
+TEST_F(BookmarkModelTest, LoadModelWithAccountStorage) {
+  auto client = std::make_unique<TestBookmarkClient>();
+  client->SetStorageStateForUma(metrics::StorageStateForUma::kAccount);
+  model_ = TestBookmarkClient::CreateModelWithClient(std::move(client));
+
+  histogram_tester()->ExpectTotalCount("Bookmarks.Storage.TimeToLoadAtStartup2",
+                                       1);
+  histogram_tester()->ExpectTotalCount(
+      "Bookmarks.Storage.TimeToLoadAtStartup2.AccountStorage", 1);
+}
+
+// Tests recording Bookmarks.Storage.TimeToLoadAtStartup2 histogram for local
+// storage not syncing.
+TEST_F(BookmarkModelTest, LoadModelWithLocalStorageNotSyncing) {
+  auto client = std::make_unique<TestBookmarkClient>();
+  client->SetStorageStateForUma(metrics::StorageStateForUma::kLocalOnly);
+  model_ = TestBookmarkClient::CreateModelWithClient(std::move(client));
+
+  histogram_tester()->ExpectTotalCount("Bookmarks.Storage.TimeToLoadAtStartup2",
+                                       1);
+  histogram_tester()->ExpectTotalCount(
+      "Bookmarks.Storage.TimeToLoadAtStartup2.LocalStorage", 1);
+}
+
+// Tests recording Bookmarks.Storage.TimeToLoadAtStartup2 histogram for local
+// storage syncing.
+TEST_F(BookmarkModelTest, LoadModelWithLocalStorageSyncing) {
+  auto client = std::make_unique<TestBookmarkClient>();
+  client->SetStorageStateForUma(metrics::StorageStateForUma::kSyncEnabled);
+  model_ = TestBookmarkClient::CreateModelWithClient(std::move(client));
+
+  histogram_tester()->ExpectTotalCount("Bookmarks.Storage.TimeToLoadAtStartup2",
+                                       1);
+  histogram_tester()->ExpectTotalCount(
+      "Bookmarks.Storage.TimeToLoadAtStartup2.LocalStorageSyncing", 1);
+}
+
 TEST_F(BookmarkModelTest, AddURL) {
   const BookmarkNode* bookmark_bar_node = model_->bookmark_bar_node();
   const std::u16string title(u"foo");
@@ -605,7 +644,7 @@
                              testing::Ne(model_->mobile_node()->id())));
 }
 
-// Tests recording user action when adding bookmarks in account storage.
+// Tests recording user action when adding a bookmark in account storage.
 TEST_F(BookmarkModelTest, AddNewURLAccountStorage) {
   auto client = std::make_unique<TestBookmarkClient>();
   client->SetStorageStateForUma(metrics::StorageStateForUma::kAccount);
@@ -618,7 +657,7 @@
                    "Bookmarks.Added.AccountStorage"));
 }
 
-// Tests recording user action when adding bookmarks in local storage not
+// Tests recording user action when adding a bookmark in local storage not
 // syncing.
 TEST_F(BookmarkModelTest, AddNewURLLocalStorageNotSyncing) {
   auto client = std::make_unique<TestBookmarkClient>();
@@ -632,7 +671,7 @@
       1, user_action_tester()->GetActionCount("Bookmarks.Added.LocalStorage"));
 }
 
-// Tests recording user action when adding bookmarks in local storage syncing.
+// Tests recording user action when adding a bookmark in local storage syncing.
 TEST_F(BookmarkModelTest, AddNewURLLocalStorageSyncing) {
   auto client = std::make_unique<TestBookmarkClient>();
   client->SetStorageStateForUma(metrics::StorageStateForUma::kSyncEnabled);
@@ -645,6 +684,45 @@
                    "Bookmarks.Added.LocalStorageSyncing"));
 }
 
+// Tests recording user action when adding a folder in account storage.
+TEST_F(BookmarkModelTest, AddNewFolderAccountStorage) {
+  auto client = std::make_unique<TestBookmarkClient>();
+  client->SetStorageStateForUma(metrics::StorageStateForUma::kAccount);
+  model_ = TestBookmarkClient::CreateModelWithClient(std::move(client));
+
+  model_->AddFolder(model_->mobile_node(), 0, u"title");
+  EXPECT_EQ(1, user_action_tester()->GetActionCount("Bookmarks.FolderAdded"));
+  EXPECT_EQ(1, user_action_tester()->GetActionCount(
+                   "Bookmarks.FolderAdded.AccountStorage"));
+}
+
+// Tests recording user action when adding a folder in local storage not
+// syncing.
+TEST_F(BookmarkModelTest, AddNewFolderLocalStorageNotSyncing) {
+  auto client = std::make_unique<TestBookmarkClient>();
+  client->SetStorageStateForUma(metrics::StorageStateForUma::kLocalOnly);
+  model_ = TestBookmarkClient::CreateModelWithClient(std::move(client));
+
+  model_->AddFolder(model_->mobile_node(), 0, u"title");
+  EXPECT_EQ(1, user_action_tester()->GetActionCount("Bookmarks.FolderAdded"));
+  EXPECT_EQ(1, user_action_tester()->GetActionCount(
+                   "Bookmarks.FolderAdded.LocalStorage"));
+  histogram_tester()->ExpectTotalCount("Bookmarks.Storage.TimeToLoadAtStartup2",
+                                       1);
+}
+
+// Tests recording user action when adding a folder in local storage syncing.
+TEST_F(BookmarkModelTest, AddNewFolderLocalStorageSyncing) {
+  auto client = std::make_unique<TestBookmarkClient>();
+  client->SetStorageStateForUma(metrics::StorageStateForUma::kSyncEnabled);
+  model_ = TestBookmarkClient::CreateModelWithClient(std::move(client));
+
+  model_->AddFolder(model_->mobile_node(), 0, u"title");
+  EXPECT_EQ(1, user_action_tester()->GetActionCount("Bookmarks.FolderAdded"));
+  EXPECT_EQ(1, user_action_tester()->GetActionCount(
+                   "Bookmarks.FolderAdded.LocalStorageSyncing"));
+}
+
 TEST_F(BookmarkModelTest, AddURLWithUnicodeTitle) {
   const BookmarkNode* bookmark_bar_node = model_->bookmark_bar_node();
   const std::u16string title(
diff --git a/components/bookmarks/common/bookmark_metrics.cc b/components/bookmarks/common/bookmark_metrics.cc
index c6f9ec1e..798c342c 100644
--- a/components/bookmarks/common/bookmark_metrics.cc
+++ b/components/bookmarks/common/bookmark_metrics.cc
@@ -46,8 +46,12 @@
   RecordBookmarkParentFolderType(parent);
 }
 
-void RecordBookmarkFolderAdded(BookmarkFolderTypeForUMA parent) {
+void RecordBookmarkFolderAdded(BookmarkFolderTypeForUMA parent,
+                               StorageStateForUma storage_state) {
   base::RecordAction(base::UserMetricsAction("Bookmarks.FolderAdded"));
+  base::RecordComputedAction(
+      base::StrCat({"Bookmarks.FolderAdded",
+                    GetStorageStateSuffixForMetrics(storage_state)}));
   RecordBookmarkParentFolderType(parent);
 }
 
@@ -76,8 +80,13 @@
                               delta);
 }
 
-void RecordTimeToLoadAtStartup(base::TimeDelta delta) {
+void RecordTimeToLoadAtStartup(base::TimeDelta delta,
+                               StorageStateForUma storage_state) {
   UmaHistogramTimes("Bookmarks.Storage.TimeToLoadAtStartup2", delta);
+  UmaHistogramTimes(
+      base::StrCat({"Bookmarks.Storage.TimeToLoadAtStartup2",
+                    GetStorageStateSuffixForMetrics(storage_state)}),
+      delta);
 }
 
 void RecordFileSizeAtStartup(int64_t total_bytes) {
diff --git a/components/bookmarks/common/bookmark_metrics.h b/components/bookmarks/common/bookmark_metrics.h
index 9df412a..0afe90c 100644
--- a/components/bookmarks/common/bookmark_metrics.h
+++ b/components/bookmarks/common/bookmark_metrics.h
@@ -52,7 +52,8 @@
                             StorageStateForUma storage_state);
 
 // Records when a bookmark folder is added by the user.
-void RecordBookmarkFolderAdded(BookmarkFolderTypeForUMA parent);
+void RecordBookmarkFolderAdded(BookmarkFolderTypeForUMA parent,
+                               StorageStateForUma storage_state);
 
 // Records when a bookmark is removed.
 void RecordBookmarkRemoved(BookmarkEditSource source);
@@ -72,7 +73,8 @@
 
 // Records the time it takes to load the bookmark model on startup with a 10
 // second max, the time starts when BookmarkModel.Load is called.
-void RecordTimeToLoadAtStartup(base::TimeDelta delta);
+void RecordTimeToLoadAtStartup(base::TimeDelta delta,
+                               StorageStateForUma storage_state);
 
 // Records size of the bookmark file at startup.
 void RecordFileSizeAtStartup(int64_t total_bytes);
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java
index 3b77bb6..8051e98a 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java
@@ -22,6 +22,7 @@
 import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
+import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.content.res.AppCompatResources;
 
 import org.chromium.base.ApiCompatibilityUtils;
@@ -58,6 +59,9 @@
     private static final ObservableSupplierImpl<Integer> sCountSupplier =
             new ObservableSupplierImpl<>();
 
+    /** Disable assert error if it fails to be displayed. */
+    private static boolean sSkipShowCheckForTesting;
+
     protected final Context mContext;
     private final Handler mHandler;
     private final boolean mInverseColor;
@@ -352,6 +356,9 @@
         }
 
         mPopupWindow.show();
+        assert sSkipShowCheckForTesting || mPopupWindow.isShowing() : "TextBubble is not presented";
+        if (!mPopupWindow.isShowing()) return;
+
         sBubbles.add(this);
         sCountSupplier.set(sBubbles.size());
         mBubbleShowStartTime = System.currentTimeMillis();
@@ -362,13 +369,13 @@
      * @see PopupWindow#dismiss()
      */
     public void dismiss() {
-        mPopupWindow.dismiss();
-
-        if (mBubbleShowStartTime != 0) {
+        if (mPopupWindow.isShowing() && mBubbleShowStartTime != 0) {
             RecordHistogram.recordTimesHistogram("InProductHelp.TextBubble.ShownTime",
                     System.currentTimeMillis() - mBubbleShowStartTime);
             mBubbleShowStartTime = 0;
         }
+
+        mPopupWindow.dismiss();
     }
 
     /**
@@ -563,4 +570,9 @@
     public View getTextBubbleContentViewForTesting() {
         return mContentView;
     }
+
+    @VisibleForTesting
+    public static void setSkipShowCheckForTesting(boolean skip) {
+        sSkipShowCheckForTesting = skip;
+    }
 }
diff --git a/components/browsing_topics/browsing_topics_calculator.cc b/components/browsing_topics/browsing_topics_calculator.cc
index e5575284..504267c 100644
--- a/components/browsing_topics/browsing_topics_calculator.cc
+++ b/components/browsing_topics/browsing_topics_calculator.cc
@@ -214,7 +214,6 @@
 void BrowsingTopicsCalculator::DeriveTopTopics(
     const std::map<HashedHost, size_t>& history_hosts_count,
     const std::map<HashedHost, std::set<Topic>>& host_topics_map,
-    size_t taxonomy_size,
     std::vector<Topic>& top_topics,
     size_t& padded_top_topics_start_index,
     size_t& history_topics_count) {
@@ -240,11 +239,6 @@
 
   history_topics_count = topics_count.size();
 
-  DCHECK_LE(
-      static_cast<size_t>(
-          blink::features::kBrowsingTopicsNumberOfTopTopicsPerEpoch.Get()),
-      taxonomy_size);
-
   // Get the top up to `kBrowsingTopicsNumberOfTopTopicsPerEpoch` topics,
   // sorted by decreasing count.
   using TopicsCountValue = std::pair<Topic, size_t>;
@@ -265,15 +259,18 @@
 
   // Pad the top topics with distinct random topics until we have
   // `kBrowsingTopicsNumberOfTopTopicsPerEpoch` topics.
+  SemanticTree semantic_tree;
   while (top_topics.size() <
          static_cast<size_t>(
              blink::features::kBrowsingTopicsNumberOfTopTopicsPerEpoch.Get())) {
     Topic padded_topic(0);
 
     do {
-      int padded_topic_index =
-          base::checked_cast<int>(GenerateRandUint64() % taxonomy_size);
-      padded_topic = Topic(padded_topic_index + 1);
+      int taxonomy_version =
+          blink::features::kBrowsingTopicsTaxonomyVersion.Get();
+      int padded_topic_index_decision = GenerateRandUint64();
+      padded_topic = semantic_tree.GetRandomTopic(taxonomy_version,
+                                                  padded_topic_index_decision);
     } while (base::Contains(top_topics, padded_topic));
 
     top_topics.emplace_back(std::move(padded_topic));
@@ -393,8 +390,9 @@
     return;
   }
 
-  absl::optional<size_t> taxonomy_size = GetTaxonomySize();
-  if (!taxonomy_size) {
+  SemanticTree semantic_tree;
+  if (!semantic_tree.IsTaxonomySupported(
+          blink::features::kBrowsingTopicsTaxonomyVersion.Get())) {
     OnCalculateCompleted(
         CalculatorResultStatus::kFailureTaxonomyVersionNotSupportedInBinary,
         EpochTopics(calculation_time_));
@@ -412,9 +410,8 @@
   std::vector<Topic> top_topics;
   size_t padded_top_topics_start_index = 0u;
   size_t history_topics_count = 0u;
-  DeriveTopTopics(history_hosts_count_, host_topics_map, *taxonomy_size,
-                  top_topics, padded_top_topics_start_index,
-                  history_topics_count);
+  DeriveTopTopics(history_hosts_count_, host_topics_map, top_topics,
+                  padded_top_topics_start_index, history_topics_count);
 
   base::UmaHistogramCounts1000(
       "BrowsingTopics.EpochTopicsCalculation.HistoryTopicsCount",
@@ -427,8 +424,6 @@
   // For each top topic, derive the context domains that observed it
   std::vector<TopicAndDomains> top_topics_and_observing_domains;
 
-  SemanticTree semantic_tree;
-
   for (const Topic& topic : top_topics) {
     if (!privacy_sandbox_settings_->IsTopicAllowed(
             privacy_sandbox::CanonicalTopic(
@@ -466,7 +461,7 @@
   OnCalculateCompleted(
       CalculatorResultStatus::kSuccess,
       EpochTopics(std::move(top_topics_and_observing_domains),
-                  padded_top_topics_start_index, *taxonomy_size,
+                  padded_top_topics_start_index,
                   blink::features::kBrowsingTopicsTaxonomyVersion.Get(),
                   model_version, calculation_time_));
 }
diff --git a/components/browsing_topics/browsing_topics_calculator.h b/components/browsing_topics/browsing_topics_calculator.h
index 0c4a8e8c..b0bf379 100644
--- a/components/browsing_topics/browsing_topics_calculator.h
+++ b/components/browsing_topics/browsing_topics_calculator.h
@@ -87,7 +87,6 @@
   void DeriveTopTopics(
       const std::map<HashedHost, size_t>& history_hosts_count,
       const std::map<HashedHost, std::set<Topic>>& host_topics_map,
-      size_t taxonomy_size,
       std::vector<Topic>& top_topics,
       size_t& padded_top_topics_start_index,
       size_t& history_topics_count);
diff --git a/components/browsing_topics/browsing_topics_calculator_unittest.cc b/components/browsing_topics/browsing_topics_calculator_unittest.cc
index e96224b..614d7cf 100644
--- a/components/browsing_topics/browsing_topics_calculator_unittest.cc
+++ b/components/browsing_topics/browsing_topics_calculator_unittest.cc
@@ -33,7 +33,6 @@
 
 namespace {
 
-constexpr size_t kTaxonomySize = 349;
 constexpr int kTaxonomyVersion = 1;
 
 constexpr char kHost1[] = "www.foo1.com";
@@ -251,7 +250,6 @@
 
   EpochTopics result1 = CalculateTopics();
   EXPECT_FALSE(result1.empty());
-  EXPECT_EQ(result1.taxonomy_size(), kTaxonomySize);
   EXPECT_EQ(result1.taxonomy_version(), kTaxonomyVersion);
   EXPECT_EQ(result1.model_version(), 1);
   EXPECT_EQ(result1.calculation_time(), begin_time);
@@ -268,7 +266,7 @@
 
   EpochTopics result2 = CalculateTopics();
   EXPECT_FALSE(result2.empty());
-  EXPECT_EQ(result2.taxonomy_size(), kTaxonomySize);
+
   EXPECT_EQ(result2.taxonomy_version(), kTaxonomyVersion);
   EXPECT_EQ(result2.model_version(), 50);
   EXPECT_EQ(result2.calculation_time(), begin_time + base::Seconds(2));
diff --git a/components/browsing_topics/browsing_topics_service_impl_unittest.cc b/components/browsing_topics/browsing_topics_service_impl_unittest.cc
index 0384a23..1237c1a 100644
--- a/components/browsing_topics/browsing_topics_service_impl_unittest.cc
+++ b/components/browsing_topics/browsing_topics_service_impl_unittest.cc
@@ -59,7 +59,6 @@
 constexpr base::Time kTime2 =
     base::Time::FromDeltaSinceWindowsEpoch(base::Days(2));
 
-constexpr size_t kTaxonomySize = 349;
 constexpr int kTaxonomyVersion = 1;
 constexpr int64_t kModelVersion = 5000000000LL;
 
@@ -77,8 +76,8 @@
   }
 
   return EpochTopics(std::move(top_topics_and_observing_domains),
-                     padded_top_topics_start_index, kTaxonomySize,
-                     kTaxonomyVersion, model_version, calculation_time);
+                     padded_top_topics_start_index, kTaxonomyVersion,
+                     model_version, calculation_time);
 }
 
 }  // namespace
diff --git a/components/browsing_topics/browsing_topics_state_unittest.cc b/components/browsing_topics/browsing_topics_state_unittest.cc
index 982942f..b9b0312a 100644
--- a/components/browsing_topics/browsing_topics_state_unittest.cc
+++ b/components/browsing_topics/browsing_topics_state_unittest.cc
@@ -38,7 +38,6 @@
 constexpr browsing_topics::HmacKey kTestKey = {1};
 constexpr browsing_topics::HmacKey kTestKey2 = {2};
 
-constexpr size_t kTaxonomySize = 349;
 constexpr int kTaxonomyVersion = 1;
 constexpr int64_t kModelVersion = 2;
 constexpr size_t kPaddedTopTopicsStartIndex = 3;
@@ -57,8 +56,8 @@
       TopicAndDomains(Topic(5), {HashedDomain(1)}));
 
   EpochTopics epoch_topics(std::move(top_topics_and_observing_domains),
-                           kPaddedTopTopicsStartIndex, kTaxonomySize,
-                           kTaxonomyVersion, kModelVersion, calculation_time);
+                           kPaddedTopTopicsStartIndex, kTaxonomyVersion,
+                           kModelVersion, calculation_time);
 
   return epoch_topics;
 }
diff --git a/components/browsing_topics/common/semantic_tree.cc b/components/browsing_topics/common/semantic_tree.cc
index 447460d..d60788ec 100644
--- a/components/browsing_topics/common/semantic_tree.cc
+++ b/components/browsing_topics/common/semantic_tree.cc
@@ -4,6 +4,7 @@
 
 #include "components/browsing_topics/common/semantic_tree.h"
 
+#include "base/check_op.h"
 #include "components/strings/grit/components_strings.h"
 #include "third_party/blink/public/common/features.h"
 
@@ -418,11 +419,23 @@
   }
   return false;
 }
+
 }  // namespace
 
 SemanticTree::SemanticTree() = default;
 SemanticTree::~SemanticTree() = default;
 
+Topic SemanticTree::GetRandomTopic(int taxonomy_version,
+                                   uint64_t random_topic_index_decision) {
+  CHECK_EQ(taxonomy_version, 1);
+  size_t random_topic_index = random_topic_index_decision % kNumTopics;
+  return Topic(base::checked_cast<int>(random_topic_index + 1));
+}
+
+bool SemanticTree::IsTaxonomySupported(int taxonomy_version) {
+  return taxonomy_version == 1;
+}
+
 std::vector<Topic> SemanticTree::GetDescendantTopics(const Topic& topic) {
   std::vector<Topic> ret;
   for (size_t i = 0; i < kNumTopics; ++i) {
diff --git a/components/browsing_topics/common/semantic_tree.h b/components/browsing_topics/common/semantic_tree.h
index c23ad33..28aaa75c 100644
--- a/components/browsing_topics/common/semantic_tree.h
+++ b/components/browsing_topics/common/semantic_tree.h
@@ -22,6 +22,16 @@
   SemanticTree();
   SemanticTree(const SemanticTree& other) = delete;
   ~SemanticTree();
+
+  // Get a topic in taxonomy `taxonomy_version`. The result is deterministic.
+  // `random_topic_index_decision` % the taxonomy size is used to select
+  // the index of the topic in the taxonomy.
+  Topic GetRandomTopic(int taxonomy_version,
+                       uint64_t random_topic_index_decision);
+
+  // Get whether the `taxonomy_version` is supported by the semantic tree.
+  bool IsTaxonomySupported(int taxonomy_version);
+
   std::vector<Topic> GetDescendantTopics(const Topic& topic);
   std::vector<Topic> GetAncestorTopics(const Topic& topic);
   // Get the most recent localized name message id as of the version in
diff --git a/components/browsing_topics/common/semantic_tree_unittest.cc b/components/browsing_topics/common/semantic_tree_unittest.cc
index c36cd99..6b1c8b9 100644
--- a/components/browsing_topics/common/semantic_tree_unittest.cc
+++ b/components/browsing_topics/common/semantic_tree_unittest.cc
@@ -17,6 +17,34 @@
   SemanticTree semantic_tree_;
 };
 
+TEST_F(SemanticTreeUnittest, GetRandomTopic_ValidInput) {
+  Topic topic = semantic_tree_.GetRandomTopic(1, 3);
+  EXPECT_EQ(topic, Topic(4));
+}
+
+TEST_F(SemanticTreeUnittest, GetRandomTopic_ZeroSeedIsValid) {
+  Topic topic = semantic_tree_.GetRandomTopic(1, 0);
+  EXPECT_EQ(topic, Topic(1));
+}
+
+TEST_F(SemanticTreeUnittest, GetRandomTopic_SeedIsHigherThanTaxonomySize) {
+  Topic topic = semantic_tree_.GetRandomTopic(1, 400);
+  EXPECT_EQ(topic, Topic(52));
+}
+
+TEST_F(SemanticTreeUnittest, GetRandomTopic_InvalidTaxonomyVersion) {
+  EXPECT_CHECK_DEATH(semantic_tree_.GetRandomTopic(10, 400));
+}
+
+TEST_F(SemanticTreeUnittest, IsTaxonomySupported_ValidTaxonomyVersion) {
+  EXPECT_TRUE(semantic_tree_.IsTaxonomySupported(1));
+}
+
+TEST_F(SemanticTreeUnittest, IsTaxonomySupported_InvalidTaxonomyVersion) {
+  EXPECT_FALSE(semantic_tree_.IsTaxonomySupported(0));
+  EXPECT_FALSE(semantic_tree_.IsTaxonomySupported(100));
+}
+
 TEST_F(SemanticTreeUnittest, GetDescendantTopicsTopicNotInMap) {
   std::vector<Topic> topics = semantic_tree_.GetDescendantTopics(Topic(10000));
   EXPECT_TRUE(topics.empty());
diff --git a/components/browsing_topics/epoch_topics.cc b/components/browsing_topics/epoch_topics.cc
index e60edd4..b20a0cf 100644
--- a/components/browsing_topics/epoch_topics.cc
+++ b/components/browsing_topics/epoch_topics.cc
@@ -22,10 +22,10 @@
     "top_topics_and_observing_domains";
 const char kPaddedTopTopicsStartIndexNameKey[] =
     "padded_top_topics_start_index";
-const char kTaxonomySizeNameKey[] = "taxonomy_size";
 const char kTaxonomyVersionNameKey[] = "taxonomy_version";
 const char kModelVersionNameKey[] = "model_version";
 const char kCalculationTimeNameKey[] = "calculation_time";
+// `taxonomy_size` is a deprecated key. Do not reuse.
 
 bool ShouldUseRandomTopic(uint64_t random_or_top_topic_decision_hash) {
   return base::checked_cast<int>(random_or_top_topic_decision_hash % 100) <
@@ -40,14 +40,12 @@
 EpochTopics::EpochTopics(
     std::vector<TopicAndDomains> top_topics_and_observing_domains,
     size_t padded_top_topics_start_index,
-    size_t taxonomy_size,
     int taxonomy_version,
     int64_t model_version,
     base::Time calculation_time)
     : top_topics_and_observing_domains_(
           std::move(top_topics_and_observing_domains)),
       padded_top_topics_start_index_(padded_top_topics_start_index),
-      taxonomy_size_(taxonomy_size),
       taxonomy_version_(taxonomy_version),
       model_version_(model_version),
       calculation_time_(calculation_time) {
@@ -103,13 +101,6 @@
   size_t padded_top_topics_start_index =
       static_cast<size_t>(*padded_top_topics_start_index_value);
 
-  absl::optional<int> taxonomy_size_value =
-      dict_value.FindInt(kTaxonomySizeNameKey);
-  if (!taxonomy_size_value)
-    return EpochTopics(calculation_time);
-
-  size_t taxonomy_size = static_cast<size_t>(*taxonomy_size_value);
-
   absl::optional<int> taxonomy_version_value =
       dict_value.FindInt(kTaxonomyVersionNameKey);
   if (!taxonomy_version_value)
@@ -130,8 +121,8 @@
   int64_t model_version = *model_version_int64_value;
 
   return EpochTopics(std::move(top_topics_and_observing_domains),
-                     padded_top_topics_start_index, taxonomy_size,
-                     taxonomy_version, model_version, calculation_time);
+                     padded_top_topics_start_index, taxonomy_version,
+                     model_version, calculation_time);
 }
 
 base::Value::Dict EpochTopics::ToDictValue() const {
@@ -147,8 +138,6 @@
                   std::move(top_topics_and_observing_domains_list));
   result_dict.Set(kPaddedTopTopicsStartIndexNameKey,
                   base::checked_cast<int>(padded_top_topics_start_index_));
-  result_dict.Set(kTaxonomySizeNameKey,
-                  base::checked_cast<int>(taxonomy_size_));
   result_dict.Set(kTaxonomyVersionNameKey, taxonomy_version_);
   result_dict.Set(kModelVersionNameKey, base::Int64ToValue(model_version_));
   result_dict.Set(kCalculationTimeNameKey,
@@ -190,11 +179,8 @@
     uint64_t random_topic_index_decision =
         HashTopDomainForRandomTopicIndexDecision(hmac_key, calculation_time_,
                                                  top_domain);
-
-    size_t random_topic_index = random_topic_index_decision % taxonomy_size_;
-
-    Topic topic = Topic(base::checked_cast<int>(random_topic_index + 1));
-
+    Topic topic = SemanticTree().GetRandomTopic(taxonomy_version(),
+                                                random_topic_index_decision);
     return CandidateTopic::Create(topic, /*is_true_topic=*/false,
                                   should_be_filtered, taxonomy_version(),
                                   model_version());
diff --git a/components/browsing_topics/epoch_topics.h b/components/browsing_topics/epoch_topics.h
index 58e1e27a..99021f03 100644
--- a/components/browsing_topics/epoch_topics.h
+++ b/components/browsing_topics/epoch_topics.h
@@ -23,7 +23,6 @@
 
   EpochTopics(std::vector<TopicAndDomains> top_topics_and_observing_domains,
               size_t padded_top_topics_start_index,
-              size_t taxonomy_size,
               int taxonomy_version,
               int64_t model_version,
               base::Time calculation_time);
@@ -77,8 +76,6 @@
     return padded_top_topics_start_index_;
   }
 
-  size_t taxonomy_size() const { return taxonomy_size_; }
-
   int taxonomy_version() const { return taxonomy_version_; }
 
   int64_t model_version() const { return model_version_; }
@@ -112,9 +109,6 @@
   // `top_topics_and_observing_domains_.size()`.
   size_t padded_top_topics_start_index_ = 0;
 
-  // The size of the taxonomy applicable to this epoch's topics.
-  size_t taxonomy_size_ = 0;
-
   // The version of the taxonomy applicable to this epoch's topics.
   int taxonomy_version_ = 0;
 
diff --git a/components/browsing_topics/epoch_topics_unittest.cc b/components/browsing_topics/epoch_topics_unittest.cc
index 124dce5..5ae8ab3 100644
--- a/components/browsing_topics/epoch_topics_unittest.cc
+++ b/components/browsing_topics/epoch_topics_unittest.cc
@@ -34,8 +34,8 @@
       TopicAndDomains(Topic(100), {HashedDomain(1)}));
 
   EpochTopics epoch_topics(std::move(top_topics_and_observing_domains),
-                           kPaddedTopTopicsStartIndex, kTaxonomySize,
-                           kTaxonomyVersion, kModelVersion, kCalculationTime);
+                           kPaddedTopTopicsStartIndex, kTaxonomyVersion,
+                           kModelVersion, kCalculationTime);
 
   return epoch_topics;
 }
@@ -51,8 +51,8 @@
   }
 
   EpochTopics epoch_topics(std::move(top_topics_and_observing_domains),
-                           kPaddedTopTopicsStartIndex, kTaxonomySize,
-                           kTaxonomyVersion, kModelVersion, kCalculationTime);
+                           kPaddedTopTopicsStartIndex, kTaxonomyVersion,
+                           kModelVersion, kCalculationTime);
   EXPECT_FALSE(epoch_topics.empty());
 
   CandidateTopic candidate_topic = epoch_topics.CandidateTopicForSite(
diff --git a/components/browsing_topics/util.cc b/components/browsing_topics/util.cc
index 1ac8a41..bdf1b65 100644
--- a/components/browsing_topics/util.cc
+++ b/components/browsing_topics/util.cc
@@ -51,16 +51,6 @@
 
 }  // namespace
 
-absl::optional<size_t> GetTaxonomySize() {
-  if (blink::features::kBrowsingTopicsTaxonomyVersion.Get() == 1) {
-    // Taxonomy version 1 has 349 topics.
-    // https://github.com/jkarlin/topics/blob/main/taxonomy_v1.md
-    return 349;
-  }
-
-  return absl::nullopt;
-}
-
 HmacKey GenerateRandomHmacKey() {
   if (g_hmac_key_overridden)
     return GetHmacKeyOverrideForTesting();
diff --git a/components/browsing_topics/util.h b/components/browsing_topics/util.h
index 110f5c8..bbb7e6e 100644
--- a/components/browsing_topics/util.h
+++ b/components/browsing_topics/util.h
@@ -8,22 +8,12 @@
 #include "base/containers/span.h"
 #include "base/time/time.h"
 #include "components/browsing_topics/common/common_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace browsing_topics {
 
 using HmacKey = std::array<uint8_t, 32>;
 using ReadOnlyHmacKey = base::span<const uint8_t, 32>;
 
-// Get the size of the taxonomy. This is used for generating random topics from
-// [1, `GetTaxonomySize()`]. It returns nullopt if this Chrome binary does not
-// support the finch configured taxonomy version
-// `kBrowsingTopicsTaxonomyVersion`.
-//
-// TODO(yaoxia): this should be maintained by UX along with the string mappings.
-// Consider moving to a UX component.
-absl::optional<size_t> GetTaxonomySize();
-
 // Generate a 256 bit random hmac key.
 HmacKey GenerateRandomHmacKey();
 
diff --git a/components/crash/core/app/crashpad_android.cc b/components/crash/core/app/crashpad_android.cc
index bdd8bf6..af48568b 100644
--- a/components/crash/core/app/crashpad_android.cc
+++ b/components/crash/core/app/crashpad_android.cc
@@ -335,6 +335,8 @@
 #define CURRENT_ABI "x86_64"
 #elif defined(__aarch64__)
 #define CURRENT_ABI "arm64-v8a"
+#elif defined(__riscv) && (__riscv_xlen == 64)
+#define CURRENT_ABI "riscv64"
 #else
 #error "Unsupported target abi"
 #endif
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn
index 0c3e261..3542f2a7 100644
--- a/components/embedder_support/android/BUILD.gn
+++ b/components/embedder_support/android/BUILD.gn
@@ -262,6 +262,7 @@
 
 android_library("context_menu_java") {
   deps = [
+    "//base:base_java",
     "//base:jni_java",
     "//content/public/android:content_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/components/embedder_support/android/contextmenu/context_menu_builder.cc b/components/embedder_support/android/contextmenu/context_menu_builder.cc
index 3cae8ee..b2d62f9 100644
--- a/components/embedder_support/android/contextmenu/context_menu_builder.cc
+++ b/components/embedder_support/android/contextmenu/context_menu_builder.cc
@@ -6,7 +6,10 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
+#include "base/android/unguessable_token_android.h"
+#include "base/unguessable_token.h"
 #include "components/embedder_support/android/context_menu_jni_headers/ContextMenuParams_jni.h"
+#include "content/public/browser/android/impression_android.h"
 #include "content/public/browser/context_menu_params.h"
 #include "third_party/blink/public/common/context_menu_data/context_menu_data.h"
 #include "url/android/gurl_android.h"
@@ -16,7 +19,9 @@
 namespace context_menu {
 
 base::android::ScopedJavaGlobalRef<jobject> BuildJavaContextMenuParams(
-    const content::ContextMenuParams& params) {
+    const content::ContextMenuParams& params,
+    int initiator_process_id,
+    absl::optional<base::UnguessableToken> initiator_frame_token) {
   GURL sanitizedReferrer =
       (params.frame_url.is_empty() ? params.page_url : params.frame_url)
           .GetAsReferrer();
@@ -26,6 +31,14 @@
   std::u16string title_text =
       (params.title_text.empty() ? params.alt_text : params.title_text);
 
+  base::android::ScopedJavaLocalRef<jobject> impression;
+  if (initiator_frame_token && params.impression) {
+    impression = content::CreateJavaImpression(
+        env, params.impression->attribution_src_token.value(),
+        initiator_frame_token.value(), initiator_process_id,
+        params.impression->runtime_features);
+  }
+
   return base::android::ScopedJavaGlobalRef<jobject>(
       Java_ContextMenuParams_create(
           env, reinterpret_cast<intptr_t>(&params),
@@ -38,7 +51,8 @@
           ConvertUTF16ToJavaString(env, title_text),
           url::GURLAndroid::FromNativeGURL(env, sanitizedReferrer),
           static_cast<int>(params.referrer_policy), can_save, params.x,
-          params.y, params.source_type, params.opened_from_highlight));
+          params.y, params.source_type, params.opened_from_highlight,
+          impression));
 }
 
 content::ContextMenuParams* ContextMenuParamsFromJavaObject(
diff --git a/components/embedder_support/android/contextmenu/context_menu_builder.h b/components/embedder_support/android/contextmenu/context_menu_builder.h
index 1a0232be..685339f 100644
--- a/components/embedder_support/android/contextmenu/context_menu_builder.h
+++ b/components/embedder_support/android/contextmenu/context_menu_builder.h
@@ -6,6 +6,8 @@
 #define COMPONENTS_EMBEDDER_SUPPORT_ANDROID_CONTEXTMENU_CONTEXT_MENU_BUILDER_H_
 
 #include "base/android/scoped_java_ref.h"
+#include "base/unguessable_token.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 struct ContextMenuParams;
@@ -14,7 +16,10 @@
 namespace context_menu {
 
 base::android::ScopedJavaGlobalRef<jobject> BuildJavaContextMenuParams(
-    const content::ContextMenuParams& params);
+    const content::ContextMenuParams& params,
+    int initiator_process_id = 0,
+    absl::optional<base::UnguessableToken> initiator_frame_token =
+        absl::nullopt);
 
 content::ContextMenuParams* ContextMenuParamsFromJavaObject(
     const base::android::JavaRef<jobject>& jcontext_menu_params);
diff --git a/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuParams.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuParams.java
index 9175980..a584a870 100644
--- a/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuParams.java
+++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuParams.java
@@ -4,11 +4,13 @@
 
 package org.chromium.components.embedder_support.contextmenu;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.blink_public.common.ContextMenuDataMediaType;
+import org.chromium.content_public.browser.Impression;
 import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.content_public.common.Referrer;
 import org.chromium.ui.base.MenuSourceType;
@@ -41,6 +43,8 @@
 
     private final boolean mOpenedFromHighlight;
 
+    private final @Nullable Impression mImpression;
+
     @CalledByNative
     private long getNativePointer() {
         return mNativePtr;
@@ -166,17 +170,25 @@
     }
 
     /**
-     * @return Whether or not the context menu was opened from ighlight.
+     * @return Whether or not the context menu was opened from highlight.
      */
     public boolean getOpenedFromHighlight() {
         return mOpenedFromHighlight;
     }
 
+    /**
+     * @return The attribution impresssion associated with this Context Menu.
+     */
+    public Impression getImpression() {
+        return mImpression;
+    }
+
     @VisibleForTesting
     public ContextMenuParams(long nativePtr, @ContextMenuDataMediaType int mediaType, GURL pageUrl,
             GURL linkUrl, String linkText, GURL unfilteredLinkUrl, GURL srcUrl, String titleText,
             Referrer referrer, boolean canSaveMedia, int triggeringTouchXDp, int triggeringTouchYDp,
-            @MenuSourceType int sourceType, boolean openedFromHighlight) {
+            @MenuSourceType int sourceType, boolean openedFromHighlight,
+            @Nullable Impression impression) {
         mNativePtr = nativePtr;
         mPageUrl = pageUrl;
         mLinkUrl = linkUrl;
@@ -194,6 +206,7 @@
         mTriggeringTouchYDp = triggeringTouchYDp;
         mSourceType = sourceType;
         mOpenedFromHighlight = openedFromHighlight;
+        mImpression = impression;
     }
 
     @CalledByNative
@@ -201,13 +214,13 @@
             GURL pageUrl, GURL linkUrl, String linkText, GURL unfilteredLinkUrl, GURL srcUrl,
             String titleText, GURL sanitizedReferrer, int referrerPolicy, boolean canSaveMedia,
             int triggeringTouchXDp, int triggeringTouchYDp, @MenuSourceType int sourceType,
-            boolean openedFromHighlight) {
+            boolean openedFromHighlight, @Nullable Impression impression) {
         // TODO(https://crbug.com/783819): Convert Referrer to use GURL.
         Referrer referrer = sanitizedReferrer.isEmpty()
                 ? null
                 : new Referrer(sanitizedReferrer.getSpec(), referrerPolicy);
         return new ContextMenuParams(nativePtr, mediaType, pageUrl, linkUrl, linkText,
                 unfilteredLinkUrl, srcUrl, titleText, referrer, canSaveMedia, triggeringTouchXDp,
-                triggeringTouchYDp, sourceType, openedFromHighlight);
+                triggeringTouchYDp, sourceType, openedFromHighlight, impression);
     }
 }
diff --git a/components/feed/feed_feature_list.cc b/components/feed/feed_feature_list.cc
index 6e3c127b..055cef6 100644
--- a/components/feed/feed_feature_list.cc
+++ b/components/feed/feed_feature_list.cc
@@ -182,4 +182,8 @@
              "FeedDynamicColors",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+BASE_FEATURE(kFeedFollowUiUpdate,
+             "FeedFollowUiUpdate",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 }  // namespace feed
diff --git a/components/feed/feed_feature_list.h b/components/feed/feed_feature_list.h
index 0e07771..046dcaf 100644
--- a/components/feed/feed_feature_list.h
+++ b/components/feed/feed_feature_list.h
@@ -154,6 +154,9 @@
 // Feature that enables dynamic colors in the feed.
 BASE_DECLARE_FEATURE(kFeedDynamicColors);
 
+// Feature that enables UI update for Follow.
+BASE_DECLARE_FEATURE(kFeedFollowUiUpdate);
+
 }  // namespace feed
 
 #endif  // COMPONENTS_FEED_FEED_FEATURE_LIST_H_
diff --git a/components/gcm_driver/features.cc b/components/gcm_driver/features.cc
index 639e798..5345f95 100644
--- a/components/gcm_driver/features.cc
+++ b/components/gcm_driver/features.cc
@@ -19,14 +19,6 @@
              "GCMTokenInvalidAfterDays",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-BASE_FEATURE(kGCMIncludeAccountTokensInCheckinRequest,
-             "GCMIncludeAccountTokensInCheckinRequest",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kGCMReportAccountTokenChanges,
-             "GCMReportAccountTokenChanges",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 const char kParamNameTokenInvalidationPeriodDays[] =
     "token_invalidation_period";
 // A token invalidation period of 0 means the feature is disabled, and the
diff --git a/components/gcm_driver/features.h b/components/gcm_driver/features.h
index 0c11d37..889da7b 100644
--- a/components/gcm_driver/features.h
+++ b/components/gcm_driver/features.h
@@ -16,8 +16,6 @@
 namespace features {
 
 BASE_DECLARE_FEATURE(kInvalidateTokenFeature);
-BASE_DECLARE_FEATURE(kGCMIncludeAccountTokensInCheckinRequest);
-BASE_DECLARE_FEATURE(kGCMReportAccountTokenChanges);
 extern const char kParamNameTokenInvalidationPeriodDays[];
 
 // The period after which the GCM token becomes stale.
diff --git a/components/gcm_driver/gcm_account_mapper.cc b/components/gcm_driver/gcm_account_mapper.cc
index 2f84e38..7eb4b06 100644
--- a/components/gcm_driver/gcm_account_mapper.cc
+++ b/components/gcm_driver/gcm_account_mapper.cc
@@ -11,7 +11,6 @@
 #include "base/time/clock.h"
 #include "base/time/default_clock.h"
 #include "base/uuid.h"
-#include "components/gcm_driver/features.h"
 #include "components/gcm_driver/gcm_driver_desktop.h"
 #include "google_apis/gcm/engine/gcm_store.h"
 
@@ -107,38 +106,6 @@
       account_mapping->access_token = token_iter->access_token;
     }
   }
-
-  if (!base::FeatureList::IsEnabled(features::kGCMReportAccountTokenChanges)) {
-    return;
-  }
-
-  // Decide what to do with each account (either start mapping, or start
-  // removing).
-  for (auto mappings_iter = accounts_.begin(); mappings_iter != accounts_.end();
-       ++mappings_iter) {
-    if (mappings_iter->access_token.empty()) {
-      // Send a remove message if the account was not previously being removed,
-      // or it doesn't have a pending message, or the pending message is
-      // already expired, but OnSendError event was lost.
-      if (mappings_iter->status != AccountMapping::REMOVING ||
-          mappings_iter->last_message_id.empty() ||
-          IsLastStatusChangeOlderThanTTL(*mappings_iter)) {
-        SendRemoveMappingMessage(*mappings_iter);
-      }
-    } else {
-      // A message is sent for all of the mappings considered NEW, or mappings
-      // that are ADDING, but have expired message (OnSendError event lost), or
-      // for those mapped accounts that can be refreshed.
-      if (mappings_iter->status == AccountMapping::NEW ||
-          (mappings_iter->status == AccountMapping::ADDING &&
-           IsLastStatusChangeOlderThanTTL(*mappings_iter)) ||
-          (mappings_iter->status == AccountMapping::MAPPED &&
-           CanTriggerUpdate(mappings_iter->status_change_timestamp))) {
-        mappings_iter->last_message_id.clear();
-        SendAddMappingMessage(*mappings_iter);
-      }
-    }
-  }
 }
 
 void GCMAccountMapper::ShutdownHandler() {
diff --git a/components/gcm_driver/gcm_client_impl.cc b/components/gcm_driver/gcm_client_impl.cc
index 20ca3888..631be2c 100644
--- a/components/gcm_driver/gcm_client_impl.cc
+++ b/components/gcm_driver/gcm_client_impl.cc
@@ -663,14 +663,10 @@
   ToCheckinProtoVersion(chrome_build_info_, &chrome_build_proto);
 
   std::map<std::string, std::string> empty_account_tokens;
-  bool include_account_tokens = base::FeatureList::IsEnabled(
-      features::kGCMIncludeAccountTokensInCheckinRequest);
 
   CheckinRequest::RequestInfo request_info(
       device_checkin_info_.android_id, device_checkin_info_.secret,
-      include_account_tokens ? device_checkin_info_.account_tokens
-                             : empty_account_tokens,
-      gservices_settings_.digest(), chrome_build_proto);
+      empty_account_tokens, gservices_settings_.digest(), chrome_build_proto);
   checkin_request_ = std::make_unique<CheckinRequest>(
       gservices_settings_.GetCheckinURL(), request_info, GetGCMBackoffPolicy(),
       base::BindOnce(&GCMClientImpl::OnCheckinCompleted,
diff --git a/components/gcm_driver/gcm_client_impl_unittest.cc b/components/gcm_driver/gcm_client_impl_unittest.cc
index 82df70a..28e03c8d 100644
--- a/components/gcm_driver/gcm_client_impl_unittest.cc
+++ b/components/gcm_driver/gcm_client_impl_unittest.cc
@@ -1258,10 +1258,7 @@
 }
 
 // This test only checks that periodic checkin happens.
-TEST_F(GCMClientImplCheckinTest, CheckinWithAccountsEmptyWithFeature) {
-  scoped_feature_list().InitAndDisableFeature(
-      features::kGCMIncludeAccountTokensInCheckinRequest);
-
+TEST_F(GCMClientImplCheckinTest, CheckinWithAccountsEmpty) {
   std::map<std::string, std::string> settings;
   settings["checkin_interval"] = base::NumberToString(kSettingsCheckinInterval);
   settings["checkin_url"] = "http://alternative.url/checkin";
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h
index 655d924..674d0df 100644
--- a/components/history_clusters/core/config.h
+++ b/components/history_clusters/core/config.h
@@ -82,9 +82,8 @@
 
   // The `kJourneysImages` feature and child params.
 
-  // Whether to attempt to provide images for eligible Journeys (so far just
-  // a proof of concept implementation for Entities only).
-  bool images = false;
+  // Whether to attempt to provide images for eligible Journeys.
+  bool images = true;
 
   // Whether the image covers the whole icon container.
   bool images_cover = true;
diff --git a/components/history_clusters/core/features.cc b/components/history_clusters/core/features.cc
index fcb03ff..fc86dd54da 100644
--- a/components/history_clusters/core/features.cc
+++ b/components/history_clusters/core/features.cc
@@ -35,7 +35,7 @@
 
 BASE_FEATURE(kJourneysImages,
              "JourneysImages",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 const base::FeatureParam<bool> kJourneysImagesCover{
     &kJourneysImages, "JourneysImagesCover", true};
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc
index 5d8d86cc..7c72970 100644
--- a/components/omnibox/browser/autocomplete_controller.cc
+++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -391,7 +391,7 @@
 #endif
 
   // Create URL scoring signal annotators.
-  if (OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled() &&
+  if (OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled() &&
       OmniboxFieldTrial::AreScoringSignalsAnnotatorsEnabled()) {
     url_scoring_signals_annotators_.push_back(
         std::make_unique<HistoryScoringSignalsAnnotator>(
@@ -997,7 +997,7 @@
   // The additional signals in `result_` will be lost when `UpdateResult()` is
   // called again. Currently, `result_` is updated in each `UpdateResult()`
   // call.
-  if (OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled() &&
+  if (OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled() &&
       OmniboxFieldTrial::AreScoringSignalsAnnotatorsEnabled()) {
     for (const auto& annotator : url_scoring_signals_annotators_) {
       annotator->AnnotateResult(input_, &result_);
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc
index 81a913c..827a559668e 100644
--- a/components/omnibox/browser/autocomplete_match.cc
+++ b/components/omnibox/browser/autocomplete_match.cc
@@ -1427,7 +1427,7 @@
 
   // Merge scoring signals from duplicate match for ML model scoring and
   // training.
-  if (OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled()) {
+  if (OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled()) {
     MergeScoringSignals(duplicate_match);
   }
 }
diff --git a/components/omnibox/browser/bookmark_provider.cc b/components/omnibox/browser/bookmark_provider.cc
index 3fea1b9..47a1231 100644
--- a/components/omnibox/browser/bookmark_provider.cc
+++ b/components/omnibox/browser/bookmark_provider.cc
@@ -250,11 +250,11 @@
   int relevance = static_cast<int>(normalized_sum * kBookmarkScoreRange) +
                   kBaseBookmarkScore;
 
-  // If scoring signal logging is disabled, skip counting bookmarks if relevance
-  // is above max score. Don't waste any time searching for additional
-  // referenced URLs if we already have a perfect title match. Returns a pair of
-  // the relevance score and -1 as a dummy bookmark count.
-  if (!OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled() &&
+  // If scoring signal logging and ML scoring is disabled, skip counting
+  // bookmarks if relevance is above max score. Don't waste any time searching
+  // for additional referenced URLs if we already have a perfect title match.
+  // Returns a pair of the relevance score and -1 as a dummy bookmark count.
+  if (!OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled() &&
       relevance >= kMaxBookmarkScore) {
     return {relevance, /*bookmark_count=*/-1};
   }
diff --git a/components/omnibox/browser/history_quick_provider.cc b/components/omnibox/browser/history_quick_provider.cc
index 5ffdadab..28f2ad7d 100644
--- a/components/omnibox/browser/history_quick_provider.cc
+++ b/components/omnibox/browser/history_quick_provider.cc
@@ -361,7 +361,7 @@
     match.from_keyword = true;
   }
 
-  if (OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled() &&
+  if (OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled() &&
       AutocompleteScoringSignalsAnnotator::IsEligibleMatch(match)) {
     // Propagate scoring signals to AC Match for ML Model training data.
     // `allowed_to_be_default_match` is set in this function, after the ACMatch
diff --git a/components/omnibox/browser/history_url_provider.cc b/components/omnibox/browser/history_url_provider.cc
index 445154d..e0e41f8 100644
--- a/components/omnibox/browser/history_url_provider.cc
+++ b/components/omnibox/browser/history_url_provider.cc
@@ -753,7 +753,7 @@
 void HistoryURLProvider::PromoteMatchesIfNecessary(
     const HistoryURLProviderParams& params) {
   bool populate_scoring_signals =
-      OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled();
+      OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled();
   if (params.promote_type == HistoryURLProviderParams::NEITHER)
     return;
   if (params.promote_type == HistoryURLProviderParams::FRONT_HISTORY_MATCH) {
@@ -817,7 +817,7 @@
                                    ? 1
                                    : 0;
     bool populate_scoring_signals =
-        OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled();
+        OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled();
     for (size_t i = first_match; i < params->matches.size(); ++i) {
       // All matches score one less than the previous match.
       --relevance;
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index fa54ba4e9..56004cac 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -1016,11 +1016,17 @@
 
 // If true, enables scoring signal annotators for logging Omnibox scoring
 // signals to OmniboxEventProto.
-const base::FeatureParam<bool> kEnableScoringSignalsAnnotators(
+const base::FeatureParam<bool> kEnableScoringSignalsAnnotatorsForLogging(
     &omnibox::kLogUrlScoringSignals,
     "enable_scoring_signals_annotators",
     false);
 
+// If true, enables scoring signal annotators for ML scoring.
+const base::FeatureParam<bool> kEnableScoringSignalsAnnotatorsForMlScoring(
+    &omnibox::kMlUrlScoring,
+    "enable_scoring_signals_annotators_for_ml_scoring",
+    false);
+
 // If true, runs the ML scoring model but does not assign new relevance scores
 // to the URL suggestions and does not rerank them.
 const base::FeatureParam<bool> kMlUrlScoringCounterfactual(
@@ -1061,7 +1067,9 @@
 MLConfig::MLConfig() {
   log_url_scoring_signals =
       base::FeatureList::IsEnabled(omnibox::kLogUrlScoringSignals);
-  enable_scoring_signals_annotators = kEnableScoringSignalsAnnotators.Get();
+  enable_scoring_signals_annotators =
+      kEnableScoringSignalsAnnotatorsForLogging.Get() ||
+      kEnableScoringSignalsAnnotatorsForMlScoring.Get();
   ml_url_scoring = base::FeatureList::IsEnabled(omnibox::kMlUrlScoring);
   ml_batch_url_scoring = kMlBatchUrlScoring.Get();
   ml_url_scoring_counterfactual = kMlUrlScoringCounterfactual.Get();
@@ -1088,9 +1096,14 @@
   return GetMLConfigInternal();
 }
 
-bool IsLogUrlScoringSignalsEnabled() {
+bool IsReportingUrlScoringSignalsEnabled() {
   return GetMLConfig().log_url_scoring_signals;
 }
+
+bool IsPopulatingUrlScoringSignalsEnabled() {
+  return IsReportingUrlScoringSignalsEnabled() || IsMlUrlScoringEnabled();
+}
+
 bool AreScoringSignalsAnnotatorsEnabled() {
   return GetMLConfig().enable_scoring_signals_annotators;
 }
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index 955c3da..915231de 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -602,9 +602,8 @@
   // Equivalent to omnibox::kLogUrlScoringSignals.
   bool log_url_scoring_signals{false};
 
-  // If true, enables scoring signal annotators for logging Omnibox URL scoring
-  // signals to OmniboxEventProto. Equivalent to
-  // OmniboxFieldTrial::kLogUrlScoringSignalsEnableScoringSignalsAnnotators.
+  // If true, enables scoring signal annotators for populating additional
+  // Omnibox URL scoring signals for logging or ML scoring.
   bool enable_scoring_signals_annotators{false};
 
   // If true, runs the ML scoring model to assign new relevance scores to the
@@ -664,7 +663,10 @@
 
 // If enabled, logs Omnibox scoring signals to OmniboxEventProto for training
 // the ML scoring models.
-bool IsLogUrlScoringSignalsEnabled();
+bool IsReportingUrlScoringSignalsEnabled();
+
+// If enabled, populates scoring signals of URL matches.
+bool IsPopulatingUrlScoringSignalsEnabled();
 
 // Whether the scoring signal annotators are enabled for logging Omnibox scoring
 // signals to OmniboxEventProto.
diff --git a/components/omnibox/browser/omnibox_metrics_provider.cc b/components/omnibox/browser/omnibox_metrics_provider.cc
index d9b828e..7ea95ea 100644
--- a/components/omnibox/browser/omnibox_metrics_provider.cc
+++ b/components/omnibox/browser/omnibox_metrics_provider.cc
@@ -207,7 +207,7 @@
 
     // Scoring signals are not logged for search suggestions or in incognito
     // mode.
-    if (OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled() &&
+    if (OmniboxFieldTrial::IsReportingUrlScoringSignalsEnabled() &&
         !AutocompleteMatch::IsSearchType(i->type) && !log.is_incognito &&
         i->scoring_signals) {
       suggestion->mutable_scoring_signals()->CopyFrom(*i->scoring_signals);
diff --git a/components/omnibox/browser/scored_history_match.cc b/components/omnibox/browser/scored_history_match.cc
index f30f93a..cf3d908c 100644
--- a/components/omnibox/browser/scored_history_match.cc
+++ b/components/omnibox/browser/scored_history_match.cc
@@ -162,7 +162,7 @@
   // has been constructed via the no-args constructor.
   ScoredHistoryMatch::Init();
 
-  if (OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled()) {
+  if (OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled()) {
     // Populate the scoring signals available in the URL Row.
     scoring_signals = absl::make_optional<ScoringSignals>();
     scoring_signals->set_typed_count(row.typed_count());
@@ -715,7 +715,7 @@
   IncrementTitleMatchTermScores(terms_to_word_starts_offsets,
                                 word_starts.title_word_starts_, &term_scores);
 
-  if (OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled()) {
+  if (OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled()) {
     // Url matching signals.
     const auto url_matching_signals = ComputeUrlMatchingSignals(
         terms_to_word_starts_offsets, url, word_starts.url_word_starts_,
diff --git a/components/omnibox/browser/shortcuts_provider.cc b/components/omnibox/browser/shortcuts_provider.cc
index 217ab7f..2c1fc7f 100644
--- a/components/omnibox/browser/shortcuts_provider.cc
+++ b/components/omnibox/browser/shortcuts_provider.cc
@@ -197,7 +197,8 @@
   if (input.focus_type() == metrics::OmniboxFocusType::INTERACTION_DEFAULT &&
       input.type() != metrics::OmniboxInputType::EMPTY &&
       !input.text().empty() && initialized_) {
-    GetMatches(input, OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled());
+    GetMatches(input,
+               OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled());
   }
 }
 
diff --git a/components/omnibox/browser/titled_url_match_utils.cc b/components/omnibox/browser/titled_url_match_utils.cc
index f3f1014..4b7a5e6 100644
--- a/components/omnibox/browser/titled_url_match_utils.cc
+++ b/components/omnibox/browser/titled_url_match_utils.cc
@@ -147,7 +147,7 @@
     match.from_keyword = true;
   }
 
-  if (OmniboxFieldTrial::IsLogUrlScoringSignalsEnabled() &&
+  if (OmniboxFieldTrial::IsPopulatingUrlScoringSignalsEnabled() &&
       AutocompleteScoringSignalsAnnotator::IsEligibleMatch(match)) {
     match.scoring_signals = absl::make_optional<ScoringSignals>();
     // Populate ACMatches with signals for ML model scoring and training.
diff --git a/components/origin_trials/browser/origin_trials.cc b/components/origin_trials/browser/origin_trials.cc
index a06fcef8..a19e72ed 100644
--- a/components/origin_trials/browser/origin_trials.cc
+++ b/components/origin_trials/browser/origin_trials.cc
@@ -6,10 +6,12 @@
 
 #include <algorithm>
 
+#include "base/containers/contains.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "components/origin_trials/common/persisted_trial_token.h"
 #include "net/base/schemeful_site.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/common/origin_trials/origin_trials.h"
 #include "third_party/blink/public/common/origin_trials/trial_token.h"
 #include "third_party/blink/public/common/origin_trials/trial_token_result.h"
@@ -41,13 +43,13 @@
                                               current_time, absl::nullopt);
 }
 
-bool OriginTrials::IsTrialPersistedForOrigin(
+bool OriginTrials::IsFeaturePersistedForOrigin(
     const url::Origin& origin,
     const url::Origin& partition_origin,
-    const base::StringPiece trial_name,
+    blink::OriginTrialFeature feature,
     const base::Time current_time) {
   return !GetPersistedTrialsForOriginWithMatch(origin, partition_origin,
-                                               current_time, trial_name)
+                                               current_time, feature)
               .empty();
 }
 
@@ -97,30 +99,39 @@
             token, origin, script_origins, current_time);
 
     const blink::TrialToken* parsed_token = validation_result.ParsedToken();
-    if (validation_result.Status() == blink::OriginTrialTokenStatus::kSuccess &&
-        blink::origin_trials::IsTrialPersistentToNextResponse(
+
+    if (validation_result.Status() != blink::OriginTrialTokenStatus::kSuccess) {
+      continue;
+    }
+    if (!blink::origin_trials::IsTrialPersistentToNextResponse(
             parsed_token->feature_name())) {
-      if (parsed_token->is_third_party()) {
-        // TODO(crbug.com/1418340): Support for all third-party tokens.
-        // Only accept deprecation trials as third-party for now.
-        bool deprecation_trial = false;
-        for (const blink::OriginTrialFeature feature :
-             blink::origin_trials::FeaturesForTrial(
-                 parsed_token->feature_name())) {
-          deprecation_trial |= blink::origin_trials::GetTrialType(feature) ==
-                               blink::OriginTrialType::kDeprecation;
-        }
-        if (deprecation_trial) {
-          // Valid third-party tokens are saved using the origin stored in the
-          // token.
-          valid_tokens[parsed_token->origin()].push_back(
-              std::move(*parsed_token));
-        }
-      } else {
-        // First party tokens use the passed-in origin, since it could be a
-        // subdomain.
-        valid_tokens[origin].push_back(std::move(*parsed_token));
+      continue;
+    }
+    // TODO(crbug.com/1227440): Should be part of general validation logic.
+    if (!trial_token_validator_->TrialEnablesFeaturesForOS(
+            parsed_token->feature_name())) {
+      continue;
+    }
+    if (parsed_token->is_third_party()) {
+      // TODO(crbug.com/1418340): Support for all third-party tokens.
+      // Only accept deprecation trials as third-party for now.
+      bool deprecation_trial = false;
+      for (const blink::OriginTrialFeature feature :
+           blink::origin_trials::FeaturesForTrial(
+               parsed_token->feature_name())) {
+        deprecation_trial |= blink::origin_trials::GetTrialType(feature) ==
+                             blink::OriginTrialType::kDeprecation;
       }
+      if (deprecation_trial) {
+        // Valid third-party tokens are saved using the origin stored in the
+        // token.
+        valid_tokens[parsed_token->origin()].push_back(
+            std::move(*parsed_token));
+      }
+    } else {
+      // First party tokens use the passed-in origin, since it could be a
+      // subdomain.
+      valid_tokens[origin].push_back(std::move(*parsed_token));
     }
   }
   std::string partition_site = GetTokenPartitionSite(partition_origin);
@@ -134,7 +145,7 @@
     const url::Origin& origin,
     const url::Origin& partition_origin,
     const base::Time current_time,
-    const absl::optional<const base::StringPiece> trial_name_match) const {
+    const absl::optional<blink::OriginTrialFeature> trial_feature_match) const {
   if (origin.opaque())
     return {};
 
@@ -143,18 +154,25 @@
 
   base::flat_set<std::string> enabled_trials;
   for (const PersistedTrialToken& token : saved_tokens) {
-    if (!trial_name_match || token.trial_name == *trial_name_match) {
-      bool valid = trial_token_validator_->RevalidateTokenAndTrial(
-          token.trial_name, token.token_expiry, token.usage_restriction,
-          token.token_signature, current_time);
-      bool persistent = blink::origin_trials::IsTrialPersistentToNextResponse(
-          token.trial_name);
-      if (valid && persistent &&
-          token.partition_sites.contains(
-              GetTokenPartitionSite(partition_origin))) {
-        // Move the string into the flat_set to avoid extra heap allocations
-        enabled_trials.insert(std::move(token.trial_name));
-      }
+    if (trial_feature_match &&
+        // TODO(crbug.com/1227440): FeaturesEnabledByTrial should be part of
+        // general validation logic.
+        !base::Contains(
+            trial_token_validator_->FeaturesEnabledByTrial(token.trial_name),
+            trial_feature_match.value())) {
+      continue;
+    }
+
+    bool valid = trial_token_validator_->RevalidateTokenAndTrial(
+        token.trial_name, token.token_expiry, token.usage_restriction,
+        token.token_signature, current_time);
+    bool persistent =
+        blink::origin_trials::IsTrialPersistentToNextResponse(token.trial_name);
+    if (valid && persistent &&
+        token.partition_sites.contains(
+            GetTokenPartitionSite(partition_origin))) {
+      // Move the string into the flat_set to avoid extra heap allocations
+      enabled_trials.insert(std::move(token.trial_name));
     }
   }
 
diff --git a/components/origin_trials/browser/origin_trials.h b/components/origin_trials/browser/origin_trials.h
index 524d89e8..f405e46 100644
--- a/components/origin_trials/browser/origin_trials.h
+++ b/components/origin_trials/browser/origin_trials.h
@@ -17,6 +17,7 @@
 #include "components/origin_trials/common/persisted_trial_token.h"
 #include "content/public/browser/origin_trials_controller_delegate.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
 
 namespace url {
@@ -30,7 +31,7 @@
 // This class manages persistent origin trials, allowing the browser to check
 // if a given trial is enabled or not.
 //
-// Persisting the enabled trials is handled by the |persistence_provider| passed
+// Persisting the enabled trials is handled by the `persistence_provider` passed
 // in through the constructor.
 class OriginTrials : public KeyedService,
                      public content::OriginTrialsControllerDelegate {
@@ -58,10 +59,10 @@
       base::span<const url::Origin> script_origins,
       const base::span<const std::string> header_tokens,
       const base::Time current_time) override;
-  bool IsTrialPersistedForOrigin(const url::Origin& origin,
-                                 const url::Origin& partition_origin,
-                                 const base::StringPiece trial_name,
-                                 const base::Time current_time) override;
+  bool IsFeaturePersistedForOrigin(const url::Origin& origin,
+                                   const url::Origin& partition_origin,
+                                   blink::OriginTrialFeature feature,
+                                   const base::Time current_time) override;
   base::flat_set<std::string> GetPersistedTrialsForOrigin(
       const url::Origin& origin,
       const url::Origin& partition_origin,
@@ -81,19 +82,20 @@
                              bool append_only);
 
   // Helper to return the still-valid persisted trials, with an optional
-  // |trial_name_match| which can be passed to ensure we only validate
-  // and return the trial if it matches the passed name.
-  // If no |trial_name_match| is provided, it will return all persisted trials
-  // that are still valid.
+  // `trial_feature_match` which can be passed to ensure we only validate
+  // and return the trial if it enables the desired trial feature.
+  // If no `trial_feature_match` is provided, it will return all persisted
+  // trials that are still valid.
   base::flat_set<std::string> GetPersistedTrialsForOriginWithMatch(
       const url::Origin& origin,
       const url::Origin& partition_origin,
       const base::Time current_time,
-      const absl::optional<const base::StringPiece> trial_name_match) const;
+      const absl::optional<blink::OriginTrialFeature> trial_feature_match)
+      const;
 
-  // Update the stored tokens for |origin| with the |new_tokens|, partitioned by
-  // |partition_site|.
-  // Will clean any tokens not found in |new_tokens| unless |append_only| is set
+  // Update the stored tokens for `origin` with the `new_tokens`, partitioned by
+  // `partition_site`.
+  // Will clean any tokens not found in `new_tokens` unless `append_only` is set
   // to true.
   void UpdatePersistedTokenSet(const url::Origin& origin,
                                base::span<const blink::TrialToken> new_tokens,
@@ -102,7 +104,7 @@
 
   // Get the 'site' used as the partitioning key for trial tokens.
   //
-  // The key is the eTLD+1 of the |origin|, taking private registries such as
+  // The key is the eTLD+1 of the `origin`, taking private registries such as
   // blogspot.com into account.
   static std::string GetTokenPartitionSite(const url::Origin& origin);
 };
diff --git a/components/origin_trials/browser/origin_trials_unittest.cc b/components/origin_trials/browser/origin_trials_unittest.cc
index 272a76fa..791fe49 100644
--- a/components/origin_trials/browser/origin_trials_unittest.cc
+++ b/components/origin_trials/browser/origin_trials_unittest.cc
@@ -14,6 +14,7 @@
 #include "components/origin_trials/common/persisted_trial_token.h"
 #include "components/origin_trials/test/test_persistence_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/common/origin_trials/scoped_test_origin_trial_policy.h"
 #include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
 #include "url/gurl.h"
@@ -22,12 +23,10 @@
 namespace origin_trials {
 namespace {
 
+using blink::OriginTrialFeature;
+
 const char kPersistentTrialName[] = "FrobulatePersistent";
 const char kNonPersistentTrialName[] = "Frobulate";
-const char kPersistentExpiryPeriodTrialName[] =
-    "FrobulatePersistentExpiryGracePeriod";
-const char kPersistentThirdPartyDeprecationTrialName[] =
-    "FrobulatePersistentThirdPartyDeprecation";
 const char kInvalidTrialName[] = "InvalidTrial";
 const char kTrialEnabledOriginA[] = "https://enabled.example.com";
 const char kTrialEnabledOriginB[] = "https://enabled.alternate.com";
@@ -119,6 +118,13 @@
     "RlbnRUaGlyZFBhcnR5RGVwcmVjYXRpb24iLCAiZXhwaXJ5IjogMjAwMDAwMDAwMCwgImlzVGhp"
     "cmRQYXJ0eSI6IHRydWV9";
 
+const char kFrobulatePersistentInvalidOsToken[] =
+    "Az7+hGm6XhszDNmzi9/cLyLCjiciNqCrtlIilym1+wg6c/owVYMJtjSx7Xjf8MHHLs3gzB/"
+    "5D9/0PSSUOI/"
+    "ujwoAAABueyJvcmlnaW4iOiAiaHR0cHM6Ly9lbmFibGVkLmV4YW1wbGUuY29tOjQ0MyIsICJmZ"
+    "WF0dXJlIjogIkZyb2J1bGF0ZVBlcnNpc3RlbnRJbnZhbGlkT1MiLCAiZXhwaXJ5IjogMjAwMDA"
+    "wMDAwMH0=";
+
 class OpenScopedTestOriginTrialPolicy
     : public blink::ScopedTestOriginTrialPolicy {
  public:
@@ -189,12 +195,12 @@
         trial_origin, /* partition_origin */ trial_origin, lookup_time);
   }
 
-  // IsTrialPersistedForOrigin using |origin| as partition origin.
-  bool IsTrialPersistedForOrigin(const url::Origin& origin,
-                                 const std::string& trial_name,
-                                 base::Time lookup_time) {
-    return origin_trials_.IsTrialPersistedForOrigin(
-        origin, /* partition_origin */ origin, trial_name, lookup_time);
+  // IsFeaturePersistedForOrigin using |origin| as partition origin.
+  bool IsFeaturePersistedForOrigin(const url::Origin& origin,
+                                   blink::OriginTrialFeature feature,
+                                   base::Time lookup_time) {
+    return origin_trials_.IsFeaturePersistedForOrigin(
+        origin, /* partition_origin */ origin, feature, lookup_time);
   }
 
   std::string GetTokenPartitionSite(const url::Origin& origin) {
@@ -255,34 +261,54 @@
 }
 
 TEST_F(OriginTrialsTest, TrialNotEnabledByDefault) {
-  EXPECT_FALSE(IsTrialPersistedForOrigin(trial_enabled_origin_,
-                                         kPersistentTrialName, kValidTime));
+  EXPECT_FALSE(IsFeaturePersistedForOrigin(
+      trial_enabled_origin_,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 }
 
 TEST_F(OriginTrialsTest, TrialEnablesFeature) {
   std::vector<std::string> tokens = {kFrobulatePersistentToken};
   PersistTrialsFromTokens(trial_enabled_origin_, tokens, kValidTime);
 
-  EXPECT_TRUE(IsTrialPersistedForOrigin(trial_enabled_origin_,
-                                        kPersistentTrialName, kValidTime));
+  EXPECT_TRUE(IsFeaturePersistedForOrigin(
+      trial_enabled_origin_,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 }
 
 TEST_F(OriginTrialsTest, TrialDoesNotEnableOtherFeatures) {
   std::vector<std::string> tokens = {kFrobulatePersistentToken};
   PersistTrialsFromTokens(trial_enabled_origin_, tokens, kValidTime);
 
-  EXPECT_FALSE(IsTrialPersistedForOrigin(trial_enabled_origin_,
-                                         kNonPersistentTrialName, kValidTime));
+  EXPECT_FALSE(IsFeaturePersistedForOrigin(
+      trial_enabled_origin_, OriginTrialFeature::kOriginTrialsSampleAPI,
+      kValidTime));
+}
+
+TEST_F(OriginTrialsTest, TrialIsNotEnabledOrPersistedOnInvalidOs) {
+  std::vector<std::string> tokens = {kFrobulatePersistentInvalidOsToken};
+  PersistTrialsFromTokens(trial_enabled_origin_, tokens, kValidTime);
+
+  EXPECT_FALSE(IsFeaturePersistedForOrigin(
+      trial_enabled_origin_,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentInvalidOS,
+      kValidTime));
+
+  base::flat_set<std::string> enabled_trials =
+      GetPersistedTrialsForOrigin(trial_enabled_origin_, kValidTime);
+  ASSERT_TRUE(enabled_trials.empty());
 }
 
 TEST_F(OriginTrialsTest, TokensCanBeAppended) {
   std::vector<std::string> tokens = {kFrobulatePersistentToken};
   PersistTrialsFromTokens(trial_enabled_origin_, tokens, kValidTime);
 
-  EXPECT_TRUE(IsTrialPersistedForOrigin(trial_enabled_origin_,
-                                        kPersistentTrialName, kValidTime));
-  EXPECT_FALSE(IsTrialPersistedForOrigin(
-      trial_enabled_origin_, kPersistentExpiryPeriodTrialName, kValidTime));
+  EXPECT_TRUE(IsFeaturePersistedForOrigin(
+      trial_enabled_origin_,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
+  EXPECT_FALSE(IsFeaturePersistedForOrigin(
+      trial_enabled_origin_,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentExpiryGracePeriod,
+      kValidTime));
 
   // Append an additional token for the same origin
   std::vector<std::string> additional_tokens = {
@@ -291,10 +317,13 @@
       trial_enabled_origin_, /*partition_origin=*/trial_enabled_origin_,
       /*script_origins=*/{}, additional_tokens, kValidTime);
   // Check that both trials are now enabled
-  EXPECT_TRUE(IsTrialPersistedForOrigin(trial_enabled_origin_,
-                                        kPersistentTrialName, kValidTime));
-  EXPECT_TRUE(IsTrialPersistedForOrigin(
-      trial_enabled_origin_, kPersistentExpiryPeriodTrialName, kValidTime));
+  EXPECT_TRUE(IsFeaturePersistedForOrigin(
+      trial_enabled_origin_,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
+  EXPECT_TRUE(IsFeaturePersistedForOrigin(
+      trial_enabled_origin_,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentExpiryGracePeriod,
+      kValidTime));
 }
 
 TEST_F(OriginTrialsTest, ThirdPartyTokensCanBeAppendedOnlyIfDeprecation) {
@@ -313,15 +342,17 @@
 
   // The FrobulatePersistent should not be persisted, as it is not a deprecation
   // token.
-  EXPECT_FALSE(origin_trials_.IsTrialPersistedForOrigin(
+  EXPECT_FALSE(origin_trials_.IsFeaturePersistedForOrigin(
       script_origin, /*partition_origin=*/trial_enabled_origin_,
-      kPersistentTrialName, kValidTime));
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 
   // FrobulatePersistentThirdPartyDeprecation is a deprecation trial, and should
   // be enabled.
-  EXPECT_TRUE(origin_trials_.IsTrialPersistedForOrigin(
+  EXPECT_TRUE(origin_trials_.IsFeaturePersistedForOrigin(
       script_origin, /*partition_origin=*/trial_enabled_origin_,
-      kPersistentThirdPartyDeprecationTrialName, kValidTime));
+      OriginTrialFeature::
+          kOriginTrialsSampleAPIPersistentThirdPartyDeprecationFeature,
+      kValidTime));
 }
 
 // Check that a stored trial name is not returned if that trial is no longer
@@ -486,9 +517,10 @@
                                          /*partition_origin=*/opaque_origin,
                                          tokens, kValidTime);
 
-  EXPECT_TRUE(origin_trials_.IsTrialPersistedForOrigin(
+  EXPECT_TRUE(origin_trials_.IsFeaturePersistedForOrigin(
       trial_enabled_origin_, /*partition_origin=*/opaque_origin,
-      kPersistentTrialName, kValidTime));
+      blink::OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature,
+      kValidTime));
 }
 
 TEST_F(OriginTrialsTest, TokensArePartitionedByTopLevelSite) {
@@ -508,27 +540,33 @@
                                          kValidTime);
 
   // Only expect trials to be enabled for partitions where they have been set
-  EXPECT_TRUE(origin_trials_.IsTrialPersistedForOrigin(
-      origin_a, partition_site_a, kPersistentTrialName, kValidTime));
+  EXPECT_TRUE(origin_trials_.IsFeaturePersistedForOrigin(
+      origin_a, partition_site_a,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 
-  EXPECT_TRUE(origin_trials_.IsTrialPersistedForOrigin(
-      origin_a, partition_site_b, kPersistentTrialName, kValidTime));
+  EXPECT_TRUE(origin_trials_.IsFeaturePersistedForOrigin(
+      origin_a, partition_site_b,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 
-  EXPECT_TRUE(origin_trials_.IsTrialPersistedForOrigin(
-      origin_b, partition_site_b, kPersistentTrialName, kValidTime));
+  EXPECT_TRUE(origin_trials_.IsFeaturePersistedForOrigin(
+      origin_b, partition_site_b,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 
-  EXPECT_FALSE(origin_trials_.IsTrialPersistedForOrigin(
-      origin_b, partition_site_a, kPersistentTrialName, kValidTime));
+  EXPECT_FALSE(origin_trials_.IsFeaturePersistedForOrigin(
+      origin_b, partition_site_a,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 
   // Removing a token should only be from one partition
   origin_trials_.PersistTrialsFromTokens(origin_a, partition_site_b, {},
                                          kValidTime);
 
-  EXPECT_TRUE(origin_trials_.IsTrialPersistedForOrigin(
-      origin_a, partition_site_a, kPersistentTrialName, kValidTime));
+  EXPECT_TRUE(origin_trials_.IsFeaturePersistedForOrigin(
+      origin_a, partition_site_a,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 
-  EXPECT_FALSE(origin_trials_.IsTrialPersistedForOrigin(
-      origin_a, partition_site_b, kPersistentTrialName, kValidTime));
+  EXPECT_FALSE(origin_trials_.IsFeaturePersistedForOrigin(
+      origin_a, partition_site_b,
+      OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature, kValidTime));
 }
 
 TEST_F(OriginTrialsTest, PartitionSiteIsETLDPlusOne) {
diff --git a/components/page_image_service/features.cc b/components/page_image_service/features.cc
index 2e2735d..2e3f7f1 100644
--- a/components/page_image_service/features.cc
+++ b/components/page_image_service/features.cc
@@ -9,10 +9,10 @@
 // Enabled by default because we are only using this as a killswitch.
 BASE_FEATURE(kImageService, "ImageService", base::FEATURE_ENABLED_BY_DEFAULT);
 
-// Disabled by default because the usage of this is still not approved.
+// Enabled the capability by default, can be used as a killswitch.
 BASE_FEATURE(kImageServiceSuggestPoweredImages,
              "ImageServiceSuggestPoweredImages",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Enabled the capability by default, can be used as a killswitch.
 BASE_FEATURE(kImageServiceOptimizationGuideSalientImages,
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index b59c0cd..80722af0 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -230,6 +230,8 @@
     "psl_matching_helper.cc",
     "psl_matching_helper.h",
     "reauth_purpose.h",
+    "sharing_invitations.cc",
+    "sharing_invitations.h",
     "smart_bubble_stats_store.h",
     "sql_table_builder.cc",
     "sql_table_builder.h",
@@ -347,6 +349,7 @@
 
   if (!is_android && !is_ios) {
     sources += [ "password_manager_features_util_desktop.cc" ]
+    deps += [ "//components/webauthn/core/browser" ]
   } else {
     sources += [ "password_manager_features_util_mobile.cc" ]
   }
@@ -778,7 +781,10 @@
 
   if (!is_android && !is_ios) {
     sources += [ "password_strength_calculation_unittest.cc" ]
-    deps += [ "//components/password_manager/services/password_strength:lib" ]
+    deps += [
+      "//components/password_manager/services/password_strength:lib",
+      "//components/webauthn/core/browser:test_support",
+    ]
   }
 
   if (!is_android) {
diff --git a/components/password_manager/core/browser/DEPS b/components/password_manager/core/browser/DEPS
index f62158c..36d302d 100644
--- a/components/password_manager/core/browser/DEPS
+++ b/components/password_manager/core/browser/DEPS
@@ -22,7 +22,7 @@
   "+components/variations",
   "+components/variations/net",
   "+components/version_info",
-  "+components/webauthn/android",
+  "+components/webauthn",
   "+components/webdata/common",
   "+crypto",
   "+google_apis",
diff --git a/components/password_manager/core/browser/passkey_credential.cc b/components/password_manager/core/browser/passkey_credential.cc
index f0e46598..9318a4b 100644
--- a/components/password_manager/core/browser/passkey_credential.cc
+++ b/components/password_manager/core/browser/passkey_credential.cc
@@ -38,20 +38,23 @@
     }
     credentials.emplace_back(
         password_manager::PasskeyCredential::Source::kAndroidPhone,
-        passkey.rp_id(), ProtobufBytesToVector(passkey.credential_id()),
-        ProtobufBytesToVector(passkey.user_id()),
-        passkey.has_user_name() ? passkey.user_name() : "",
-        passkey.has_user_display_name() ? passkey.user_display_name() : "");
+        RpId(passkey.rp_id()),
+        CredentialId(ProtobufBytesToVector(passkey.credential_id())),
+        UserId(ProtobufBytesToVector(passkey.user_id())),
+        Username(passkey.has_user_name() ? passkey.user_name() : ""),
+        DisplayName(passkey.has_user_display_name()
+                        ? passkey.user_display_name()
+                        : ""));
   }
   return credentials;
 }
 
 PasskeyCredential::PasskeyCredential(Source source,
-                                     std::string rp_id,
-                                     std::vector<uint8_t> credential_id,
-                                     std::vector<uint8_t> user_id,
-                                     std::string username,
-                                     std::string display_name)
+                                     RpId rp_id,
+                                     CredentialId credential_id,
+                                     UserId user_id,
+                                     Username username,
+                                     DisplayName display_name)
     : source_(source),
       rp_id_(std::move(rp_id)),
       credential_id_(std::move(credential_id)),
diff --git a/components/password_manager/core/browser/passkey_credential.h b/components/password_manager/core/browser/passkey_credential.h
index 71005a94..9553b16 100644
--- a/components/password_manager/core/browser/passkey_credential.h
+++ b/components/password_manager/core/browser/passkey_credential.h
@@ -10,6 +10,8 @@
 #include <vector>
 
 #include "base/containers/span.h"
+#include "base/types/strong_alias.h"
+#include "components/sync/protocol/webauthn_credential_specifics.pb.h"
 
 namespace sync_pb {
 class WebauthnCredentialSpecifics;
@@ -28,15 +30,22 @@
     kOther,
   };
 
+  using RpId = base::StrongAlias<class RpIdTag, std::string>;
+  using CredentialId =
+      base::StrongAlias<class CredentialIdTag, std::vector<uint8_t>>;
+  using UserId = base::StrongAlias<class UserIdTag, std::vector<uint8_t>>;
+  using Username = base::StrongAlias<class UsernameTag, std::string>;
+  using DisplayName = base::StrongAlias<class DisplayNameTag, std::string>;
+
   static std::vector<PasskeyCredential> FromCredentialSpecifics(
       base::span<const sync_pb::WebauthnCredentialSpecifics> passkeys);
 
   PasskeyCredential(Source source,
-                    std::string rp_id,
-                    std::vector<uint8_t> credential_id,
-                    std::vector<uint8_t> user_id,
-                    std::string username = "",
-                    std::string display_name = "");
+                    RpId rp_id,
+                    CredentialId credential_id,
+                    UserId user_id,
+                    Username username = Username(""),
+                    DisplayName display_name = DisplayName(""));
   ~PasskeyCredential();
 
   PasskeyCredential(const PasskeyCredential&);
diff --git a/components/password_manager/core/browser/passkey_credential_unittest.cc b/components/password_manager/core/browser/passkey_credential_unittest.cc
index 3c0e52b..17615f89 100644
--- a/components/password_manager/core/browser/passkey_credential_unittest.cc
+++ b/components/password_manager/core/browser/passkey_credential_unittest.cc
@@ -74,16 +74,23 @@
           credential1_shadow,
       });
 
-  ASSERT_THAT(credentials,
-              testing::UnorderedElementsAre(
-                  PasskeyCredential(PasskeyCredential::Source::kAndroidPhone,
-                                    kRpId, ToUint8Vector(kCredentialIdShadow),
-                                    ToUint8Vector(kUserId1), kUserName1,
-                                    kUserDisplayName1),
-                  PasskeyCredential(PasskeyCredential::Source::kAndroidPhone,
-                                    kRpId, ToUint8Vector(kCredentialId2),
-                                    ToUint8Vector(kUserId2), kUserName2,
-                                    kUserDisplayName2)));
+  ASSERT_THAT(
+      credentials,
+      testing::UnorderedElementsAre(
+          PasskeyCredential(PasskeyCredential::Source::kAndroidPhone,
+                            PasskeyCredential::RpId(kRpId),
+                            PasskeyCredential::CredentialId(
+                                ToUint8Vector(kCredentialIdShadow)),
+                            PasskeyCredential::UserId(ToUint8Vector(kUserId1)),
+                            PasskeyCredential::Username(kUserName1),
+                            PasskeyCredential::DisplayName(kUserDisplayName1)),
+          PasskeyCredential(
+              PasskeyCredential::Source::kAndroidPhone,
+              PasskeyCredential::RpId(kRpId),
+              PasskeyCredential::CredentialId(ToUint8Vector(kCredentialId2)),
+              PasskeyCredential::UserId(ToUint8Vector(kUserId2)),
+              PasskeyCredential::Username(kUserName2),
+              PasskeyCredential::DisplayName(kUserDisplayName2))));
 }
 
 TEST_F(PasskeyCredentialTest, FromCredentialSpecifics_EmptyOptionalFields) {
@@ -96,8 +103,12 @@
   ASSERT_THAT(
       PasskeyCredential::FromCredentialSpecifics(std::vector{credential}),
       testing::UnorderedElementsAre(PasskeyCredential(
-          PasskeyCredential::Source::kAndroidPhone, kRpId,
-          ToUint8Vector(kCredentialId1), ToUint8Vector(kUserId1), "", "")));
+          PasskeyCredential::Source::kAndroidPhone,
+          PasskeyCredential::RpId(kRpId),
+          PasskeyCredential::CredentialId(ToUint8Vector(kCredentialId1)),
+          PasskeyCredential::UserId(ToUint8Vector(kUserId1)),
+          PasskeyCredential::Username(""),
+          PasskeyCredential::DisplayName(""))));
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
index 27b5daf..39a13e2 100644
--- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -2086,7 +2086,10 @@
   const std::string kNameUtf8 = "nadeshiko@example.com";
   const std::u16string kName = u"nadeshiko@example.com";
   PasskeyCredential passkey(PasskeyCredential::Source::kAndroidPhone,
-                            "example.com", kId, /*user_id=*/{}, kNameUtf8);
+                            PasskeyCredential::RpId("example.com"),
+                            PasskeyCredential::CredentialId(kId),
+                            PasskeyCredential::UserId(),
+                            PasskeyCredential::Username(kNameUtf8));
   EXPECT_CALL(client, GetWebAuthnCredentialsDelegateForDriver)
       .WillRepeatedly(Return(&webauthn_credentials_delegate));
   absl::optional<std::vector<PasskeyCredential>> passkey_list =
@@ -2198,10 +2201,12 @@
   password_autofill_manager_->OnAddPasswordFillData(data);
 
   // Enable WebAuthn autofill to return a credential.
-  PasskeyCredential passkey(PasskeyCredential::Source::kAndroidPhone,
-                            "rpid.com",
-                            /*credential_id=*/{1, 2, 3, 4},
-                            /*user_id=*/{1, 2, 3, 4}, "nadeshiko@example.com");
+  PasskeyCredential passkey(
+      PasskeyCredential::Source::kAndroidPhone,
+      PasskeyCredential::RpId("rpid.com"),
+      PasskeyCredential::CredentialId({1, 2, 3, 4}),
+      PasskeyCredential::UserId({1, 2, 3, 4}),
+      PasskeyCredential::Username("nadeshiko@example.com"));
   absl::optional<std::vector<PasskeyCredential>> passkeys =
       std::vector{std::move(passkey)};
   EXPECT_CALL(client, GetWebAuthnCredentialsDelegateForDriver)
diff --git a/components/password_manager/core/browser/password_list_sorter_unittest.cc b/components/password_manager/core/browser/password_list_sorter_unittest.cc
index 0b55d8e..2adcdce 100644
--- a/components/password_manager/core/browser/password_list_sorter_unittest.cc
+++ b/components/password_manager/core/browser/password_list_sorter_unittest.cc
@@ -245,8 +245,10 @@
   form.username_value = u"lora";
   CredentialUIEntry password(std::move(form));
 
-  PasskeyCredential passkey_credential(PasskeyCredential::Source::kAndroidPhone,
-                                       "test.com", {}, {}, "lora");
+  PasskeyCredential passkey_credential(
+      PasskeyCredential::Source::kAndroidPhone,
+      PasskeyCredential::RpId("test.com"), PasskeyCredential::CredentialId(),
+      PasskeyCredential::UserId(), PasskeyCredential::Username("lora"));
   CredentialUIEntry passkey(std::move(passkey_credential));
 
   EXPECT_NE(CreateSortKey(password), CreateSortKey(passkey));
diff --git a/components/password_manager/core/browser/sharing_invitations.cc b/components/password_manager/core/browser/sharing_invitations.cc
new file mode 100644
index 0000000..ee574a2
--- /dev/null
+++ b/components/password_manager/core/browser/sharing_invitations.cc
@@ -0,0 +1,51 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/password_manager/core/browser/sharing_invitations.h"
+
+namespace password_manager {
+
+IncomingSharingInvitation::IncomingSharingInvitation() = default;
+IncomingSharingInvitation::IncomingSharingInvitation(
+    const IncomingSharingInvitation& rhs) = default;
+IncomingSharingInvitation::IncomingSharingInvitation(
+    IncomingSharingInvitation&& rhs) = default;
+IncomingSharingInvitation& IncomingSharingInvitation::operator=(
+    const IncomingSharingInvitation& rhs) = default;
+IncomingSharingInvitation& IncomingSharingInvitation::operator=(
+    IncomingSharingInvitation&& rhs) = default;
+IncomingSharingInvitation::~IncomingSharingInvitation() = default;
+
+bool operator==(const IncomingSharingInvitation& lhs,
+                const IncomingSharingInvitation& rhs) {
+  return
+
+      lhs.url == lhs.url && lhs.username_element == rhs.username_element &&
+      lhs.username_value == rhs.username_value &&
+      lhs.password_element == rhs.password_element &&
+      lhs.signon_realm == rhs.signon_realm &&
+      lhs.password_value == rhs.password_value &&
+      lhs.sender_email == rhs.sender_email &&
+      lhs.date_created == rhs.date_created;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const IncomingSharingInvitation& invitation) {
+  return os << "IncomingSharingInvitation("
+            << "\nprimary_key: "
+            << invitation.primary_key.value_or(IncomingInvitationPrimaryKey(-1))
+            << "\nurl: " << invitation.url
+            << "\nusername_element: " << invitation.username_element
+            << "\nusername_value: " << invitation.username_value
+            << "\npassword_element: " << invitation.password_element
+            << "\nsignon_realm: " << invitation.signon_realm
+            << "\npassword_value: " << invitation.password_value
+            << "\nscheme: " << static_cast<int>(invitation.scheme)
+            << "\ndisplay_name: " << invitation.display_name
+            << "\nicon_url: " << invitation.icon_url
+            << "\nsender_email: " << invitation.sender_email
+            << "\ndate_created: " << invitation.date_created << "\n)\n";
+}
+
+}  // namespace password_manager
diff --git a/components/password_manager/core/browser/sharing_invitations.h b/components/password_manager/core/browser/sharing_invitations.h
new file mode 100644
index 0000000..1231d39
--- /dev/null
+++ b/components/password_manager/core/browser/sharing_invitations.h
@@ -0,0 +1,60 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SHARING_INVITATIONS_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SHARING_INVITATIONS_H_
+
+#include "base/time/time.h"
+#include "base/types/strong_alias.h"
+#include "components/password_manager/core/browser/password_form.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "url/gurl.h"
+
+namespace password_manager {
+
+// IncomingSharingInvitation primary key which is used in the database.
+using IncomingInvitationPrimaryKey =
+    base::StrongAlias<class IncomingInvitationPrimaryKeyTag, int>;
+
+// Represents a password sharing invitation received in the password manager.
+struct IncomingSharingInvitation {
+  IncomingSharingInvitation();
+  IncomingSharingInvitation(const IncomingSharingInvitation& rhs);
+  IncomingSharingInvitation(IncomingSharingInvitation&& rhs);
+  IncomingSharingInvitation& operator=(const IncomingSharingInvitation& rhs);
+  IncomingSharingInvitation& operator=(IncomingSharingInvitation&& rhs);
+  ~IncomingSharingInvitation();
+
+  // The primary key of the sharing invitation record in the logins database.
+  // This is only set when the invitation has been read from the login database.
+  absl::optional<IncomingInvitationPrimaryKey> primary_key;
+
+  // Those are aligned with the counterparts in the PasswordForm struct. Refer
+  // to password_form.h for documentation.
+  GURL url;
+  std::u16string username_element;
+  std::u16string username_value;
+  std::u16string password_element;
+  std::string signon_realm;
+  std::u16string password_value;
+  PasswordForm::Scheme scheme = PasswordForm::Scheme::kHtml;
+  std::u16string display_name;
+  GURL icon_url;
+  std::u16string sender_email;
+  base::Time date_created;
+};
+
+// For testing.
+#if defined(UNIT_TEST)
+bool operator==(const IncomingSharingInvitation& lhs,
+                const IncomingSharingInvitation& rhs);
+bool operator!=(const IncomingSharingInvitation& lhs,
+                const IncomingSharingInvitation& rhs);
+std::ostream& operator<<(std::ostream& os,
+                         const IncomingSharingInvitation& invitation);
+#endif
+
+}  // namespace password_manager
+
+#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SHARING_INVITATIONS_H_
diff --git a/components/password_manager/core/browser/ui/credential_ui_entry.cc b/components/password_manager/core/browser/ui/credential_ui_entry.cc
index 75dd0d8b..fee23322 100644
--- a/components/password_manager/core/browser/ui/credential_ui_entry.cc
+++ b/components/password_manager/core/browser/ui/credential_ui_entry.cc
@@ -121,7 +121,9 @@
 }
 
 CredentialUIEntry::CredentialUIEntry(const PasskeyCredential& passkey)
-    : is_passkey(true), username(base::UTF8ToUTF16(passkey.username())) {
+    : is_passkey(true),
+      username(base::UTF8ToUTF16(passkey.username())),
+      user_display_name(base::UTF8ToUTF16(passkey.display_name())) {
   CredentialFacet facet;
   facet.url = RPIDToURL(passkey.rp_id());
   facet.signon_realm = facet.url.possibly_invalid_spec();
diff --git a/components/password_manager/core/browser/ui/credential_ui_entry.h b/components/password_manager/core/browser/ui/credential_ui_entry.h
index 221fbb8..79cbc231 100644
--- a/components/password_manager/core/browser/ui/credential_ui_entry.h
+++ b/components/password_manager/core/browser/ui/credential_ui_entry.h
@@ -104,6 +104,9 @@
   // The current username.
   std::u16string username;
 
+  // The user's display name, if this is a passkey. Empty otherwise.
+  std::u16string user_display_name;
+
   // The current password.
   std::u16string password;
 
diff --git a/components/password_manager/core/browser/ui/credential_ui_entry_unittest.cc b/components/password_manager/core/browser/ui/credential_ui_entry_unittest.cc
index c9819ac..e516824 100644
--- a/components/password_manager/core/browser/ui/credential_ui_entry_unittest.cc
+++ b/components/password_manager/core/browser/ui/credential_ui_entry_unittest.cc
@@ -6,6 +6,8 @@
 
 #include <vector>
 
+#include "base/strings/utf_string_conversions.h"
+#include "components/password_manager/core/browser/passkey_credential.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -59,6 +61,7 @@
   CredentialUIEntry entry = CredentialUIEntry(form);
 
   unsigned long size = 1;
+  EXPECT_FALSE(entry.is_passkey);
   EXPECT_EQ(entry.facets.size(), size);
   EXPECT_EQ(entry.facets[0].signon_realm, "https://g.com/");
   EXPECT_EQ(entry.stored_in.size(), size);
@@ -120,6 +123,27 @@
   EXPECT_EQ(entry.blocked_by_user, false);
 }
 
+TEST(CredentialUIEntryTest, CredentialUIEntryFromPasskey) {
+  const std::vector<uint8_t> cred_id = {1, 2, 3, 4};
+  const std::vector<uint8_t> user_id = {5, 6, 7, 4};
+  const std::u16string kUsername = u"marisa";
+  const std::u16string kDisplayName = u"Marisa Kirisame";
+  PasskeyCredential passkey(
+      PasskeyCredential::Source::kAndroidPhone,
+      PasskeyCredential::RpId("rpid.com"),
+      PasskeyCredential::CredentialId(cred_id),
+      PasskeyCredential::UserId(user_id),
+      PasskeyCredential::Username(base::UTF16ToUTF8(kUsername)),
+      PasskeyCredential::DisplayName(base::UTF16ToUTF8(kDisplayName)));
+  CredentialUIEntry entry(passkey);
+  EXPECT_TRUE(entry.is_passkey);
+  EXPECT_EQ(entry.username, kUsername);
+  EXPECT_EQ(entry.user_display_name, kDisplayName);
+  ASSERT_EQ(entry.facets.size(), 1u);
+  EXPECT_EQ(entry.facets.at(0).url, GURL("https://rpid.com/"));
+  EXPECT_EQ(entry.facets.at(0).signon_realm, "https://rpid.com/");
+}
+
 TEST(CredentialUIEntryTest, TestGetAffiliatedDomains) {
   std::vector<PasswordForm> forms;
 
diff --git a/components/password_manager/core/browser/ui/passwords_grouper_unittest.cc b/components/password_manager/core/browser/ui/passwords_grouper_unittest.cc
index 0d14be5..33aaa20 100644
--- a/components/password_manager/core/browser/ui/passwords_grouper_unittest.cc
+++ b/components/password_manager/core/browser/ui/passwords_grouper_unittest.cc
@@ -31,9 +31,13 @@
 PasskeyCredential CreatePasskey(std::string rp_id,
                                 std::string username = "username",
                                 std::string display_name = "display_name") {
-  return PasskeyCredential(PasskeyCredential::Source::kAndroidPhone,
-                           std::move(rp_id), {1, 2, 3, 4}, {5, 6, 7, 8},
-                           std::move(username), std::move(display_name));
+  return PasskeyCredential(
+      PasskeyCredential::Source::kAndroidPhone,
+      PasskeyCredential::RpId(std::move(rp_id)),
+      PasskeyCredential::CredentialId({1, 2, 3, 4}),
+      PasskeyCredential::UserId({5, 6, 7, 8}),
+      PasskeyCredential::Username(std::move(username)),
+      PasskeyCredential::DisplayName(std::move(display_name)));
 }
 
 PasswordForm CreateForm(std::string signon_realm,
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
index 5ea26511..fe5a841 100644
--- a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
+++ b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
@@ -23,6 +23,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "components/password_manager/core/browser/form_parsing/form_parser.h"
 #include "components/password_manager/core/browser/import/csv_password.h"
+#include "components/password_manager/core/browser/passkey_credential.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_list_sorter.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
@@ -32,6 +33,7 @@
 #include "components/password_manager/core/browser/ui/passwords_grouper.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/sync/base/features.h"
+#include "components/webauthn/core/browser/passkey_model.h"
 #include "url/gurl.h"
 
 namespace {
@@ -99,9 +101,11 @@
 SavedPasswordsPresenter::SavedPasswordsPresenter(
     AffiliationService* affiliation_service,
     scoped_refptr<PasswordStoreInterface> profile_store,
-    scoped_refptr<PasswordStoreInterface> account_store)
+    scoped_refptr<PasswordStoreInterface> account_store,
+    PasskeyModel* passkey_store)
     : profile_store_(std::move(profile_store)),
       account_store_(std::move(account_store)),
+      passkey_store_(passkey_store),
       undo_helper_(std::make_unique<PasswordUndoHelper>(profile_store_.get(),
                                                         account_store_.get())),
       passwords_grouper_(
@@ -143,6 +147,7 @@
 
 bool SavedPasswordsPresenter::RemoveCredential(
     const CredentialUIEntry& credential) {
+  // TODO(crbug.com/1432717): support passkeys.
   std::vector<PasswordForm> forms_to_delete =
       GetCorrespondingPasswordForms(credential);
   undo_helper_->StartGroupingActions();
@@ -289,6 +294,7 @@
     const CredentialUIEntry& updated_credential) {
   std::vector<PasswordForm> forms_to_change =
       GetCorrespondingPasswordForms(original_credential);
+  // TODO(crbug.com/1432717): support passkeys.
   if (forms_to_change.empty())
     return EditResult::kNotFound;
 
@@ -430,7 +436,8 @@
     const {
   auto credentials = GetSavedCredentials();
   base::EraseIf(credentials, [](const auto& credential) {
-    return credential.blocked_by_user || !credential.federation_origin.opaque();
+    return credential.is_passkey || credential.blocked_by_user ||
+           !credential.federation_origin.opaque();
   });
   return credentials;
 }
@@ -600,9 +607,16 @@
     all_forms.push_back(form);
   }
 
+  // Passkeys are collected synchronously.
+  std::vector<PasskeyCredential> passkeys;
+  if (passkey_store_) {
+    passkeys = PasskeyCredential::FromCredentialSpecifics(
+        passkey_store_->GetAllPasskeys());
+  }
+
   // Notify observers after grouping is complete.
   passwords_grouper_->GroupCredentials(
-      std::move(all_forms), /*passkeys=*/{},
+      std::move(all_forms), std::move(passkeys),
       metrics_util::TimeCallback(std::move(completion),
                                  "PasswordManager.PasswordsGrouping.Time"));
 }
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter.h b/components/password_manager/core/browser/ui/saved_passwords_presenter.h
index 2699210..3a1430a7 100644
--- a/components/password_manager/core/browser/ui/saved_passwords_presenter.h
+++ b/components/password_manager/core/browser/ui/saved_passwords_presenter.h
@@ -18,6 +18,7 @@
 #include "components/password_manager/core/browser/password_store_consumer.h"
 #include "components/password_manager/core/browser/ui/affiliated_group.h"
 #include "components/password_manager/core/browser/ui/credential_ui_entry.h"
+#include "components/webauthn/core/browser/passkey_model.h"
 
 namespace password_manager {
 
@@ -105,7 +106,8 @@
 
   SavedPasswordsPresenter(AffiliationService* affiliation_service,
                           scoped_refptr<PasswordStoreInterface> profile_store,
-                          scoped_refptr<PasswordStoreInterface> account_store);
+                          scoped_refptr<PasswordStoreInterface> account_store,
+                          PasskeyModel* passkey_store = nullptr);
   ~SavedPasswordsPresenter() override;
 
   SavedPasswordsPresenter(const SavedPasswordsPresenter&) = delete;
@@ -166,11 +168,11 @@
       metrics_util::MoveToAccountStoreTrigger trigger);
 
   // Returns a list of unique passwords which includes normal credentials,
-  // federated credentials and blocked forms. If a same form is present both on
-  // account and profile stores it will be represented as a single entity.
-  // Uniqueness is determined using site name, username, password. For Android
-  // credentials package name is also taken into account and for Federated
-  // credentials federation origin.
+  // federated credentials, passkeys, and blocked forms. If a same form is
+  // present both on account and profile stores it will be represented as a
+  // single entity. Uniqueness is determined using site name, username,
+  // password. For Android credentials package name is also taken into account
+  // and for Federated credentials federation origin.
   std::vector<CredentialUIEntry> GetSavedCredentials() const;
 
   // Returns a list of affiliated groups for the Password Manager.
@@ -235,6 +237,10 @@
   scoped_refptr<PasswordStoreInterface> profile_store_;
   scoped_refptr<PasswordStoreInterface> account_store_;
 
+  // Store containing account passkeys. This may be null if the feature is
+  // disabled.
+  raw_ptr<PasskeyModel> passkey_store_;
+
   // The number of stores from which no updates have been received yet.
   int pending_store_updates_ = 0;
 
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc b/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc
index 686b59b..31a3b68 100644
--- a/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc
+++ b/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc
@@ -4,11 +4,13 @@
 
 #include "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
 
+#include <array>
 #include <string>
 #include <utility>
 
 #include "base/containers/flat_map.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/rand_util.h"
 #include "base/scoped_observation.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
@@ -24,6 +26,7 @@
 #include "components/password_manager/core/browser/affiliation/mock_affiliation_service.h"
 #include "components/password_manager/core/browser/fake_password_store_backend.h"
 #include "components/password_manager/core/browser/mock_password_store_interface.h"
+#include "components/password_manager/core/browser/passkey_credential.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_store.h"
@@ -32,9 +35,17 @@
 #include "components/password_manager/core/browser/ui/credential_ui_entry.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/sync/base/features.h"
+#include "components/sync/protocol/webauthn_credential_specifics.pb.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+// components/webauthn/core is a desktop-only dependency of
+// components/password_manager/core. gn cannot parse the preprocessor directive
+// above when checking includes, so we need nogncheck here.
+#include "components/webauthn/core/browser/test_passkey_model.h"  // nogncheck
+#endif
+
 namespace password_manager {
 
 namespace {
@@ -59,6 +70,33 @@
 using StrictMockSavedPasswordsPresenterObserver =
     ::testing::StrictMock<MockSavedPasswordsPresenterObserver>;
 
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+constexpr char kPasskeyCredentialId[] = "abcd";
+constexpr char kPasskeyRPID[] = "passkeys.com";
+constexpr char kPasskeyUserId[] = "1234";
+constexpr char kPasskeyUsername[] = "hmiku";
+constexpr char kPasskeyUserDisplayName[] = "Hatsune Miku";
+constexpr char kPasskeyFacet[] = "https://passkeys.com";
+
+sync_pb::WebauthnCredentialSpecifics CreateTestPasskey() {
+  sync_pb::WebauthnCredentialSpecifics credential;
+  credential.set_sync_id(base::RandBytesAsString(16));
+  credential.set_credential_id(kPasskeyCredentialId);
+  credential.set_rp_id(kPasskeyRPID);
+  credential.set_user_id(kPasskeyUserId);
+  credential.set_user_name(kPasskeyUsername);
+  credential.set_user_display_name(kPasskeyUserDisplayName);
+  return credential;
+}
+
+CredentialUIEntry AsCredentialUIEntry(
+    sync_pb::WebauthnCredentialSpecifics passkey) {
+  return CredentialUIEntry(
+      PasskeyCredential::FromCredentialSpecifics(std::array{std::move(passkey)})
+          .at(0));
+}
+#endif
+
 class SavedPasswordsPresenterTest : public testing::TestWithParam<bool> {
  protected:
   void SetUp() override {
@@ -78,6 +116,9 @@
   }
 
   TestPasswordStore& store() { return *store_; }
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+  TestPasskeyModel& passkey_store() { return test_passkey_store_; }
+#endif
   SavedPasswordsPresenter& presenter() { return presenter_; }
 
   void RunUntilIdle() { task_env_.RunUntilIdle(); }
@@ -92,8 +133,15 @@
   scoped_refptr<TestPasswordStore> store_ =
       base::MakeRefCounted<TestPasswordStore>();
   FakeAffiliationService affiliation_service_;
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+  TestPasskeyModel test_passkey_store_;
+  SavedPasswordsPresenter presenter_{&affiliation_service_, store_,
+                                     /*account_store=*/nullptr,
+                                     &test_passkey_store_};
+#else
   SavedPasswordsPresenter presenter_{&affiliation_service_, store_,
                                      /*account_store=*/nullptr};
+#endif
 };
 
 password_manager::PasswordForm CreateTestPasswordForm(
@@ -796,6 +844,103 @@
   }
 }
 
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+TEST_P(SavedPasswordsPresenterTest, GetSavedCredentialsWithPasskeys) {
+  // Password grouping is required for passkey support.
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      password_manager::features::kPasswordsGrouping);
+  PasswordForm form =
+      CreateTestPasswordForm(PasswordForm::Store::kProfileStore);
+
+  PasswordForm blocked_form;
+  blocked_form.signon_realm = form.signon_realm;
+  blocked_form.blocked_by_user = true;
+  blocked_form.in_store = PasswordForm::Store::kProfileStore;
+
+  PasswordForm federated_form;
+  federated_form.url = GURL("https://federated.com");
+  federated_form.signon_realm = "federation://federated.com/idp.com";
+  federated_form.username_value = u"example@gmail.com";
+  federated_form.federation_origin =
+      url::Origin::Create(GURL("federation-origin.com"));
+  federated_form.in_store = PasswordForm::Store::kProfileStore;
+
+  sync_pb::WebauthnCredentialSpecifics passkey = CreateTestPasskey();
+  passkey_store().AddNewPasskeyForTesting(passkey);
+
+  store().AddLogin(form);
+  store().AddLogin(blocked_form);
+  store().AddLogin(federated_form);
+  RunUntilIdle();
+
+  ASSERT_THAT(
+      store().stored_passwords(),
+      UnorderedElementsAre(
+          Pair(form.signon_realm, UnorderedElementsAre(form, blocked_form)),
+          Pair(federated_form.signon_realm, ElementsAre(federated_form))));
+
+  // GetAllSavedCredentials should return all credentials.
+  EXPECT_THAT(presenter().GetSavedCredentials(),
+              UnorderedElementsAre(CredentialUIEntry(form),
+                                   CredentialUIEntry(federated_form),
+                                   AsCredentialUIEntry(std::move(passkey))));
+}
+
+TEST_P(SavedPasswordsPresenterTest, GetAffiliatedGroupsWithPasskeys) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      password_manager::features::kPasswordsGrouping);
+
+  MockAffiliationService mock_affiliation_service;
+  SavedPasswordsPresenter presenter{&mock_affiliation_service, &store(),
+                                    nullptr, &passkey_store()};
+  presenter.Init();
+  RunUntilIdle();
+
+  PasswordForm form1 =
+      CreateTestPasswordForm(PasswordForm::Store::kProfileStore);
+  PasswordForm form2 =
+      CreateTestPasswordForm(PasswordForm::Store::kProfileStore, 1);
+  PasswordForm form3 =
+      CreateTestPasswordForm(PasswordForm::Store::kProfileStore, 2);
+
+  sync_pb::WebauthnCredentialSpecifics passkey = CreateTestPasskey();
+  passkey_store().AddNewPasskeyForTesting(passkey);
+
+  store().AddLogin(form1);
+  store().AddLogin(form2);
+  store().AddLogin(form3);
+
+  std::vector<password_manager::GroupedFacets> grouped_facets(2);
+  grouped_facets[0].facets = {
+      Facet(FacetURI::FromPotentiallyInvalidSpec(form1.signon_realm)),
+      Facet(FacetURI::FromPotentiallyInvalidSpec(form2.signon_realm)),
+      Facet(FacetURI::FromPotentiallyInvalidSpec(kPasskeyFacet))};
+  grouped_facets[0].branding_info.name = "Group 1";
+  grouped_facets[0].branding_info.icon_url =
+      GURL("https://test1.com/favicon.ico");
+  grouped_facets[1].facets = {
+      Facet(FacetURI::FromPotentiallyInvalidSpec(form3.signon_realm))};
+  grouped_facets[1].branding_info.name = "Group 2";
+  grouped_facets[1].branding_info.icon_url =
+      GURL("https://test3.com/favicon.ico");
+  EXPECT_CALL(mock_affiliation_service, GetGroupingInfo)
+      .WillRepeatedly(base::test::RunOnceCallback<1>(grouped_facets));
+  RunUntilIdle();
+
+  CredentialUIEntry credential1(form1), credential2(form2), credential3(form3);
+  EXPECT_THAT(
+      presenter.GetAffiliatedGroups(),
+      UnorderedElementsAre(
+          AffiliatedGroup({credential1, credential2,
+                           AsCredentialUIEntry(std::move(passkey))},
+                          grouped_facets[0].branding_info),
+          AffiliatedGroup({credential3}, grouped_facets[1].branding_info)));
+}
+
+#endif
+
 TEST_P(SavedPasswordsPresenterTest, UndoRemoval) {
   PasswordForm form =
       CreateTestPasswordForm(PasswordForm::Store::kProfileStore);
@@ -1433,7 +1578,7 @@
   base::HistogramTester histogram_tester;
   MockAffiliationService mock_affiliation_service;
   SavedPasswordsPresenter presenter{&mock_affiliation_service, &store(),
-                                    nullptr};
+                                    nullptr, /*passkey_store=*/nullptr};
   presenter.Init();
   RunUntilIdle();
 
@@ -1688,7 +1833,7 @@
 
 TEST_F(SavedPasswordsPresenterInitializationTest, InitWithOneStore) {
   SavedPasswordsPresenter presenter{&affiliation_service(), profile_store(),
-                                    nullptr};
+                                    /*account_store=*/nullptr};
 
   EXPECT_FALSE(presenter.IsWaitingForPasswordStore());
 
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
index 6d48222f..3df758b 100644
--- a/components/password_manager/core/common/password_manager_features.cc
+++ b/components/password_manager/core/common/password_manager_features.cc
@@ -307,6 +307,13 @@
              "PasswordGenerationPreviewOnHover",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)  // Desktop
+// Show, update, and delete GPM passkeys on the Chrome Password Manager.
+BASE_FEATURE(kPasswordManagerPasskeys,
+             "PasswordManagerPasskeys",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+#endif
+
 #if BUILDFLAG(IS_ANDROID)
 
 // The string version to use for the save/update password prompts when the user
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h
index 7dd5e0a..d09b767 100644
--- a/components/password_manager/core/common/password_manager_features.h
+++ b/components/password_manager/core/common/password_manager_features.h
@@ -93,6 +93,9 @@
 BASE_DECLARE_FEATURE(kUsernameFirstFlowFallbackCrowdsourcing);
 BASE_DECLARE_FEATURE(kUsernameFirstFlowHonorAutocomplete);
 BASE_DECLARE_FEATURE(kPasswordGenerationPreviewOnHover);
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)  // Desktop
+BASE_DECLARE_FEATURE(kPasswordManagerPasskeys);
+#endif
 
 // All features parameters are in alphabetical order.
 
diff --git a/components/performance_manager/features.cc b/components/performance_manager/features.cc
index 9343d5c..8d26a4d4 100644
--- a/components/performance_manager/features.cc
+++ b/components/performance_manager/features.cc
@@ -126,6 +126,10 @@
     &kDiscardedTabTreatment, "discard_tab_treatment_option",
     static_cast<int>(DiscardTabTreatmentOptions::kFadeFullsizedFavicon)};
 
+const base::FeatureParam<int> kMemoryUsageInHovercardsHighThresholdBytes{
+    &kMemoryUsageInHovercards,
+    "memory_usage_in_hovercards_high_threshold_bytes", 800 * 1024 * 1024};
+
 BASE_FEATURE(kUseDeviceBatterySaverChromeOS,
              "UseDeviceBatterySaverChromeOS",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/performance_manager/public/features.h b/components/performance_manager/public/features.h
index 0943715..afa6852 100644
--- a/components/performance_manager/public/features.h
+++ b/components/performance_manager/public/features.h
@@ -184,6 +184,9 @@
 // The version of the tab discard treatment on the favicon should be shown
 extern const base::FeatureParam<int> kDiscardedTabTreatmentOption;
 
+// Threshold for when memory usage is labeled as "high".
+extern const base::FeatureParam<int> kMemoryUsageInHovercardsHighThresholdBytes;
+
 BASE_DECLARE_FEATURE(kUseDeviceBatterySaverChromeOS);
 
 enum class DiscardTabTreatmentOptions {
diff --git a/components/policy/core/browser/android/policy_cache_updater_android_unittest.cc b/components/policy/core/browser/android/policy_cache_updater_android_unittest.cc
index 916c5ddc..fee7b22 100644
--- a/components/policy/core/browser/android/policy_cache_updater_android_unittest.cc
+++ b/components/policy/core/browser/android/policy_cache_updater_android_unittest.cc
@@ -80,7 +80,7 @@
         true /* is_first_policy_load_complete_return */);
     j_support_ = Java_PolicyCacheUpdaterTestSupporter_Constructor(env_);
     policy_service_ = std::make_unique<policy::PolicyServiceImpl>(
-        std::vector<ConfigurationPolicyProvider*>({&policy_provider_}));
+        std::vector<ConfigurationPolicyProvider*>{&policy_provider_});
     policy_handler_list_ = std::make_unique<ConfigurationPolicyHandlerList>(
         ConfigurationPolicyHandlerList::
             PopulatePolicyHandlerParametersCallback(),
diff --git a/components/policy/core/common/features.cc b/components/policy/core/common/features.cc
index cf0390b..ab26bc7 100644
--- a/components/policy/core/common/features.cc
+++ b/components/policy/core/common/features.cc
@@ -29,7 +29,7 @@
 
 BASE_FEATURE(kSafeSitesFilterBehaviorPolicyAndroid,
              "SafeSitesFilterBehaviorPolicyAndroid",
-             base::FEATURE_ENABLED_BY_DEFAULT);
+             base::FEATURE_DISABLED_BY_DEFAULT);
 #endif  // BUILDFLAG(IS_ANDROID)
 
 BASE_FEATURE(kPolicyMergeMultiSource,
diff --git a/components/policy/resources/templates/policy_definitions/Extensions/ExtensionInstallForcelist.yaml b/components/policy/resources/templates/policy_definitions/Extensions/ExtensionInstallForcelist.yaml
index 1ecca2f..fd305b77 100644
--- a/components/policy/resources/templates/policy_definitions/Extensions/ExtensionInstallForcelist.yaml
+++ b/components/policy/resources/templates/policy_definitions/Extensions/ExtensionInstallForcelist.yaml
@@ -14,7 +14,7 @@
 
         The source code of any extension may be altered by users through developer tools, potentially rendering the extension dysfunctional. If this is a concern, set the <ph name="DEVELOPER_TOOLS_DISABLED_POLICY_NAME">DeveloperToolsDisabled</ph> policy.
 
-        Each list item of the policy is a string that contains an extension ID and, optionally, an "update" URL separated by a semicolon (;). The extension ID is the 32-letter string found, for example, on chrome://extensions when in Developer mode. If specified, the "update" URL should point to an Update Manifest XML document ( https://developer.chrome.com/extensions/autoupdate ). By default, the Chrome Web Store's update URL is used. The "update" URL set in this policy is only used for the initial installation; subsequent updates of the extension use the update URL in the extension's manifest.
+        Each list item of the policy is a string that contains an extension ID and, optionally, an update URL separated by a semicolon (;). The extension ID is the 32-letter string found, for example, on chrome://extensions when in Developer mode. If specified, the update URL should point to an Update Manifest XML document ( https://developer.chrome.com/extensions/autoupdate ). The update URL should use one of the following schemes: <ph name="HTTP_SCHEME">http</ph>, <ph name="HTTPS_SCHEME">https</ph> or <ph name="FILE_SCHEME">file</ph>. By default, the Chrome Web Store's update URL is used. The update URL set in this policy is only used for the initial installation; subsequent updates of the extension use the update URL in the extension's manifest.
 
          Note: This policy doesn't apply to Incognito mode. Read about hosting extensions ( https://developer.chrome.com/extensions/hosting ).
 example_value:
diff --git a/components/policy/resources/templates/policy_definitions/Extensions/ExtensionUnpublishedAvailability.yaml b/components/policy/resources/templates/policy_definitions/Extensions/ExtensionUnpublishedAvailability.yaml
index b4d53ad..7d68a38e 100644
--- a/components/policy/resources/templates/policy_definitions/Extensions/ExtensionUnpublishedAvailability.yaml
+++ b/components/policy/resources/templates/policy_definitions/Extensions/ExtensionUnpublishedAvailability.yaml
@@ -4,19 +4,21 @@
 caption: Control availability of extensions unpublished on the Chrome Web Store.
 desc: |-
   If this policy is enabled, extensions that are unpublished on the Chrome Web
-  Store will be disabled on <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.
+  Store will be disabled in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.
   This policy only applies to extensions that are installed and updated from the
-  Chrome Web Store. Off-store extensions such as unpacked extensions installed
-  using developer mode and extensions installed using the command-line switch
-  are ignored. Force-installed extensions that do not update from the
-  Chrome Web Store and all version-pinned extensions are also ignored.
+  Chrome Web Store.
+
+  Off-store extensions such as unpacked extensions installed using developer
+  mode and extensions installed using the command-line switch are ignored.
+  Force-installed extensions that are self-hosted are ignored. All
+  version-pinned extensions are also ignored.
 
   If the policy is set to <ph name="ALLOW_UNPUBLISHED">AllowUnpublished</ph> (0) or not set, extensions that are unpublished on the Chrome Web Store are allowed.
   If the policy is set to <ph name="DISABLE_UNPUBLISHED">DisableUnpublished</ph> (1), extensions that are unpublished on the Chrome Web Store are disabled.
 
-future_on:
-- chrome.*
-- chrome_os
+supported_on:
+- chrome.*:115-
+- chrome_os:115-
 features:
   dynamic_refresh: true
   per_profile: true
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp
index e11309d..27ad49e0 100644
--- a/components/policy_strings.grdp
+++ b/components/policy_strings.grdp
@@ -198,8 +198,11 @@
       Duplicate handlers for file_extension "<ph name="FILE_EXTENSION">$1<ex>txt</ex></ph>" referenced by apps "<ph name="POLICY_IDS_LIST">$2<ex>https://google.com/maps, pnomlkjighijklmnopabcdefghijklff</ex></ph>".
     </message>
   </if>
-  <message name="IDS_POLICY_INVALID_EXTENSION_ERROR" desc="The text displayed in the status column when the extension doesn't match the expected format.">
-    Invalid Extension: Expected the value to be of one of the following forms: &lt;extension_id&gt; or &lt;extension_id&gt;;&lt;update_url&gt;.
+  <message name="IDS_POLICY_INVALID_EXTENSION_ID_ERROR" desc="The text displayed in the status column when the extension ID doesn't match the expected format.">
+    Invalid extension ID.
+  </message>
+  <message name="IDS_POLICY_INVALID_UPDATE_URL_ERROR" desc="The text displayed in the status column when the extension update url is invalid or uses an unsupported scheme.">
+    Update URL for extension with ID "<ph name="EXTENSION_ID">$1<ex>abcdefghijklmnopabcdefghijklmnop</ex></ph>" is invalid or uses an unsupported scheme. Supported schemes are: <ph name="HTTP_SCHEME">http</ph>, <ph name="HTTPS_SCHEME">https</ph> and <ph name="FILE_SCHEME">file</ph>.
   </message>
   <message name="IDS_POLICY_URL_PATH_SPECIFIED_ERROR" desc="The text displayed in the status column when a path is specified for an URL, which is not supported">
     The URL pattern "<ph name="URL_PATTERN">$1<ex>*://example.com/</ex></ph>" has a path specified. Paths are not supported for this key, please remove the path and try again. e.g. *://example.com/ => *://example.com",
@@ -276,9 +279,6 @@
   <message name="IDS_POLICY_INVALID_PROXY_MODE_ERROR" desc="The text displayed in the status column when the value for ProxyMode is invalid.">
     Invalid proxy mode.
   </message>
-  <message name="IDS_POLICY_INVALID_UPDATE_URL_ERROR" desc="The text displayed in the status column when the update URL for given extension is invalid.">
-    Invalid update URL for extension with ID "<ph name="EXTENSION_ID">$1<ex>abcdefghijklmnopabcdefghijklmnop</ex></ph>".
-  </message>
   <if expr="chromeos_ash">
     <message name="IDS_POLICY_UNKNOWN_ARC_MANAGED_CONFIGURATION_VARIABLE" desc="The warning text displayed in the status column when the managed configuration of an ARC application contains an unknown variable.">
       Unknown variable "<ph name="VARIABLE">$1<ex>${UNKNOWN_VARIABLE}</ex></ph>" in the managed configuration of "<ph name="APPLICATION_ID">$2<ex>com.dropbox.android</ex></ph>".
diff --git a/components/policy_strings_grdp/IDS_POLICY_INVALID_EXTENSION_ERROR.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_INVALID_EXTENSION_ERROR.png.sha1
deleted file mode 100644
index 2659880..0000000
--- a/components/policy_strings_grdp/IDS_POLICY_INVALID_EXTENSION_ERROR.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-c2af8dc21c52171c338cd50489077e235c85d0cf
\ No newline at end of file
diff --git a/components/policy_strings_grdp/IDS_POLICY_INVALID_EXTENSION_ID_ERROR.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_INVALID_EXTENSION_ID_ERROR.png.sha1
new file mode 100644
index 0000000..a76f75b4
--- /dev/null
+++ b/components/policy_strings_grdp/IDS_POLICY_INVALID_EXTENSION_ID_ERROR.png.sha1
@@ -0,0 +1 @@
+7f2cd45d91a94a7b5d10cf4f4531957df6c0508f
\ No newline at end of file
diff --git a/components/policy_strings_grdp/IDS_POLICY_INVALID_UPDATE_URL_ERROR.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_INVALID_UPDATE_URL_ERROR.png.sha1
new file mode 100644
index 0000000..1363edb
--- /dev/null
+++ b/components/policy_strings_grdp/IDS_POLICY_INVALID_UPDATE_URL_ERROR.png.sha1
@@ -0,0 +1 @@
+7b318805e85b9dfb8b651d4a1e4cad8340bc2f05
\ No newline at end of file
diff --git a/components/reading_list/core/dual_reading_list_model_unittest.cc b/components/reading_list/core/dual_reading_list_model_unittest.cc
index 8cdfdb5..95dd565b 100644
--- a/components/reading_list/core/dual_reading_list_model_unittest.cc
+++ b/components/reading_list/core/dual_reading_list_model_unittest.cc
@@ -13,6 +13,7 @@
 #include "components/reading_list/core/reading_list_entry.h"
 #include "components/reading_list/core/reading_list_model_impl.h"
 #include "components/sync/base/storage_type.h"
+#include "components/sync/model/client_tag_based_model_type_processor.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -189,11 +190,9 @@
         /*initial_account_entries_builders=*/{});
   }
 
-  bool ResetStorageAndMimicSignedInSyncDisabled(
+  bool TriggerStorageLoadCompletionSignedInSyncDisabled(
       std::vector<TestEntryBuilder> initial_local_entries_builders = {},
       std::vector<TestEntryBuilder> initial_account_entries_builders = {}) {
-    ResetStorage();
-
     auto metadata_batch = std::make_unique<syncer::MetadataBatch>();
     sync_pb::ModelTypeState state;
     state.set_initial_sync_state(
@@ -217,6 +216,14 @@
                std::move(initial_account_entries), std::move(metadata_batch));
   }
 
+  bool ResetStorageAndMimicSignedInSyncDisabled(
+      std::vector<TestEntryBuilder> initial_local_entries_builders = {},
+      std::vector<TestEntryBuilder> initial_account_entries_builders = {}) {
+    ResetStorage();
+    return TriggerStorageLoadCompletionSignedInSyncDisabled(
+        initial_local_entries_builders, initial_account_entries_builders);
+  }
+
   bool ResetStorageAndMimicSyncEnabled(
       std::vector<TestEntryBuilder> initial_syncable_entries_builders = {}) {
     ResetStorage();
@@ -276,6 +283,27 @@
   EXPECT_FALSE(dual_model_->loaded());
 }
 
+TEST_F(DualReadingListModelTest, MetaDataClearedBeforeModelLoaded) {
+  ResetStorage();
+  static_cast<syncer::ClientTagBasedModelTypeProcessor*>(
+      account_model_ptr_->GetSyncBridgeForTest()->change_processor())
+      ->ClearMetadataWhileStopped();
+
+  EXPECT_CALL(observer_, ReadingListModelBeganBatchUpdates).Times(0);
+  EXPECT_CALL(observer_, ReadingListModelCompletedBatchUpdates).Times(0);
+  EXPECT_CALL(observer_, ReadingListWillRemoveEntry).Times(0);
+  EXPECT_CALL(observer_, ReadingListDidRemoveEntry).Times(0);
+  EXPECT_CALL(observer_, ReadingListDidApplyChanges).Times(0);
+  EXPECT_CALL(observer_, ReadingListModelLoaded);
+  TriggerStorageLoadCompletionSignedInSyncDisabled(
+      /*initial_local_entries_builders=*/{},
+      /*initial_account_entries_builders=*/{
+          TestEntryBuilder(kUrl, clock_.Now())});
+
+  EXPECT_EQ(0ul, account_model_ptr_->size());
+  EXPECT_EQ(0ul, dual_model_->size());
+}
+
 TEST_F(DualReadingListModelTest, ReturnAccountModelSize) {
   ASSERT_TRUE(ResetStorageAndTriggerLoadCompletion(
       /*initial_local_or_syncable_entries_builders=*/{},
diff --git a/components/reading_list/core/reading_list_model_impl.cc b/components/reading_list/core/reading_list_model_impl.cc
index ca1c222..b4299324 100644
--- a/components/reading_list/core/reading_list_model_impl.cc
+++ b/components/reading_list/core/reading_list_model_impl.cc
@@ -275,8 +275,11 @@
   if (!entry)
     return;
 
-  for (auto& observer : observers_)
-    observer.ReadingListWillRemoveEntry(this, url);
+  if (!suppress_deletions_batch_updates_notifications_) {
+    for (auto& observer : observers_) {
+      observer.ReadingListWillRemoveEntry(this, url);
+    }
+  }
 
   std::unique_ptr<ReadingListModelStorage::ScopedBatchUpdate> batch =
       storage_layer_->EnsureBatchCreated();
@@ -290,9 +293,11 @@
 
   entries_.erase(url);
 
-  for (auto& observer : observers_) {
-    observer.ReadingListDidRemoveEntry(this, url);
-    observer.ReadingListDidApplyChanges(this);
+  if (!suppress_deletions_batch_updates_notifications_) {
+    for (auto& observer : observers_) {
+      observer.ReadingListDidRemoveEntry(this, url);
+      observer.ReadingListDidApplyChanges(this);
+    }
   }
 }
 
@@ -582,7 +587,8 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   auto token = std::make_unique<ScopedReadingListBatchUpdateImpl>(this);
   ++current_batch_updates_count_;
-  if (current_batch_updates_count_ == 1) {
+  if (current_batch_updates_count_ == 1 &&
+      !suppress_deletions_batch_updates_notifications_) {
     for (auto& observer : observers_) {
       observer.ReadingListModelBeganBatchUpdates(this);
     }
@@ -646,8 +652,15 @@
   DCHECK_EQ(read_entry_count_ + unread_entry_count_, entries_.size());
   loaded_ = true;
 
-  sync_bridge_.ModelReadyToSync(/*model=*/this,
-                                std::move(result_or_error.value().second));
+  {
+    // In rare cases, ModelReadyToSync() leads to the deletion of all local
+    // entries. Such deletions should not be propagated to observers, because
+    // ReadingListModelLoaded hasn't been broadcasted yet.
+    base::AutoReset<bool> auto_reset_suppress_observer_notifications(
+        &suppress_deletions_batch_updates_notifications_, true);
+    sync_bridge_.ModelReadyToSync(/*model=*/this,
+                                  std::move(result_or_error.value().second));
+  }
 
   base::UmaHistogramCounts1000("ReadingList.Unread.Count.OnModelLoaded",
                                unread_entry_count_);
@@ -664,7 +677,8 @@
   DCHECK(IsPerformingBatchUpdates());
   DCHECK(current_batch_updates_count_ > 0);
   --current_batch_updates_count_;
-  if (current_batch_updates_count_ == 0) {
+  if (current_batch_updates_count_ == 0 &&
+      !suppress_deletions_batch_updates_notifications_) {
     for (auto& observer : observers_) {
       observer.ReadingListModelCompletedBatchUpdates(this);
     }
diff --git a/components/reading_list/core/reading_list_model_impl.h b/components/reading_list/core/reading_list_model_impl.h
index 186362a..88ddb0e 100644
--- a/components/reading_list/core/reading_list_model_impl.h
+++ b/components/reading_list/core/reading_list_model_impl.h
@@ -179,6 +179,10 @@
 
   bool loaded_ = false;
 
+  // Used to suppress deletions and batch updates notifications when
+  // ReadingListModelLoaded is not broadcasted yet.
+  bool suppress_deletions_batch_updates_notifications_ = false;
+
   std::map<GURL, scoped_refptr<ReadingListEntry>> entries_;
   size_t unread_entry_count_ = 0;
   size_t read_entry_count_ = 0;
diff --git a/components/reporting/util/BUILD.gn b/components/reporting/util/BUILD.gn
index dadbbf6..d9ec17f 100644
--- a/components/reporting/util/BUILD.gn
+++ b/components/reporting/util/BUILD.gn
@@ -105,6 +105,18 @@
   ]
 }
 
+source_set("rate_limiter_leaky_bucket") {
+  sources = [
+    "rate_limiter_leaky_bucket.cc",
+    "rate_limiter_leaky_bucket.h",
+  ]
+
+  deps = [
+    ":rate_limiter_interface",
+    "//base",
+  ]
+}
+
 source_set("rate_limiter_slide_window") {
   sources = [
     "rate_limiter_slide_window.cc",
@@ -124,6 +136,7 @@
   sources = [
     "disconnectable_client_unittest.cc",
     "file_unittest.cc",
+    "rate_limiter_leaky_bucket_unittest.cc",
     "rate_limiter_slide_window_unittest.cc",
     "refcounted_closure_list_unittest.cc",
     "status_macros_unittest.cc",
@@ -135,6 +148,7 @@
     ":disconnectable_client",
     ":file",
     ":rate_limiter_interface",
+    ":rate_limiter_leaky_bucket",
     ":rate_limiter_slide_window",
     ":refcounted_closure_list",
     ":status",
diff --git a/components/reporting/util/rate_limiter_leaky_bucket.cc b/components/reporting/util/rate_limiter_leaky_bucket.cc
new file mode 100644
index 0000000..4d53f56
--- /dev/null
+++ b/components/reporting/util/rate_limiter_leaky_bucket.cc
@@ -0,0 +1,72 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/reporting/util/rate_limiter_leaky_bucket.h"
+
+#include <cmath>
+#include <cstddef>
+
+#include "base/check.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/time/time.h"
+
+namespace reporting {
+
+RateLimiterLeakyBucket::RateLimiterLeakyBucket(size_t max_level,
+                                               base::TimeDelta filling_time,
+                                               base::TimeDelta filling_period)
+    : max_level_(max_level),
+      filling_time_(filling_time),
+      filling_period_(filling_period) {
+  DCHECK_GT(max_level_, 0u);
+  DCHECK_GT(filling_time_, base::TimeDelta());
+  // Make sure filling rate is reasonable - at least 1 token per period!
+  DCHECK_LT(filling_time_ / max_level_, filling_period_);
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+  // Empty initially, start filling in.
+  ScheduleNextFill();
+}
+
+RateLimiterLeakyBucket::~RateLimiterLeakyBucket() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+bool RateLimiterLeakyBucket::Acquire(size_t event_size) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (event_size > max_level_) {
+    return false;  // The event is too large, will never be accepted.
+  }
+
+  if (current_level_ < max_level_) {
+    return false;  // The bucket has not filled in yet.
+  }
+
+  // Accept and account for the new event.
+  current_level_ -= event_size;
+  // Resume filling in.
+  ScheduleNextFill();
+  return true;
+}
+
+void RateLimiterLeakyBucket::NextFill() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  current_level_ += std::ceil(max_level_ * filling_period_ / filling_time_);
+  if (current_level_ > max_level_) {
+    current_level_ = max_level_;
+  } else if (current_level_ < max_level_) {
+    ScheduleNextFill();
+  }
+}
+
+void RateLimiterLeakyBucket::ScheduleNextFill() {
+  base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(&RateLimiterLeakyBucket::NextFill,
+                     weak_ptr_factory_.GetWeakPtr()),
+      filling_period_);
+}
+}  // namespace reporting
diff --git a/components/reporting/util/rate_limiter_leaky_bucket.h b/components/reporting/util/rate_limiter_leaky_bucket.h
new file mode 100644
index 0000000..fedb583
--- /dev/null
+++ b/components/reporting/util/rate_limiter_leaky_bucket.h
@@ -0,0 +1,82 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_REPORTING_UTIL_RATE_LIMITER_LEAKY_BUCKET_H_
+#define COMPONENTS_REPORTING_UTIL_RATE_LIMITER_LEAKY_BUCKET_H_
+
+#include <cstddef>
+
+#include "base/functional/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/time/time.h"
+#include "components/reporting/util/rate_limiter_interface.h"
+
+namespace reporting {
+
+// Rate limiter implementation of the leaky bucket algorithm.
+
+// A leaky bucket works as if filling up with water. The water represents the
+// incoming events, and the bucket represents the system's capacity to accept
+// them. The bucket has a hole in the bottom, which represents the rate at which
+// the system can accept events. Water is not allowed to overflow the bucket.
+//
+// `max_level` is the maximum total size of events that can be in the bucket at
+// any given time. `filling_time` represents the leakage rate at which events
+// are allowed to go through the bucket. `filling_period` indicates how often do
+// we want to update the level (the more frequently we do it, the fewer tokens
+// we add each time).
+// When a new event arrives, its size is released from the bucket, but only if
+// the bucket is full, otherwise the event is rejected. After that the bucket
+// resumes filling in at the prescribed rate - the time it takes is proportional
+// to the event size.
+//
+// The outcome is that the events are accepted at no more than the leakage rate.
+// It works well for averaging events rate over time.
+//
+class RateLimiterLeakyBucket : public RateLimiterInterface {
+ public:
+  RateLimiterLeakyBucket(size_t max_level,
+                         base::TimeDelta filling_time,
+                         base::TimeDelta filling_period = base::Seconds(1));
+
+  RateLimiterLeakyBucket(const RateLimiterLeakyBucket&) = delete;
+  RateLimiterLeakyBucket& operator=(const RateLimiterLeakyBucket&) = delete;
+
+  ~RateLimiterLeakyBucket() override;
+
+  // If the event is allowed, the method returns `true` and updates state to
+  // prepare for the next call. Otherwise returns false.
+  bool Acquire(size_t event_size) override;
+
+ private:
+  // Adds next portion of tokens.
+  void NextFill();
+
+  // Schedules adding next portion of tokens.
+  void ScheduleNextFill();
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  // Total size of the bucket.
+  const size_t max_level_;
+
+  // How long does it take to fill in the bucket up to maximum.
+  const base::TimeDelta filling_time_;
+
+  // How often to add the next portion to the bucket.
+  const base::TimeDelta filling_period_;
+
+  // Current level of the bucket. Starts with 0 and goes up at with such a rate
+  // that fills it up to the `max_level_` in `filling_time_`.
+  // New event is only accepted if the bucket is full.
+  size_t current_level_ GUARDED_BY_CONTEXT(sequence_checker_) = 0u;
+
+  // Weak ptr factory.
+  base::WeakPtrFactory<RateLimiterLeakyBucket> weak_ptr_factory_{this};
+};
+}  // namespace reporting
+
+#endif  // COMPONENTS_REPORTING_UTIL_RATE_LIMITER_LEAKY_BUCKET_H_
diff --git a/components/reporting/util/rate_limiter_leaky_bucket_unittest.cc b/components/reporting/util/rate_limiter_leaky_bucket_unittest.cc
new file mode 100644
index 0000000..82018ce6
--- /dev/null
+++ b/components/reporting/util/rate_limiter_leaky_bucket_unittest.cc
@@ -0,0 +1,86 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/reporting/util/rate_limiter_leaky_bucket.h"
+
+#include <cstddef>
+
+#include "base/rand_util.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace reporting {
+namespace {
+
+constexpr size_t kMaxLevel = 1024u;
+constexpr base::TimeDelta kFillingTime = base::Seconds(16);
+constexpr base::TimeDelta kFillingPeriod = base::Seconds(2);
+constexpr size_t kEventCount = 8;
+
+class RateLimiterLeakyBucketTest : public ::testing::Test {
+ protected:
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+
+  RateLimiterLeakyBucket rate_limiter_{kMaxLevel, kFillingTime, kFillingPeriod};
+};
+
+TEST_F(RateLimiterLeakyBucketTest, SingularEvent) {
+  // Initially - not even 1-byte event can be accepted.
+  ASSERT_FALSE(rate_limiter_.Acquire(1u));
+  // Same when bucket is almost full.
+  task_environment_.FastForwardBy(kFillingTime - kFillingPeriod);
+  ASSERT_FALSE(rate_limiter_.Acquire(1u));
+  // Accept only once it is full.
+  task_environment_.FastForwardBy(kFillingPeriod);
+  ASSERT_TRUE(rate_limiter_.Acquire(kMaxLevel));
+  ASSERT_FALSE(rate_limiter_.Acquire(1u));
+}
+
+TEST_F(RateLimiterLeakyBucketTest, SteadyEventsStream) {
+  // Let the bucket fill in.
+  task_environment_.FastForwardBy(kFillingTime);
+  // Drop one event every `kFillingTime / kMaxLevel` sec,
+  // allowing one event through and no more.
+  for (size_t i = 0; i < kEventCount; ++i) {
+    ASSERT_TRUE(rate_limiter_.Acquire(1u));
+    ASSERT_FALSE(rate_limiter_.Acquire(1u));
+    // We only used 1 byte, will fill in again in 1 period.
+    task_environment_.FastForwardBy(kFillingPeriod);
+  }
+}
+
+TEST_F(RateLimiterLeakyBucketTest, RandomizedEventsStream) {
+  // Let the bucket fill in.
+  task_environment_.FastForwardBy(kFillingTime);
+  // Drop one event every `kFillingTime / kMaxLevel + random` sec,
+  // allowing one event through and no more.
+  for (size_t i = 0; i < kEventCount; ++i) {
+    ASSERT_TRUE(rate_limiter_.Acquire(1u));
+    ASSERT_FALSE(rate_limiter_.Acquire(1u));
+    // We only used 1 byte, will fill in again in 1 period, plus add a random.
+    task_environment_.FastForwardBy(kFillingPeriod +
+                                    base::Milliseconds(base::RandInt(0, 100)));
+  }
+}
+
+TEST_F(RateLimiterLeakyBucketTest, LargeEventsStream) {
+  // Let the bucket fill in.
+  task_environment_.FastForwardBy(kFillingTime);
+  // Drop one event every `kFillingTime / kMaxLevel` sec,
+  // allowing one event through and no more.
+  for (size_t i = 0; i < kEventCount; ++i) {
+    ASSERT_TRUE(rate_limiter_.Acquire(kMaxLevel));
+    ASSERT_FALSE(rate_limiter_.Acquire(1u));
+    // kFillingPeriod is not sufficient now.
+    task_environment_.FastForwardBy(kFillingPeriod);
+    ASSERT_FALSE(rate_limiter_.Acquire(1u));
+    // Let the bucket fill in.
+    task_environment_.FastForwardBy(kFillingTime - kFillingPeriod);
+  }
+}
+}  // namespace
+}  // namespace reporting
diff --git a/components/reporting/util/rate_limiter_slide_window.cc b/components/reporting/util/rate_limiter_slide_window.cc
index 26313c6..f2d91cd 100644
--- a/components/reporting/util/rate_limiter_slide_window.cc
+++ b/components/reporting/util/rate_limiter_slide_window.cc
@@ -10,6 +10,7 @@
 #include "base/check.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 
 namespace reporting {
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
index 7e6269f8..5fd84b05 100644
--- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
+++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
@@ -928,6 +928,11 @@
     ReferrerChain* out_referrer_chain) {
   bool is_url_removed_by_policy = false;
   for (ReferrerChainEntry& entry : *out_referrer_chain) {
+    // entry can be empty if it is removed in
+    // MaybeRemoveNonUserGestureReferrerEntries.
+    if (!entry.has_url()) {
+      continue;
+    }
     if (IsURLAllowlistedByPolicy(GURL(entry.url()), *pref_service_)) {
       entry.clear_url();
       is_url_removed_by_policy = true;
diff --git a/components/safe_browsing/core/browser/safe_browsing_metrics_collector.cc b/components/safe_browsing/core/browser/safe_browsing_metrics_collector.cc
index e80a259..9d927400 100644
--- a/components/safe_browsing/core/browser/safe_browsing_metrics_collector.cc
+++ b/components/safe_browsing/core/browser/safe_browsing_metrics_collector.cc
@@ -87,6 +87,7 @@
 void SafeBrowsingMetricsCollector::LogMetricsAndScheduleNextLogging() {
   LogDailyOptInMetrics();
   LogDailyEventMetrics();
+  MaybeLogDailyEsbProtegoPingSentLast24Hours();
   RemoveOldEventsFromPref();
 
   pref_service_->SetInt64(
@@ -95,6 +96,34 @@
   ScheduleNextLoggingAfterInterval(base::Days(kMetricsLoggingIntervalDay));
 }
 
+void SafeBrowsingMetricsCollector::
+    MaybeLogDailyEsbProtegoPingSentLast24Hours() {
+  if (GetSafeBrowsingState(*pref_service_) !=
+      SafeBrowsingState::ENHANCED_PROTECTION) {
+    return;
+  }
+
+  auto last_ping_with_token = pref_service_->GetTime(
+      prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime);
+  auto last_ping_without_token = pref_service_->GetTime(
+      prefs::kSafeBrowsingEsbProtegoPingWithoutTokenLastLogTime);
+  auto most_recent_ping_type = last_ping_with_token > last_ping_without_token
+                                   ? ProtegoPingType::kWithToken
+                                   : ProtegoPingType::kWithoutToken;
+  auto most_recent_ping_time =
+      std::max(last_ping_with_token, last_ping_without_token);
+
+  auto most_recent_collector_run_time = PrefValueToTime(
+      pref_service_->GetValue(prefs::kSafeBrowsingMetricsLastLogTime));
+
+  bool sent_ping_since_last_collector_run =
+      most_recent_ping_time > most_recent_collector_run_time;
+  base::UmaHistogramEnumeration(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      sent_ping_since_last_collector_run ? most_recent_ping_type
+                                         : ProtegoPingType::kNone);
+}
+
 void SafeBrowsingMetricsCollector::ScheduleNextLoggingAfterInterval(
     base::TimeDelta interval) {
   metrics_collector_timer_.Stop();
diff --git a/components/safe_browsing/core/browser/safe_browsing_metrics_collector.h b/components/safe_browsing/core/browser/safe_browsing_metrics_collector.h
index 7901e2f96..73d71d6b 100644
--- a/components/safe_browsing/core/browser/safe_browsing_metrics_collector.h
+++ b/components/safe_browsing/core/browser/safe_browsing_metrics_collector.h
@@ -131,6 +131,46 @@
 
  private:
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingMetricsCollectorTest, GetUserState);
+  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingMetricsCollectorTest,
+                           ProtegoRequestIsNotLoggedWhenEsbIsNotEnabled);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsNoneIfNotRecordedBeforeFirstRunOfCollector);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsWithTokenWhenPingSincePreviousLogTime);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsWithoutTokenWhenPingSincePreviousLogTime);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsWithTokenWhenPingMoreRecentThanWithoutToken);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsWithoutTokenWhenPingMoreRecentThanWithToken);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsNoneWhenNoPingWithTokenSincePreviousLogTime);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsNoneWhenNoPingWithoutTokenSincePreviousLogTime);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsWithTokenWhenPingBeforeCollectorHasEverRun);
+  FRIEND_TEST_ALL_PREFIXES(
+      SafeBrowsingMetricsCollectorTest,
+      ProtegoRequestLogsWithoutTokenWhenPingBeforeCollectorHasEverRun);
+
+  // The type of Protego ping that was sent by an enhanced protection
+  // user. These values are persisted to logs. Entries should not be renumbered
+  // and numeric values should never be reused.
+  enum class ProtegoPingType {
+    kUnknownType = 0,
+    kNone = 1,
+    kWithToken = 2,
+    kWithoutToken = 3,
+    kMaxValue = kWithoutToken,
+  };
 
   static bool IsBypassEventType(const EventType& type);
   static bool IsSecuritySensitiveEventType(const EventType& type);
@@ -138,6 +178,7 @@
 
   // For daily metrics.
   void LogMetricsAndScheduleNextLogging();
+  void MaybeLogDailyEsbProtegoPingSentLast24Hours();
   void ScheduleNextLoggingAfterInterval(base::TimeDelta interval);
   void LogDailyOptInMetrics();
   void LogDailyEventMetrics();
diff --git a/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc
index a5d7595..f7388a5c 100644
--- a/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc
+++ b/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "components/safe_browsing/core/browser/safe_browsing_metrics_collector.h"
+
 #include <memory>
 #include <utility>
 
@@ -91,6 +92,12 @@
         prefs::kSafeBrowsingEventTimestamps);
     pref_service_.registry()->RegisterBooleanPref(
         prefs::kEnhancedProtectionEnabledViaTailoredSecurity, false);
+    // Registration is normally handled by the safebrowsing preference module
+    pref_service_.registry()->RegisterTimePref(
+        prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime, base::Time());
+    pref_service_.registry()->RegisterTimePref(
+        prefs::kSafeBrowsingEsbProtegoPingWithoutTokenLastLogTime,
+        base::Time());
   }
 };
 
@@ -738,4 +745,173 @@
             metrics_collector_->GetLatestSecuritySensitiveEventTimestamp());
 }
 
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestIsNotLoggedWhenEsbIsNotEnabled) {
+  base::HistogramTester histograms;
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::STANDARD_PROTECTION);
+  pref_service_.SetTime(prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime,
+                        base::Time::Now() - base::Minutes(30));
+  metrics_collector_->StartLogging();
+  histograms.ExpectTotalCount(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      /* expected_count */ 0);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsNoneIfNotRecordedBeforeFirstRunOfCollector) {
+  base::HistogramTester histograms;
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+
+  pref_service_.SetTime(prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime,
+                        base::Time());
+
+  metrics_collector_->StartLogging();
+
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kNone,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsWithTokenWhenPingSincePreviousLogTime) {
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+  metrics_collector_->StartLogging();
+
+  base::HistogramTester histograms;
+  pref_service_.SetTime(prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime,
+                        base::Time::Now() + base::Minutes(30));
+  task_environment_.FastForwardBy(base::Days(1));
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kWithToken,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsWithoutTokenWhenPingSincePreviousLogTime) {
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+  metrics_collector_->StartLogging();
+
+  base::HistogramTester histograms;
+  pref_service_.SetTime(
+      prefs::kSafeBrowsingEsbProtegoPingWithoutTokenLastLogTime,
+      base::Time::Now() + base::Minutes(30));
+  task_environment_.FastForwardBy(base::Days(1));
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kWithoutToken,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsWithTokenWhenPingMoreRecentThanWithoutToken) {
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+  metrics_collector_->StartLogging();
+
+  base::HistogramTester histograms;
+  base::Time time_of_ping_without_token = base::Time::Now() + base::Minutes(30);
+
+  pref_service_.SetTime(
+      prefs::kSafeBrowsingEsbProtegoPingWithoutTokenLastLogTime,
+      time_of_ping_without_token);
+  pref_service_.SetTime(prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime,
+                        time_of_ping_without_token + base::Minutes(1));
+
+  task_environment_.FastForwardBy(base::Days(1));
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kWithToken,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsWithoutTokenWhenPingMoreRecentThanWithToken) {
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+  metrics_collector_->StartLogging();
+
+  base::HistogramTester histograms;
+  base::Time time_of_ping_with_token = base::Time::Now() + base::Minutes(30);
+
+  pref_service_.SetTime(prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime,
+                        time_of_ping_with_token);
+  pref_service_.SetTime(
+      prefs::kSafeBrowsingEsbProtegoPingWithoutTokenLastLogTime,
+      time_of_ping_with_token + base::Minutes(1));
+
+  task_environment_.FastForwardBy(base::Days(1));
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kWithoutToken,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsNoneWhenNoPingWithTokenSincePreviousLogTime) {
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+  pref_service_.SetTime(prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime,
+                        base::Time::Now() + base::Minutes(30));
+  task_environment_.FastForwardBy(base::Minutes(35));
+  metrics_collector_->StartLogging();
+
+  // Ignore histogram values logged before now.
+  base::HistogramTester histograms;
+  task_environment_.FastForwardBy(base::Days(1));
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kNone,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsNoneWhenNoPingWithoutTokenSincePreviousLogTime) {
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+  pref_service_.SetTime(
+      prefs::kSafeBrowsingEsbProtegoPingWithoutTokenLastLogTime,
+      base::Time::Now() + base::Minutes(30));
+  task_environment_.FastForwardBy(base::Minutes(35));
+  metrics_collector_->StartLogging();
+
+  // Ignore histogram values logged before now.
+  base::HistogramTester histograms;
+  task_environment_.FastForwardBy(base::Days(1));
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kNone,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsWithTokenWhenPingBeforeCollectorHasEverRun) {
+  base::HistogramTester histograms;
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+
+  pref_service_.SetTime(prefs::kSafeBrowsingEsbProtegoPingWithTokenLastLogTime,
+                        base::Time::Now() - base::Days(1) - base::Minutes(30));
+
+  metrics_collector_->StartLogging();
+
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kWithToken,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       ProtegoRequestLogsWithoutTokenWhenPingBeforeCollectorHasEverRun) {
+  base::HistogramTester histograms;
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+
+  pref_service_.SetTime(
+      prefs::kSafeBrowsingEsbProtegoPingWithoutTokenLastLogTime,
+      base::Time::Now() - base::Days(1) - base::Minutes(30));
+
+  metrics_collector_->StartLogging();
+
+  histograms.ExpectUniqueSample(
+      "SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours",
+      SafeBrowsingMetricsCollector::ProtegoPingType::kWithoutToken,
+      /* expected_count */ 1);
+}
+
 }  // namespace safe_browsing
diff --git a/components/safe_browsing/core/browser/tailored_security_service/OWNERS b/components/safe_browsing/core/browser/tailored_security_service/OWNERS
index 4f674dd..23b514c 100644
--- a/components/safe_browsing/core/browser/tailored_security_service/OWNERS
+++ b/components/safe_browsing/core/browser/tailored_security_service/OWNERS
@@ -1 +1,2 @@
 drubery@chromium.org
+jacastro@chromium.org
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc
index ade82b1..7d538cc 100644
--- a/components/safe_browsing/core/common/features.cc
+++ b/components/safe_browsing/core/common/features.cc
@@ -27,7 +27,7 @@
 
 BASE_FEATURE(kAddPageLoadTokenToClientSafeBrowsingReport,
              "AddPageLoadTokenToClientSafeBrowsingReport",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 BASE_FEATURE(kAntiPhishingTelemetry,
              "AntiPhishingTelemetry",
diff --git a/components/search/ntp_features.cc b/components/search/ntp_features.cc
index b5ee79c..307b4041 100644
--- a/components/search/ntp_features.cc
+++ b/components/search/ntp_features.cc
@@ -151,7 +151,7 @@
 // If true, displays a horizontal scrollbar on overflowing modules.
 BASE_FEATURE(kNtpModulesOverflowScrollbar,
              "NtpModulesOverflowScrollbar",
-             base::FEATURE_ENABLED_BY_DEFAULT);
+             base::FEATURE_DISABLED_BY_DEFAULT);
 
 // If enabled, modules will be able to be reordered via dragging and dropping
 BASE_FEATURE(kNtpModulesDragAndDrop,
diff --git a/components/services/storage/public/mojom/service_worker_database.mojom b/components/services/storage/public/mojom/service_worker_database.mojom
index f669b865..6f3bf4d 100644
--- a/components/services/storage/public/mojom/service_worker_database.mojom
+++ b/components/services/storage/public/mojom/service_worker_database.mojom
@@ -13,6 +13,7 @@
 import "third_party/blink/public/mojom/service_worker/service_worker_database.mojom";
 import "third_party/blink/public/mojom/service_worker/service_worker_fetch_handler_type.mojom";
 import "third_party/blink/public/mojom/service_worker/service_worker_registration_options.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom";
 import "third_party/blink/public/mojom/storage_key/storage_key.mojom";
 import "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom";
 import "url/mojom/url.mojom";
@@ -74,6 +75,8 @@
   // to restrict the use of some powerful APIs in FencedFrames
   // (crbug.com/1276419).
   blink.mojom.AncestorFrameType ancestor_frame_type;
+
+  blink.mojom.ServiceWorkerRouterRules? router_rule;
 };
 
 // Represents a service worker script data which is stored in database.
diff --git a/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.css b/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.css
index 4160427..6e686782 100644
--- a/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.css
+++ b/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.css
@@ -5,6 +5,15 @@
 /* This is the stylesheet for the interstitial when the
    "WebFilterInterstitialRefresh" flag is enabled. */
 
+.banner {
+  align-items: center;
+  box-shadow: 0 0 2px rgba(60, 64, 67, 0.12), 0 0 6px rgba(60, 64, 67, 0.15);
+  border-radius: 4px;
+  display: flex;
+  flex-direction: row;
+  padding: 16px;
+ }
+
 body {
   --avatar-stroke-color: var(--google-gray-50);
   --custodian-name-color: #333333;
@@ -14,7 +23,7 @@
   --paragraph-color: var(--google-gray-700);
   --callout-text-color: var(--google-gray-900);
   --callout-bg-color: var(--google-gray-100);
-  font-family: "Roboto", sans-serif;
+  font-family: 'Roboto', sans-serif;
   padding: 24px 24px 20px 24px;
 }
 
@@ -74,6 +83,23 @@
   border-color: var(--focused-details-button-border);
 }
 
+#family-link-kite {
+  height: 24px;
+  width: 24px;
+  padding: 16px;
+}
+
+.banner-header {
+  color: var(--header-color);
+  line-height: 24px;
+  margin-top: 0;
+}
+
+.banner-content {
+  line-height: 20px;
+  margin-top: 0;
+}
+
 h1,
 p,
 .custodian-contact {
diff --git a/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.html b/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.html
index 191e985..646bd64 100644
--- a/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.html
+++ b/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.html
@@ -14,6 +14,14 @@
 <body class="supervised-user-block">
 <div class="frame-blocked" id="frame-blocked" tabindex="-1">
   <div class="message-container">
+    <div class="banner" id="banner">
+      <img id="family-link-kite"
+      src="supervised_user_icon.png">
+      <div id="banner-message">
+        <p class="banner-header">$i18n{bannerTitle}</p>
+        <p class="banner-content"> $i18n{bannerMessage}</p>
+      </div>
+    </div>
     <picture id="error-page-illustration">
       <source
         srcset="error_page_illustration_dark_theme.svg"
diff --git a/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.js b/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.js
index 5d8c416..a56507d 100644
--- a/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.js
+++ b/components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.js
@@ -80,6 +80,11 @@
     }
   }
 
+  const showBanner = loadTimeData.getBoolean('showBanner');
+  if (!showBanner) {
+    $('banner').style.display = 'none';
+  }
+
   const alreadyRequestedAccessRemote =
       loadTimeData.getBoolean('alreadySentRemoteRequest');
   if (alreadyRequestedAccessRemote) {
diff --git a/components/supervised_user/core/browser/supervised_user_error_page.cc b/components/supervised_user/core/browser/supervised_user_error_page.cc
index dda1987..e1c872e39 100644
--- a/components/supervised_user/core/browser/supervised_user_error_page.cc
+++ b/components/supervised_user/core/browser/supervised_user_error_page.cc
@@ -74,7 +74,8 @@
                                FilteringBehaviorReason reason,
                                const std::string& app_locale,
                                bool already_sent_remote_request,
-                               bool is_main_frame) {
+                               bool is_main_frame,
+                               bool show_banner) {
   base::Value::Dict strings;
   strings.Set("blockPageTitle",
               l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_TITLE));
@@ -102,6 +103,12 @@
   strings.Set("isLocalWebApprovalsEnabled", local_web_approvals_enabled);
   strings.Set("isLocalWebApprovalsPreferred",
               supervised_user::IsLocalWebApprovalThePreferredButton());
+  strings.Set("showBanner", show_banner);
+  strings.Set("bannerTitle",
+              l10n_util::GetStringUTF8(IDS_PARENT_BLOCKED_SITE_BANNER_TITLE));
+  strings.Set("bannerMessage",
+              l10n_util::GetStringUTF8(IDS_PARENT_BLOCKED_SITE_BANNER_MESSAGE));
+
   bool is_automatically_blocked = ReasonIsAutomatic(reason);
 
   std::string block_header;
diff --git a/components/supervised_user/core/browser/supervised_user_error_page.h b/components/supervised_user/core/browser/supervised_user_error_page.h
index ee6e434..3770d8e9 100644
--- a/components/supervised_user/core/browser/supervised_user_error_page.h
+++ b/components/supervised_user/core/browser/supervised_user_error_page.h
@@ -23,7 +23,8 @@
                                FilteringBehaviorReason reason,
                                const std::string& app_locale,
                                bool already_sent_remote_request,
-                               bool is_main_frame);
+                               bool is_main_frame,
+                               bool show_banner);
 
 }  //  namespace supervised_user
 
diff --git a/components/supervised_user/core/browser/supervised_user_error_page_unittest.cc b/components/supervised_user/core/browser/supervised_user_error_page_unittest.cc
index d6148ca..702a91f8 100644
--- a/components/supervised_user/core/browser/supervised_user_error_page_unittest.cc
+++ b/components/supervised_user/core/browser/supervised_user_error_page_unittest.cc
@@ -93,7 +93,8 @@
       param.profile_image_url2, param.custodian, param.custodian_email,
       param.second_custodian, param.second_custodian_email, param.reason,
       /*app_locale=*/"",
-      /*already_sent_request=*/false, /*is_main_frame=*/true);
+      /*already_sent_request=*/false, /*is_main_frame=*/true,
+      /*show_banner=*/true);
   // The result should contain the original HTML (with $i18n{} replacements)
   // plus scripts that plug values into it. The test can't easily check that the
   // scripts are correct, but can check that the output contains the expected
diff --git a/components/supervised_user/core/browser/supervised_user_interstitial.cc b/components/supervised_user/core/browser/supervised_user_interstitial.cc
index 34a60241..6ce156a6 100644
--- a/components/supervised_user/core/browser/supervised_user_interstitial.cc
+++ b/components/supervised_user/core/browser/supervised_user_interstitial.cc
@@ -82,10 +82,13 @@
       supervised_user_service->remote_web_approvals_manager()
           .AreApprovalRequestsEnabled();
 
+  bool show_banner =
+      supervised_user_service->ShouldShowFirstTimeInterstitialBanner();
+
   return BuildErrorPageHtml(
       allow_access_requests, profile_image_url, profile_image_url2, custodian,
       custodian_email, second_custodian, second_custodian_email, reason,
-      application_locale, already_sent_request, is_main_frame);
+      application_locale, already_sent_request, is_main_frame, show_banner);
 }
 
 void SupervisedUserInterstitial::GoBack() {
diff --git a/components/supervised_user/core/browser/supervised_user_service.cc b/components/supervised_user/core/browser/supervised_user_service.cc
index 40b7d81..f37b31b 100644
--- a/components/supervised_user/core/browser/supervised_user_service.cc
+++ b/components/supervised_user/core/browser/supervised_user_service.cc
@@ -70,14 +70,16 @@
       static_cast<supervised_user::FirstTimeInterstitialBannerState>(
           user_prefs_->GetInteger(prefs::kFirstTimeInterstitialBannerState));
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
-  if (banner_state ==
-          supervised_user::FirstTimeInterstitialBannerState::kUnknown &&
-      can_show_first_time_interstitial_banner_) {
-    banner_state =
-        supervised_user::FirstTimeInterstitialBannerState::kNeedToShow;
-  } else {
-    banner_state =
-        supervised_user::FirstTimeInterstitialBannerState::kSetupComplete;
+  if (supervised_user::CanDisplayFirstTimeInterstitialBanner()) {
+    if (banner_state ==
+            supervised_user::FirstTimeInterstitialBannerState::kUnknown &&
+        can_show_first_time_interstitial_banner_) {
+      banner_state =
+          supervised_user::FirstTimeInterstitialBannerState::kNeedToShow;
+    } else {
+      banner_state =
+          supervised_user::FirstTimeInterstitialBannerState::kSetupComplete;
+    }
   }
 #else
   banner_state =
@@ -414,12 +416,7 @@
 }
 
 void SupervisedUserService::MarkFirstTimeInterstitialBannerShown() const {
-  supervised_user::FirstTimeInterstitialBannerState banner_state =
-      static_cast<supervised_user::FirstTimeInterstitialBannerState>(
-          user_prefs_->GetInteger(prefs::kFirstTimeInterstitialBannerState));
-
-  if (banner_state ==
-      supervised_user::FirstTimeInterstitialBannerState::kNeedToShow) {
+  if (ShouldShowFirstTimeInterstitialBanner()) {
     user_prefs_->SetInteger(
         prefs::kFirstTimeInterstitialBannerState,
         static_cast<int>(
@@ -427,4 +424,11 @@
   }
 }
 
+bool SupervisedUserService::ShouldShowFirstTimeInterstitialBanner() const {
+  supervised_user::FirstTimeInterstitialBannerState banner_state =
+      static_cast<supervised_user::FirstTimeInterstitialBannerState>(
+          user_prefs_->GetInteger(prefs::kFirstTimeInterstitialBannerState));
+  return banner_state ==
+         supervised_user::FirstTimeInterstitialBannerState::kNeedToShow;
+}
 }  // namespace supervised_user
diff --git a/components/supervised_user/core/browser/supervised_user_service.h b/components/supervised_user/core/browser/supervised_user_service.h
index 502ba0e..c0f8f22 100644
--- a/components/supervised_user/core/browser/supervised_user_service.h
+++ b/components/supervised_user/core/browser/supervised_user_service.h
@@ -145,6 +145,9 @@
   // who haven't yet seen the banner.
   void MarkFirstTimeInterstitialBannerShown() const;
 
+  // Returns true if the interstitial banner needs to be shown to user.
+  bool ShouldShowFirstTimeInterstitialBanner() const;
+
   // Use |SupervisedUserServiceFactory::GetForProfile(..)| to get
   // an instance of this service.
   // Public to allow visibility to iOS factory.
diff --git a/components/supervised_user/core/common/features.cc b/components/supervised_user/core/common/features.cc
index bc7aa07..9418e697 100644
--- a/components/supervised_user/core/common/features.cc
+++ b/components/supervised_user/core/common/features.cc
@@ -147,6 +147,12 @@
 BASE_FEATURE(kEnableManagedByParentUi,
              "EnableManagedByParentUi",
              base::FEATURE_DISABLED_BY_DEFAULT);
+
+bool CanDisplayFirstTimeInterstitialBanner() {
+  return base::FeatureList::IsEnabled(kEnableSupervisionOnDesktopAndIOS) &&
+         base::FeatureList::IsEnabled(
+             kFilterWebsitesForSupervisedUsersOnDesktopAndIOS);
+}
 // The URL which the "Managed by your parent" UI links to. This is defined as a
 // FeatureParam (but with the currently correct default) because:
 // * We expect to change this URL in the near-term, this allows us to gradually
diff --git a/components/supervised_user/core/common/features.h b/components/supervised_user/core/common/features.h
index f6c9b012..5bad65ba 100644
--- a/components/supervised_user/core/common/features.h
+++ b/components/supervised_user/core/common/features.h
@@ -26,6 +26,10 @@
 BASE_DECLARE_FEATURE(kEnableManagedByParentUi);
 extern const base::FeatureParam<std::string> kManagedByParentUiMoreInfoUrl;
 
+// Returns whether banner can be displayed to the user after website filtering
+// is enabled
+bool CanDisplayFirstTimeInterstitialBanner();
+
 BASE_DECLARE_FEATURE(kLocalExtensionApprovalsV2);
 
 BASE_DECLARE_FEATURE(kRetireStaticDenyList);
diff --git a/components/viz/service/display_embedder/skia_output_device_dawn.cc b/components/viz/service/display_embedder/skia_output_device_dawn.cc
index 16f43c63..fd75e38 100644
--- a/components/viz/service/display_embedder/skia_output_device_dawn.cc
+++ b/components/viz/service/display_embedder/skia_output_device_dawn.cc
@@ -156,9 +156,11 @@
       /*plane_index=*/0, /*mipmapped=*/false, /*root_surface=*/true);
   skgpu::graphite::DawnTextureInfo dawn_texture_info;
   texture_info.getDawnTextureInfo(&dawn_texture_info);
+
+  wgpu::TextureView texture_view = swap_chain_.GetCurrentTextureView();
   skgpu::graphite::BackendTexture backend_texture(
       SkISize::Make(size_.width(), size_.height()), dawn_texture_info,
-      swap_chain_.GetCurrentTextureView().Get());
+      texture_view.Get());
 
   SkSurfaceProps surface_props{0, kUnknown_SkPixelGeometry};
   sk_surface_ = SkSurfaces::WrapBackendTexture(
diff --git a/components/webapk/webapk.proto b/components/webapk/webapk.proto
index 7e0e43e8..6490a54e 100644
--- a/components/webapk/webapk.proto
+++ b/components/webapk/webapk.proto
@@ -117,9 +117,10 @@
 message Image {
   enum Usage {
     PRIMARY_ICON = 1;
-    BADGE_ICON = 2;
     SPLASH_ICON = 3;
     SHORTCUT_ICON = 4;
+
+    reserved 2;
   }
 
   // Image's URL.
diff --git a/components/webauthn/core/browser/BUILD.gn b/components/webauthn/core/browser/BUILD.gn
index fda97cf..15668ed 100644
--- a/components/webauthn/core/browser/BUILD.gn
+++ b/components/webauthn/core/browser/BUILD.gn
@@ -33,10 +33,13 @@
   sources = [
     "mock_internal_authenticator.cc",
     "mock_internal_authenticator.h",
+    "test_passkey_model.cc",
+    "test_passkey_model.h",
   ]
   deps = [
     ":browser",
     "//base/test:test_support",
+    "//components/sync",
     "//content/public/browser",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/components/webauthn/core/browser/passkey_model.h b/components/webauthn/core/browser/passkey_model.h
index 1dbad14..c271d57 100644
--- a/components/webauthn/core/browser/passkey_model.h
+++ b/components/webauthn/core/browser/passkey_model.h
@@ -45,7 +45,7 @@
       const = 0;
   virtual std::string AddNewPasskeyForTesting(
       sync_pb::WebauthnCredentialSpecifics passkey) = 0;
-  virtual bool DeletePasskeyForTesting(std::string sync_id) = 0;
+  virtual bool DeletePasskeyForTesting(const std::string& sync_id) = 0;
 };
 
 #endif  // COMPONENTS_WEBAUTHN_CORE_BROWSER_PASSKEY_MODEL_H_
diff --git a/components/webauthn/core/browser/passkey_sync_bridge.cc b/components/webauthn/core/browser/passkey_sync_bridge.cc
index fc06c54..ca06760 100644
--- a/components/webauthn/core/browser/passkey_sync_bridge.cc
+++ b/components/webauthn/core/browser/passkey_sync_bridge.cc
@@ -228,7 +228,7 @@
   return sync_id;
 }
 
-bool PasskeySyncBridge::DeletePasskeyForTesting(std::string sync_id) {
+bool PasskeySyncBridge::DeletePasskeyForTesting(const std::string& sync_id) {
   auto it = data_.find(sync_id);
   if (it == data_.end()) {
     return false;
diff --git a/components/webauthn/core/browser/passkey_sync_bridge.h b/components/webauthn/core/browser/passkey_sync_bridge.h
index 9f04e124..9d71236 100644
--- a/components/webauthn/core/browser/passkey_sync_bridge.h
+++ b/components/webauthn/core/browser/passkey_sync_bridge.h
@@ -55,7 +55,7 @@
       const override;
   std::string AddNewPasskeyForTesting(
       sync_pb::WebauthnCredentialSpecifics passkey) override;
-  bool DeletePasskeyForTesting(std::string sync_id) override;
+  bool DeletePasskeyForTesting(const std::string& sync_id) override;
 
  private:
   void OnCreateStore(const absl::optional<syncer::ModelError>& error,
diff --git a/components/webauthn/core/browser/test_passkey_model.cc b/components/webauthn/core/browser/test_passkey_model.cc
new file mode 100644
index 0000000..ac2c4fcf
--- /dev/null
+++ b/components/webauthn/core/browser/test_passkey_model.cc
@@ -0,0 +1,44 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/webauthn/core/browser/test_passkey_model.h"
+
+#include "base/containers/cxx20_erase_unordered_set.h"
+#include "base/notreached.h"
+#include "base/rand_util.h"
+#include "components/sync/protocol/webauthn_credential_specifics.pb.h"
+
+TestPasskeyModel::TestPasskeyModel() = default;
+TestPasskeyModel::~TestPasskeyModel() = default;
+
+base::WeakPtr<syncer::ModelTypeControllerDelegate>
+TestPasskeyModel::GetModelTypeControllerDelegate() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+base::flat_set<std::string> TestPasskeyModel::GetAllSyncIds() const {
+  base::flat_set<std::string> ids;
+  for (const auto& credential : credentials_) {
+    ids.emplace(credential.sync_id());
+  }
+  return ids;
+}
+
+std::vector<sync_pb::WebauthnCredentialSpecifics>
+TestPasskeyModel::GetAllPasskeys() const {
+  return credentials_;
+}
+
+std::string TestPasskeyModel::AddNewPasskeyForTesting(
+    sync_pb::WebauthnCredentialSpecifics passkey) {
+  credentials_.push_back(std::move(passkey));
+  return credentials_.back().credential_id();
+}
+
+bool TestPasskeyModel::DeletePasskeyForTesting(const std::string& sync_id) {
+  return base::EraseIf(credentials_, [&sync_id](const auto& credential) {
+    return credential.sync_id() == sync_id;
+  });
+}
diff --git a/components/webauthn/core/browser/test_passkey_model.h b/components/webauthn/core/browser/test_passkey_model.h
new file mode 100644
index 0000000..95b03e5
--- /dev/null
+++ b/components/webauthn/core/browser/test_passkey_model.h
@@ -0,0 +1,32 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_WEBAUTHN_CORE_BROWSER_TEST_PASSKEY_MODEL_H_
+#define COMPONENTS_WEBAUTHN_CORE_BROWSER_TEST_PASSKEY_MODEL_H_
+
+#include <string>
+
+#include "components/sync/protocol/webauthn_credential_specifics.pb.h"
+#include "components/webauthn/core/browser/passkey_model.h"
+
+class TestPasskeyModel : public PasskeyModel {
+ public:
+  TestPasskeyModel();
+  ~TestPasskeyModel() override;
+
+  // PasskeyModel:
+  base::WeakPtr<syncer::ModelTypeControllerDelegate>
+  GetModelTypeControllerDelegate() override;
+  base::flat_set<std::string> GetAllSyncIds() const override;
+  std::vector<sync_pb::WebauthnCredentialSpecifics> GetAllPasskeys()
+      const override;
+  std::string AddNewPasskeyForTesting(
+      sync_pb::WebauthnCredentialSpecifics passkey) override;
+  bool DeletePasskeyForTesting(const std::string& sync_id) override;
+
+ private:
+  std::vector<sync_pb::WebauthnCredentialSpecifics> credentials_;
+};
+
+#endif  // COMPONENTS_WEBAUTHN_CORE_BROWSER__TEST_PASSKEY_MODEL_H_
diff --git a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
index c87ae83..34f794f 100644
--- a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
+++ b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
@@ -108,7 +108,7 @@
             std::vector<std::unique_ptr<blink::WebInputEvent>>{},
             std::vector<std::unique_ptr<blink::WebInputEvent>>{}, latency_info);
     std::vector<uint8_t> native_event_data =
-        ui::EventToData(key_event.os_event);
+        ui::EventToData(key_event.os_event.Get());
     host_->ForwardKeyboardEventWithCommands(
         std::move(input_event), native_event_data, key_event.skip_in_browser,
         std::move(edit_commands));
diff --git a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
index b95ab55..ed4e4ad 100644
--- a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
+++ b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
@@ -11,6 +11,7 @@
 #include <tuple>
 #include <utility>
 
+#include "base/apple/owned_objc.h"
 #include "base/containers/contains.h"
 #include "base/debug/crash_logging.h"
 #import "base/mac/foundation_util.h"
@@ -956,7 +957,7 @@
   // Don't cancel child popups; the key events are probably what's triggering
   // the popup in the first place.
 
-  NativeWebKeyboardEvent event(theEvent);
+  NativeWebKeyboardEvent event((base::apple::OwnedNSEvent(theEvent)));
   ui::LatencyInfo latency_info;
   if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown ||
       event.GetType() == blink::WebInputEvent::Type::kChar) {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 9ff40fa5..dc056f3 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1776,6 +1776,8 @@
     "renderer_host/media/media_stream_dispatcher_host.h",
     "renderer_host/media/media_stream_manager.cc",
     "renderer_host/media/media_stream_manager.h",
+    "renderer_host/media/media_stream_metrics.cc",
+    "renderer_host/media/media_stream_metrics.h",
     "renderer_host/media/media_stream_power_logger.cc",
     "renderer_host/media/media_stream_power_logger.h",
     "renderer_host/media/media_stream_provider.h",
@@ -2620,6 +2622,7 @@
     ]
     deps += [
       ":mac_helpers",
+      "//base:base_arc",
       "//components/remote_cocoa/app_shim",
       "//components/remote_cocoa/browser",
       "//components/remote_cocoa/common:mojo",
@@ -2640,6 +2643,7 @@
   } else if (is_ios) {
     sources += [
       "child_process_launcher_helper_ios.cc",
+      "devtools/protocol/native_input_event_builder_ios.mm",
       "renderer_host/browser_compositor_ios.h",
       "renderer_host/browser_compositor_ios.mm",
       "renderer_host/delegated_frame_host_client_ios.cc",
@@ -3003,6 +3007,8 @@
       "android/gpu_process_callback.cc",
       "android/ime_adapter_android.cc",
       "android/ime_adapter_android.h",
+      "android/impression_utils.cc",
+      "android/impression_utils.h",
       "android/java/gin_java_bound_object.cc",
       "android/java/gin_java_bound_object.h",
       "android/java/gin_java_bound_object_delegate.cc",
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index af7f64f..cb2569e 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -82,6 +82,12 @@
 
   ~AccessibilityWinBrowserTest() override;
 
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    AccessibilityBrowserTest::SetUpCommandLine(command_line);
+    // Some of these tests assume a device scale factor of 1.0.
+    command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1");
+  }
+
  protected:
   class AccessibleChecker;
   std::string PrintAXTree() const;
diff --git a/content/browser/android/impression_utils.cc b/content/browser/android/impression_utils.cc
new file mode 100644
index 0000000..9c3f1bf
--- /dev/null
+++ b/content/browser/android/impression_utils.cc
@@ -0,0 +1,80 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/android/impression_utils.h"
+
+#include "base/android/unguessable_token_android.h"
+#include "base/numerics/safe_conversions.h"
+#include "content/public/android/content_jni_headers/ImpressionUtils_jni.h"
+
+namespace content {
+
+base::android::ScopedJavaLocalRef<jobject> CreateJavaImpression(
+    JNIEnv* env,
+    base::UnguessableToken attribution_src_token,
+    base::UnguessableToken initiator_frame_token,
+    int initiator_process_id,
+    const network::AttributionReportingRuntimeFeatures& features) {
+  return Java_ImpressionUtils_create(
+      env,
+      base::android::UnguessableTokenAndroid::Create(env,
+                                                     attribution_src_token),
+      base::android::UnguessableTokenAndroid::Create(env,
+                                                     initiator_frame_token),
+      initiator_process_id, features.ToEnumBitmask());
+}
+
+network::AttributionReportingRuntimeFeatures
+GetAttributionRuntimeFeaturesFromJavaImpression(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_object) {
+  if (!j_object) {
+    return network::AttributionReportingRuntimeFeatures();
+  }
+  return network::AttributionReportingRuntimeFeatures::FromEnumBitmask(
+      base::checked_cast<uint64_t>(
+          Java_ImpressionUtils_getAttributionRuntimeFeatures(env, j_object)));
+}
+
+absl::optional<blink::LocalFrameToken> GetInitiatorFrameTokenFromJavaImpression(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_object) {
+  if (!j_object) {
+    return absl::nullopt;
+  }
+  auto optional_token =
+      base::android::UnguessableTokenAndroid::FromJavaUnguessableToken(
+          env, Java_ImpressionUtils_getInitiatorFrameToken(env, j_object));
+  if (optional_token) {
+    return blink::LocalFrameToken(optional_token.value());
+  }
+  return absl::nullopt;
+}
+
+int GetInitiatorProcessIDFromJavaImpression(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_object) {
+  if (!j_object) {
+    return false;
+  }
+  return Java_ImpressionUtils_getInitiatorProcessID(env, j_object);
+}
+
+absl::optional<blink::AttributionSrcToken>
+GetAttributionSrcTokenFromJavaImpression(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_object) {
+  if (!j_object) {
+    return absl::nullopt;
+  }
+  auto optional_token =
+      base::android::UnguessableTokenAndroid::FromJavaUnguessableToken(
+          env, Java_ImpressionUtils_getAttributionSrcToken(env, j_object));
+  if (optional_token) {
+    return blink::AttributionSrcToken(optional_token.value());
+  }
+  return absl::nullopt;
+}
+
+}  // namespace content
diff --git a/content/browser/android/impression_utils.h b/content/browser/android/impression_utils.h
new file mode 100644
index 0000000..78c6cc2
--- /dev/null
+++ b/content/browser/android/impression_utils.h
@@ -0,0 +1,38 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ANDROID_IMPRESSION_UTILS_H_
+#define CONTENT_BROWSER_ANDROID_IMPRESSION_UTILS_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/unguessable_token.h"
+#include "content/public/browser/android/impression_android.h"
+#include "services/network/public/cpp/attribution_reporting_runtime_features.h"
+#include "third_party/blink/public/common/tokens/tokens.h"
+
+namespace content {
+
+network::AttributionReportingRuntimeFeatures
+GetAttributionRuntimeFeaturesFromJavaImpression(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_object);
+
+absl::optional<blink::LocalFrameToken> GetInitiatorFrameTokenFromJavaImpression(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_object);
+
+int GetInitiatorProcessIDFromJavaImpression(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_object);
+
+absl::optional<blink::AttributionSrcToken>
+GetAttributionSrcTokenFromJavaImpression(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_object);
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_ANDROID_IMPRESSION_UTILS_H_
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc
index 38f318f..30e46d5 100644
--- a/content/browser/child_process_security_policy_impl.cc
+++ b/content/browser/child_process_security_policy_impl.cc
@@ -2613,9 +2613,15 @@
     const url::Origin& origin,
     bool is_origin_agent_cluster,
     bool requires_origin_keyed_process) {
-  DCHECK(is_origin_agent_cluster ||
-         base::FeatureList::IsEnabled(
-             blink::features::kOriginAgentClusterDefaultEnabled));
+  // This can only be called from the UI thread, as it reads state that's only
+  // available (and is only safe to be retrieved) on the UI thread, such as
+  // BrowsingInstance IDs.
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(
+      is_origin_agent_cluster ||
+      SiteIsolationPolicy::AreOriginAgentClustersEnabledByDefault(
+          isolation_context.browser_or_resource_context().ToBrowserContext()));
+
   // We ought to have validated the origin prior to getting here.  If the
   // origin isn't valid at this point, something has gone wrong.
   CHECK((is_origin_agent_cluster &&
@@ -2626,11 +2632,6 @@
         IsolatedOriginUtil::IsValidOriginForOptOutIsolation(origin))
       << "Trying to isolate invalid origin: " << origin;
 
-  // This can only be called from the UI thread, as it reads state that's only
-  // available (and is only safe to be retrieved) on the UI thread, such as
-  // BrowsingInstance IDs.
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
   BrowsingInstanceId browsing_instance_id(
       isolation_context.browsing_instance_id());
   // This function should only be called when a BrowsingInstance is registering
diff --git a/content/browser/devtools/protocol/native_input_event_builder.h b/content/browser/devtools/protocol/native_input_event_builder.h
index e522d6b..c72650a 100644
--- a/content/browser/devtools/protocol/native_input_event_builder.h
+++ b/content/browser/devtools/protocol/native_input_event_builder.h
@@ -8,13 +8,11 @@
 #include "build/build_config.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 
-namespace content {
-namespace protocol {
+namespace content::protocol {
 
 class NativeInputEventBuilder {
  public:
-#if BUILDFLAG(IS_MAC)
-  // This returned object has a retain count of 1.
+#if BUILDFLAG(IS_APPLE)
   static gfx::NativeEvent CreateEvent(const NativeWebKeyboardEvent& event);
 #else
   // We only need this for Macs because they require an OS event to process
@@ -25,7 +23,6 @@
 #endif
 };
 
-}  // namespace protocol
-}  // namespace content
+}  // namespace content::protocol
 
 #endif  // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_NATIVE_INPUT_EVENT_BUILDER_H_
diff --git a/content/browser/devtools/protocol/native_input_event_builder_ios.mm b/content/browser/devtools/protocol/native_input_event_builder_ios.mm
new file mode 100644
index 0000000..16726f56
--- /dev/null
+++ b/content/browser/devtools/protocol/native_input_event_builder_ios.mm
@@ -0,0 +1,19 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/protocol/native_input_event_builder.h"
+
+#include "base/apple/owned_objc.h"
+
+namespace content::protocol {
+
+gfx::NativeEvent NativeInputEventBuilder::CreateEvent(
+    const NativeWebKeyboardEvent& event) {
+  // We only need this for Macs because they require an OS event to process
+  // some keyboard events in browser (see: https://crbug.com/667387). TODO: Does
+  // this hold true for iOS Blink?
+  return base::apple::OwnedUIEvent();
+}
+
+}  // namespace content::protocol
diff --git a/content/browser/devtools/protocol/native_input_event_builder_mac.mm b/content/browser/devtools/protocol/native_input_event_builder_mac.mm
index a8f08dd9..04a58f51 100644
--- a/content/browser/devtools/protocol/native_input_event_builder_mac.mm
+++ b/content/browser/devtools/protocol/native_input_event_builder_mac.mm
@@ -6,16 +6,15 @@
 
 #include <algorithm>
 
+#include "base/apple/owned_objc.h"
 #include "base/strings/sys_string_conversions.h"
 #include "content/browser/devtools/protocol/native_input_event_builder.h"
 #include "third_party/blink/public/common/input/web_input_event.h"
 
-namespace content {
-namespace protocol {
+namespace content::protocol {
 
 // Mac requires a native event to emulate key events. This method gives
 // only crude capabilities (see: crbug.com/667387).
-// The returned object has a retain count of 1.
 gfx::NativeEvent NativeInputEventBuilder::CreateEvent(
     const NativeWebKeyboardEvent& event) {
   NSEventType type = NSEventTypeKeyUp;
@@ -41,17 +40,17 @@
       (modifiers & blink::WebInputEvent::kMetaKey ? NSEventModifierFlagCommand
                                                   : 0);
 
-  return [[NSEvent keyEventWithType:type
-                           location:NSZeroPoint
-                      modifierFlags:flags
-                          timestamp:0
-                       windowNumber:0
-                            context:nil
-                         characters:character
-        charactersIgnoringModifiers:character
-                          isARepeat:NO
-                            keyCode:event.native_key_code] retain];
+  return base::apple::OwnedNSEvent([NSEvent
+                 keyEventWithType:type
+                         location:NSZeroPoint
+                    modifierFlags:flags
+                        timestamp:0
+                     windowNumber:0
+                          context:nil
+                       characters:character
+      charactersIgnoringModifiers:character
+                        isARepeat:NO
+                          keyCode:event.native_key_code]);
 }
 
-}  // namespace protocol
-}  // namespace content
+}  // namespace content::protocol
diff --git a/content/browser/file_system_access/file_system_access_file_handle_impl_unittest.cc b/content/browser/file_system_access/file_system_access_file_handle_impl_unittest.cc
index ee12693..56e6081 100644
--- a/content/browser/file_system_access/file_system_access_file_handle_impl_unittest.cc
+++ b/content/browser/file_system_access/file_system_access_file_handle_impl_unittest.cc
@@ -194,7 +194,7 @@
     manager_ = base::MakeRefCounted<FileSystemAccessManagerImpl>(
         file_system_context_, chrome_blob_context_,
         /*permission_context=*/nullptr,
-        /*off_the_record=*/false);
+        /*off_the_record=*/is_incognito);
 
     handle_ = std::make_unique<FileSystemAccessFileHandleImpl>(
         manager_.get(),
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc
index cef85241..a9a56c7f 100644
--- a/content/browser/interest_group/auction_runner_unittest.cc
+++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -1974,6 +1974,8 @@
                 /*scoring_signals_data_version=*/absl::nullopt,
                 /*debug_loss_report_url=*/absl::nullopt,
                 /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+                /*scoring_latency=*/base::TimeDelta(),
+                /*trusted_signals_fetch_latency=*/base::TimeDelta(),
                 /*errors=*/{});
       }
     }
@@ -8488,6 +8490,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   score_ad_params = seller_worklet->WaitForScoreAd();
@@ -8504,6 +8508,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   // Finish the auction.
@@ -8757,6 +8763,8 @@
             /*scoring_signals_data_version=*/absl::nullopt,
             /*debug_loss_report_url=*/absl::nullopt,
             /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+            /*scoring_latency=*/base::TimeDelta(),
+            /*trusted_signals_fetch_latency=*/base::TimeDelta(),
             /*errors=*/{});
 
     // Finish the auction.
@@ -8991,6 +8999,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   // Top-level seller worklet scores the bid.
@@ -9011,6 +9021,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   // Top-level seller worklet returns a report url.
@@ -9203,6 +9215,8 @@
                             /*debug_loss_report_url=*/absl::nullopt,
                             /*debug_win_report_url=*/absl::nullopt,
                             /*pa_requests=*/{},
+                            /*scoring_latency=*/base::TimeDelta(),
+                            /*trusted_signals_fetch_latency=*/base::TimeDelta(),
                             /*errors=*/{});
 
     // The auction fails, because of the bad ComponentAuctionModifiedBidParams.
@@ -9272,6 +9286,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   auction_run_loop_->Run();
@@ -9348,6 +9364,8 @@
               /*scoring_signals_data_version=*/absl::nullopt,
               /*debug_loss_report_url=*/absl::nullopt,
               /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+              /*scoring_latency=*/base::TimeDelta(),
+              /*trusted_signals_fetch_latency=*/base::TimeDelta(),
               /*errors=*/{});
 
       // Finish the auction.
@@ -9460,6 +9478,8 @@
               /*scoring_signals_data_version=*/absl::nullopt,
               /*debug_loss_report_url=*/absl::nullopt,
               /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+              /*scoring_latency=*/base::TimeDelta(),
+              /*trusted_signals_fetch_latency=*/base::TimeDelta(),
               /*errors=*/{});
 
       // Finish the auction.
@@ -9816,6 +9836,8 @@
             /*scoring_signals_data_version=*/absl::nullopt,
             /*debug_loss_report_url=*/absl::nullopt,
             /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+            /*scoring_latency=*/base::TimeDelta(),
+            /*trusted_signals_fetch_latency=*/base::TimeDelta(),
             /*errors=*/{});
     auction_run_loop_->Run();
     EXPECT_EQ("Invalid bid_in_seller_currency", TakeBadMessage());
@@ -9863,6 +9885,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   // Finish the auction.
@@ -9936,6 +9960,8 @@
             /*scoring_signals_data_version=*/absl::nullopt,
             /*debug_loss_report_url=*/absl::nullopt,
             /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+            /*scoring_latency=*/base::TimeDelta(),
+            /*trusted_signals_fetch_latency=*/base::TimeDelta(),
             /*errors=*/{});
 
     // Bidder2 returns a bid, which is then scored.
@@ -9956,6 +9982,8 @@
             /*scoring_signals_data_version=*/absl::nullopt,
             /*debug_loss_report_url=*/absl::nullopt,
             /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+            /*scoring_latency=*/base::TimeDelta(),
+            /*trusted_signals_fetch_latency=*/base::TimeDelta(),
             /*errors=*/{});
     // Need to flush the service pipe to make sure the AuctionRunner has
     // received the score.
@@ -10095,6 +10123,8 @@
                     /*scoring_signals_data_version=*/absl::nullopt,
                     /*debug_loss_report_url=*/absl::nullopt,
                     /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+                    /*scoring_latency=*/base::TimeDelta(),
+                    /*trusted_signals_fetch_latency=*/base::TimeDelta(),
                     /*errors=*/{});
             // Wait for the AuctionRunner to receive the score.
             task_environment()->RunUntilIdle();
@@ -10113,6 +10143,8 @@
                     /*debug_loss_report_url=*/absl::nullopt,
                     /*debug_win_report_url=*/absl::nullopt,
                     /*pa_requests=*/{},
+                    /*scoring_latency=*/base::TimeDelta(),
+                    /*trusted_signals_fetch_latency=*/base::TimeDelta(),
                     /*errors=*/{});
             // Wait for the AuctionRunner to receive the score.
             task_environment()->RunUntilIdle();
@@ -10398,6 +10430,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   // Finish the auction.
@@ -10515,6 +10549,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   // Finish the auction.
@@ -11773,6 +11809,8 @@
             /*scoring_signals_data_version=*/absl::nullopt,
             /*debug_loss_report_url=*/absl::nullopt,
             /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+            /*scoring_latency=*/base::TimeDelta(),
+            /*trusted_signals_fetch_latency=*/base::TimeDelta(),
             /*errors=*/{});
 
     // Finish the auction.
@@ -12654,6 +12692,8 @@
           /*debug_loss_report_url=*/absl::nullopt,
           /*debug_win_report_url=*/absl::nullopt,
           std::move(score_ad_1_pa_requests),
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   PrivateAggregationRequests report_win_pa_requests;
@@ -12719,14 +12759,21 @@
     bidder_worklets[i]->SetBiddingLatency(base::Milliseconds(100 * i + 10));
 
     std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>
-        pa_requests;
-    pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+        bidder_pa_requests, seller_pa_requests;
+    bidder_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
         /*bucket=*/100 * i, auction_worklet::mojom::BaseValue::kScriptRunTime,
         "reserved.always"));
-    pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+    seller_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+        /*bucket=*/100 * i + 10,
+        auction_worklet::mojom::BaseValue::kScriptRunTime, "reserved.always"));
+    bidder_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
         /*bucket=*/100 * i + 1,
         auction_worklet::mojom::BaseValue::kSignalsFetchTime,
         "reserved.always"));
+    seller_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+        /*bucket=*/100 * i + 11,
+        auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+        "reserved.always"));
     bidder_worklets[i]->InvokeGenerateBidCallback(
         i + 1, /*bid_currency=*/absl::nullopt,
         blink::AdDescriptor(
@@ -12743,7 +12790,7 @@
         /*duration=*/base::Seconds(5),
         /*bidding_signals_data_version=*/absl::nullopt,
         /*debug_loss_report_url=*/absl::nullopt,
-        /*debug_win_report_url=*/absl::nullopt, std::move(pa_requests));
+        /*debug_win_report_url=*/absl::nullopt, std::move(bidder_pa_requests));
     auto score_ad_params = seller_worklet->WaitForScoreAd();
     mojo::Remote<auction_worklet::mojom::ScoreAdClient>(
         std::move(score_ad_params.score_ad_client))
@@ -12755,22 +12802,47 @@
             /*bid_in_seller_currency=*/absl::nullopt,
             /*scoring_signals_data_version=*/absl::nullopt,
             /*debug_loss_report_url=*/absl::nullopt,
-            /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+            /*debug_win_report_url=*/absl::nullopt,
+            /*pa_requests=*/std::move(seller_pa_requests),
+            /*scoring_latency=*/base::Milliseconds(100 * i + 20),
+            /*trusted_signals_fetch_latency=*/base::Milliseconds(100 * i + 21),
             /*errors=*/{});
   }
 
+  std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>
+      bidder_report_pa_requests, seller_report_pa_requests;
+  bidder_report_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/50, auction_worklet::mojom::BaseValue::kScriptRunTime,
+      "reserved.always"));
+  seller_report_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/60, auction_worklet::mojom::BaseValue::kScriptRunTime,
+      "reserved.always"));
+  bidder_report_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/51, auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+      "reserved.always"));
+  seller_report_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/61, auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+      "reserved.always"));
+
   // Need to flush the service pipe to make sure the AuctionRunner has
   // received the score.
   seller_worklet->Flush();
   seller_worklet->WaitForReportResult();
-  seller_worklet->InvokeReportResultCallback();
+  seller_worklet->SetReportingLatency(base::Milliseconds(200));
+  seller_worklet->InvokeReportResultCallback(
+      /*report_url=*/absl::nullopt,
+      /*ad_beacon_map=*/{}, std::move(seller_report_pa_requests));
   mock_auction_process_manager_->WaitForWinningBidderReload();
   auto winning_bidder_worklet =
       mock_auction_process_manager_->TakeBidderWorklet(kBidder2Url);
   ASSERT_TRUE(winning_bidder_worklet);
   winning_bidder_worklet->WaitForReportWin();
-  winning_bidder_worklet->InvokeReportWinCallback();
+  winning_bidder_worklet->SetReportingLatency(base::Milliseconds(250));
+  winning_bidder_worklet->InvokeReportWinCallback(
+      /*report_url=*/absl::nullopt,
+      /*ad_beacon_map=*/{}, std::move(bidder_report_pa_requests));
   auction_run_loop_->Run();
+
   EXPECT_THAT(
       private_aggregation_manager_.TakePrivateAggregationRequests(),
       testing::UnorderedElementsAre(
@@ -12780,12 +12852,239 @@
                                                                  /*value=*/10),
                                   BuildPrivateAggregationRequest(/*bucket=*/1,
                                                                  /*value=*/1))),
-          testing::Pair(kBidder2,
+          testing::Pair(
+              kBidder2,
+              ElementsAreRequests(BuildPrivateAggregationRequest(/*bucket=*/100,
+                                                                 /*value=*/110),
+                                  BuildPrivateAggregationRequest(/*bucket=*/101,
+                                                                 /*value=*/101),
+                                  BuildPrivateAggregationRequest(/*bucket=*/50,
+                                                                 /*value=*/250),
+                                  // No signals fetch for reporting, so
+                                  // value = 0.
+                                  BuildPrivateAggregationRequest(/*bucket=*/51,
+                                                                 /*value=*/0))),
+          testing::Pair(kSeller,
                         ElementsAreRequests(
-                            BuildPrivateAggregationRequest(/*bucket=*/100,
-                                                           /*value=*/110),
-                            BuildPrivateAggregationRequest(/*bucket=*/101,
-                                                           /*value=*/101)))));
+                            BuildPrivateAggregationRequest(/*bucket=*/10,
+                                                           /*value=*/20),
+                            BuildPrivateAggregationRequest(/*bucket=*/11,
+                                                           /*value=*/21),
+                            BuildPrivateAggregationRequest(/*bucket=*/110,
+                                                           /*value=*/120),
+                            BuildPrivateAggregationRequest(/*bucket=*/111,
+                                                           /*value=*/121),
+                            BuildPrivateAggregationRequest(/*bucket=*/60,
+                                                           /*value=*/200),
+                            // No signals fetch for reporting, so value = 0.
+                            BuildPrivateAggregationRequest(/*bucket=*/61,
+                                                           /*value=*/0)))));
+}
+
+TEST_F(AuctionRunnerTest, ComponentAuctionPrivateAggregationTimeMetrics) {
+  const int kNumBidders = 2;
+  UseMockWorkletService();
+
+  SetUpComponentAuctionAndResponses(/*bidder1_seller=*/kComponentSeller1,
+                                    /*bidder2_seller=*/kComponentSeller1,
+                                    /*bid_from_component_auction_wins=*/true,
+                                    /*report_post_auction_signals=*/false);
+
+  StartStandardAuction();
+  mock_auction_process_manager_->WaitForWorklets(kNumBidders,
+                                                 /*num_sellers=*/2);
+
+  auto component_seller_worklet =
+      mock_auction_process_manager_->TakeSellerWorklet(kComponentSeller1Url);
+  ASSERT_TRUE(component_seller_worklet);
+
+  auto top_seller_worklet =
+      mock_auction_process_manager_->TakeSellerWorklet(kSellerUrl);
+  ASSERT_TRUE(top_seller_worklet);
+
+  std::unique_ptr<MockBidderWorklet> bidder_worklets[2];
+  bidder_worklets[0] =
+      mock_auction_process_manager_->TakeBidderWorklet(kBidder1Url);
+  bidder_worklets[1] =
+      mock_auction_process_manager_->TakeBidderWorklet(kBidder2Url);
+
+  for (int i = 0; i < kNumBidders; ++i) {
+    ASSERT_TRUE(bidder_worklets[i]);
+    bidder_worklets[i]->SetBidderTrustedSignalsFetchLatency(
+        base::Milliseconds(100 * i + 1));
+    bidder_worklets[i]->SetBiddingLatency(base::Milliseconds(100 * i + 10));
+
+    std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>
+        bidder_pa_requests, component_seller_pa_requests;
+    bidder_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+        /*bucket=*/100 * i, auction_worklet::mojom::BaseValue::kScriptRunTime,
+        "reserved.always"));
+    component_seller_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+        /*bucket=*/100 * i + 10,
+        auction_worklet::mojom::BaseValue::kScriptRunTime, "reserved.always"));
+    bidder_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+        /*bucket=*/100 * i + 1,
+        auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+        "reserved.always"));
+    component_seller_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+        /*bucket=*/100 * i + 11,
+        auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+        "reserved.always"));
+    bidder_worklets[i]->InvokeGenerateBidCallback(
+        i + 1, /*bid_currency=*/absl::nullopt,
+        blink::AdDescriptor(
+            GURL(base::StringPrintf("https://ad%d.com/", i + 1))),
+        auction_worklet::mojom::BidderWorkletKAnonEnforcedBidPtr(),
+        /*ad_component_descriptors=*/absl::nullopt,
+        /*duration=*/base::Seconds(5),
+        /*bidding_signals_data_version=*/absl::nullopt,
+        /*debug_loss_report_url=*/absl::nullopt,
+        /*debug_win_report_url=*/absl::nullopt, std::move(bidder_pa_requests));
+
+    auto component_score_ad_params = component_seller_worklet->WaitForScoreAd();
+    mojo::Remote<auction_worklet::mojom::ScoreAdClient>(
+        std::move(component_score_ad_params.score_ad_client))
+        ->OnScoreAdComplete(
+            /*score=*/i + 1,
+            /*reject_reason=*/
+            auction_worklet::mojom::RejectReason::kNotAvailable,
+            auction_worklet::mojom::ComponentAuctionModifiedBidParams::New(),
+            /*bid_in_seller_currency=*/absl::nullopt,
+            /*scoring_signals_data_version=*/absl::nullopt,
+            /*debug_loss_report_url=*/absl::nullopt,
+            /*debug_win_report_url=*/absl::nullopt,
+            /*pa_requests=*/std::move(component_seller_pa_requests),
+            /*scoring_latency=*/base::Milliseconds(100 * i + 20),
+            /*trusted_signals_fetch_latency=*/base::Milliseconds(100 * i + 21),
+            /*errors=*/{});
+  }
+
+  std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>
+      top_seller_pa_requests;
+  top_seller_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/20, auction_worklet::mojom::BaseValue::kScriptRunTime,
+      "reserved.always"));
+  top_seller_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/21, auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+      "reserved.always"));
+
+  auto top_score_ad_params = top_seller_worklet->WaitForScoreAd();
+  mojo::Remote<auction_worklet::mojom::ScoreAdClient>(
+      std::move(top_score_ad_params.score_ad_client))
+      ->OnScoreAdComplete(
+          /*score=*/1,
+          /*reject_reason=*/
+          auction_worklet::mojom::RejectReason::kNotAvailable,
+          auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
+          /*bid_in_seller_currency=*/absl::nullopt,
+          /*scoring_signals_data_version=*/absl::nullopt,
+          /*debug_loss_report_url=*/absl::nullopt,
+          /*debug_win_report_url=*/absl::nullopt,
+          /*pa_requests=*/std::move(top_seller_pa_requests),
+          /*scoring_latency=*/base::Milliseconds(30),
+          /*trusted_signals_fetch_latency=*/base::Milliseconds(31),
+          /*errors=*/{});
+
+  std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>
+      bidder_report_pa_requests, component_seller_report_pa_requests,
+      top_seller_report_pa_requests;
+  bidder_report_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/50, auction_worklet::mojom::BaseValue::kScriptRunTime,
+      "reserved.always"));
+  component_seller_report_pa_requests.push_back(
+      BuildPrivateAggregationForBaseValue(
+          /*bucket=*/60, auction_worklet::mojom::BaseValue::kScriptRunTime,
+          "reserved.always"));
+  top_seller_report_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/70, auction_worklet::mojom::BaseValue::kScriptRunTime,
+      "reserved.always"));
+  bidder_report_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/51, auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+      "reserved.always"));
+  component_seller_report_pa_requests.push_back(
+      BuildPrivateAggregationForBaseValue(
+          /*bucket=*/61, auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+          "reserved.always"));
+  top_seller_report_pa_requests.push_back(BuildPrivateAggregationForBaseValue(
+      /*bucket=*/71, auction_worklet::mojom::BaseValue::kSignalsFetchTime,
+      "reserved.always"));
+
+  top_seller_worklet->WaitForReportResult();
+  top_seller_worklet->SetReportingLatency(base::Milliseconds(200));
+  top_seller_worklet->InvokeReportResultCallback(
+      /*report_url=*/absl::nullopt,
+      /*ad_beacon_map=*/{}, std::move(top_seller_report_pa_requests));
+
+  mock_auction_process_manager_->WaitForWinningSellerReload();
+  component_seller_worklet =
+      mock_auction_process_manager_->TakeSellerWorklet(kComponentSeller1Url);
+  component_seller_worklet->set_expect_send_pending_signals_requests_called(
+      false);
+  component_seller_worklet->WaitForReportResult();
+  component_seller_worklet->SetReportingLatency(base::Milliseconds(250));
+  component_seller_worklet->InvokeReportResultCallback(
+      /*report_url=*/absl::nullopt,
+      /*ad_beacon_map=*/{}, std::move(component_seller_report_pa_requests));
+
+  mock_auction_process_manager_->WaitForWinningBidderReload();
+  auto winning_bidder_worklet =
+      mock_auction_process_manager_->TakeBidderWorklet(kBidder2Url);
+  ASSERT_TRUE(winning_bidder_worklet);
+  winning_bidder_worklet->WaitForReportWin();
+  winning_bidder_worklet->SetReportingLatency(base::Milliseconds(300));
+  winning_bidder_worklet->InvokeReportWinCallback(
+      /*report_url=*/absl::nullopt,
+      /*ad_beacon_map=*/{}, std::move(bidder_report_pa_requests));
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(
+      private_aggregation_manager_.TakePrivateAggregationRequests(),
+      testing::UnorderedElementsAre(
+          testing::Pair(
+              kBidder1,
+              ElementsAreRequests(BuildPrivateAggregationRequest(/*bucket=*/0,
+                                                                 /*value=*/10),
+                                  BuildPrivateAggregationRequest(/*bucket=*/1,
+                                                                 /*value=*/1))),
+          testing::Pair(
+              kBidder2,
+              ElementsAreRequests(BuildPrivateAggregationRequest(/*bucket=*/100,
+                                                                 /*value=*/110),
+                                  BuildPrivateAggregationRequest(/*bucket=*/101,
+                                                                 /*value=*/101),
+                                  BuildPrivateAggregationRequest(/*bucket=*/50,
+                                                                 /*value=*/300),
+                                  // No signals fetch for reporting,
+                                  // so value = 0.
+                                  BuildPrivateAggregationRequest(/*bucket=*/51,
+                                                                 /*value=*/0))),
+          testing::Pair(
+              kComponentSeller1,
+              ElementsAreRequests(BuildPrivateAggregationRequest(/*bucket=*/10,
+                                                                 /*value=*/20),
+                                  BuildPrivateAggregationRequest(/*bucket=*/11,
+                                                                 /*value=*/21),
+                                  BuildPrivateAggregationRequest(/*bucket=*/110,
+                                                                 /*value=*/120),
+                                  BuildPrivateAggregationRequest(/*bucket=*/111,
+                                                                 /*value=*/121),
+                                  BuildPrivateAggregationRequest(/*bucket=*/60,
+                                                                 /*value=*/250),
+                                  // No signals fetch for reporting,
+                                  // so value = 0.
+                                  BuildPrivateAggregationRequest(/*bucket=*/61,
+                                                                 /*value=*/0))),
+          testing::Pair(kSeller,
+                        ElementsAreRequests(
+                            BuildPrivateAggregationRequest(/*bucket=*/20,
+                                                           /*value=*/30),
+                            BuildPrivateAggregationRequest(/*bucket=*/21,
+                                                           /*value=*/31),
+                            BuildPrivateAggregationRequest(/*bucket=*/70,
+                                                           /*value=*/200),
+                            // No signals fetch for reporting, so value = 0.
+                            BuildPrivateAggregationRequest(/*bucket=*/71,
+                                                           /*value=*/0)))));
 }
 
 TEST_F(AuctionRunnerTest,
@@ -15884,6 +16183,8 @@
             /*scoring_signals_data_version=*/absl::nullopt,
             test_case.seller_debug_loss_report_url,
             test_case.seller_debug_win_report_url, /*pa_requests=*/{},
+            /*scoring_latency=*/base::TimeDelta(),
+            /*trusted_signals_fetch_latency=*/base::TimeDelta(),
             /*errors=*/{});
     auction_run_loop_->Run();
     EXPECT_EQ(test_case.expected_error_message, TakeBadMessage());
@@ -15953,6 +16254,8 @@
           /*scoring_signals_data_version=*/absl::nullopt,
           GURL("https://seller-debug-loss-reporting.com/1"),
           GURL("https://seller-debug-win-reporting.com/1"), /*pa_requests=*/{},
+          /*scoring_latency=*/base::TimeDelta(),
+          /*trusted_signals_fetch_latency=*/base::TimeDelta(),
           /*errors=*/{});
 
   seller_worklet->WaitForReportResult();
@@ -17576,6 +17879,8 @@
             /*scoring_signals_data_version=*/absl::nullopt,
             /*debug_loss_report_url=*/absl::nullopt,
             /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{},
+            /*scoring_latency=*/base::TimeDelta(),
+            /*trusted_signals_fetch_latency=*/base::TimeDelta(),
             /*errors=*/{});
 
     // Finish the auction.
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc
index 5db67e39..336069cdac 100644
--- a/content/browser/interest_group/interest_group_auction.cc
+++ b/content/browser/interest_group/interest_group_auction.cc
@@ -3196,6 +3196,8 @@
     const absl::optional<GURL>& debug_loss_report_url,
     const absl::optional<GURL>& debug_win_report_url,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta scoring_latency,
+    base::TimeDelta trusted_signals_fetch_latency,
     const std::vector<std::string>& errors) {
   DCHECK_GT(bids_being_scored_, 0);
 
@@ -3217,6 +3219,9 @@
   } else {
     bid->bid_state->EndTracing();
   }
+  bid->bid_state->pa_timings(seller_phase()).script_run_time = scoring_latency;
+  bid->bid_state->pa_timings(seller_phase()).signals_fetch_time =
+      trusted_signals_fetch_latency;
 
   --bids_being_scored_;
 
diff --git a/content/browser/interest_group/interest_group_auction.h b/content/browser/interest_group/interest_group_auction.h
index 9aa8869..d64082e3 100644
--- a/content/browser/interest_group/interest_group_auction.h
+++ b/content/browser/interest_group/interest_group_auction.h
@@ -804,6 +804,8 @@
       const absl::optional<GURL>& debug_loss_report_url,
       const absl::optional<GURL>& debug_win_report_url,
       PrivateAggregationRequests pa_requests,
+      base::TimeDelta scoring_latency,
+      base::TimeDelta trusted_signals_fetch_latency,
       const std::vector<std::string>& errors) override;
 
   PrivateAggregationPhase seller_phase() const {
diff --git a/content/browser/interest_group/interest_group_auction_reporter.cc b/content/browser/interest_group/interest_group_auction_reporter.cc
index ecd053e7..e88c1779 100644
--- a/content/browser/interest_group/interest_group_auction_reporter.cc
+++ b/content/browser/interest_group/interest_group_auction_reporter.cc
@@ -315,7 +315,8 @@
                                /*signals_for_winner=*/absl::nullopt,
                                /*seller_report_url=*/absl::nullopt,
                                /*seller_ad_beacon_map=*/{},
-                               /*pa_requests=*/{}, errors);
+                               /*pa_requests=*/{},
+                               /*reporting_latency=*/base::TimeDelta(), errors);
 }
 
 void InterestGroupAuctionReporter::OnSellerWorkletReceived(
@@ -422,6 +423,7 @@
     const absl::optional<GURL>& seller_report_url,
     const base::flat_map<std::string, GURL>& seller_ad_beacon_map,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta reporting_latency,
     const std::vector<std::string>& errors) {
   TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "seller_worklet_report_result",
                                   seller_info->trace_id);
@@ -436,6 +438,8 @@
   log_private_aggregation_requests_callback_.Run(pa_requests);
 
   const url::Origin& seller = seller_info->auction_config->seller;
+  PrivateAggregationTimings timings;
+  timings.script_run_time = reporting_latency;
   for (auction_worklet::mojom::PrivateAggregationRequestPtr& request :
        pa_requests) {
     // reportResult() only gets executed for seller when there was an auction
@@ -446,7 +450,7 @@
     absl::optional<PrivateAggregationRequestWithEventType> converted_request =
         FillInPrivateAggregationRequest(
             std::move(request), winning_bid, highest_scoring_other_bid,
-            /*reject_reason=*/absl::nullopt, PrivateAggregationTimings(),
+            /*reject_reason=*/absl::nullopt, timings,
             /*is_winner=*/true);
 
     // Only private aggregation requests with reserved event types are kept for
@@ -675,7 +679,8 @@
                             /*highest_scoring_other_bid=*/0.0,
                             /*bidder_report_url=*/absl::nullopt,
                             /*bidder_ad_beacon_map=*/{},
-                            /*pa_requests=*/{}, errors);
+                            /*pa_requests=*/{},
+                            /*reporting_latency=*/base::TimeDelta(), errors);
 }
 
 void InterestGroupAuctionReporter::OnBidderReportWinComplete(
@@ -684,6 +689,7 @@
     const absl::optional<GURL>& bidder_report_url,
     const base::flat_map<std::string, GURL>& bidder_ad_beacon_map,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta reporting_latency,
     const std::vector<std::string>& errors) {
   TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "bidder_worklet_report_win",
                                   top_level_seller_winning_bid_info_.trace_id);
@@ -702,6 +708,8 @@
 
   const url::Origin& bidder =
       winning_bid_info_.storage_interest_group->interest_group.owner;
+  PrivateAggregationTimings timings;
+  timings.script_run_time = reporting_latency;
   for (auction_worklet::mojom::PrivateAggregationRequestPtr& request :
        pa_requests) {
     // Only winner's reportWin() gets executed, so is_winner is true, which
@@ -712,7 +720,7 @@
         FillInPrivateAggregationRequest(
             std::move(request), winning_bid,
             /*highest_scoring_other_bid=*/highest_scoring_other_bid,
-            /*reject_reason=*/absl::nullopt, PrivateAggregationTimings(),
+            /*reject_reason=*/absl::nullopt, timings,
             /*is_winner=*/true);
 
     if (converted_request.has_value()) {
diff --git a/content/browser/interest_group/interest_group_auction_reporter.h b/content/browser/interest_group/interest_group_auction_reporter.h
index 3edd2e8f..34c865f 100644
--- a/content/browser/interest_group/interest_group_auction_reporter.h
+++ b/content/browser/interest_group/interest_group_auction_reporter.h
@@ -322,6 +322,7 @@
       const absl::optional<GURL>& seller_report_url,
       const base::flat_map<std::string, GURL>& seller_ad_beacon_map,
       PrivateAggregationRequests pa_requests,
+      base::TimeDelta reporting_latency,
       const std::vector<std::string>& errors);
 
   // Starts request for a bidder worklet. Invokes OnBidderWorkletReceived() on
@@ -347,6 +348,7 @@
       const absl::optional<GURL>& bidder_report_url,
       const base::flat_map<std::string, GURL>& bidder_ad_beacon_map,
       PrivateAggregationRequests pa_requests,
+      base::TimeDelta reporting_latency,
       const std::vector<std::string>& errors);
 
   // Sets `reporting_complete_` to true an invokes MaybeCompleteCallback().
diff --git a/content/browser/interest_group/mock_auction_process_manager.cc b/content/browser/interest_group/mock_auction_process_manager.cc
index fb4b7c9a..4de11cd 100644
--- a/content/browser/interest_group/mock_auction_process_manager.cc
+++ b/content/browser/interest_group/mock_auction_process_manager.cc
@@ -290,7 +290,7 @@
   DCHECK(report_win_callback_);
   std::move(report_win_callback_)
       .Run(report_url, ad_beacon_map, std::move(pa_requests),
-           std::move(errors));
+           reporting_latency_, std::move(errors));
 }
 
 void MockBidderWorklet::Flush() {
@@ -451,7 +451,7 @@
   DCHECK(report_result_callback_);
   std::move(report_result_callback_)
       .Run(/*signals_for_winner=*/absl::nullopt, std::move(report_url),
-           ad_beacon_map, std::move(pa_requests), errors);
+           ad_beacon_map, std::move(pa_requests), reporting_latency_, errors);
 }
 
 void MockSellerWorklet::Flush() {
diff --git a/content/browser/interest_group/mock_auction_process_manager.h b/content/browser/interest_group/mock_auction_process_manager.h
index 4f40dcc8..a50acf20 100644
--- a/content/browser/interest_group/mock_auction_process_manager.h
+++ b/content/browser/interest_group/mock_auction_process_manager.h
@@ -123,6 +123,11 @@
   void SetBidderTrustedSignalsFetchLatency(base::TimeDelta delta);
   void SetBiddingLatency(base::TimeDelta delta);
 
+  // Same for `reporting_latency` for ReportWin()
+  void SetReportingLatency(base::TimeDelta delta) {
+    reporting_latency_ = delta;
+  }
+
   // Invokes the GenerateBid callback. A bid of base::nullopt means no bid
   // should be offered. Waits for the GenerateBid() call first, if needed.
   void InvokeGenerateBidCallback(
@@ -191,6 +196,9 @@
   base::TimeDelta trusted_signals_fetch_latency_;
   base::TimeDelta bidding_latency_;
 
+  // To be fed as `reporting_latency` to ReportWin() callback.
+  base::TimeDelta reporting_latency_;
+
   // Receiver is last so that destroying `this` while there's a pending callback
   // over the pipe will not DCHECK.
   mojo::Receiver<auction_worklet::mojom::BidderWorklet> receiver_;
@@ -281,6 +289,12 @@
   // Waits until ReportResult() has been invoked, if it hasn't been already.
   void WaitForReportResult();
 
+  // Configures `reporting_latency` passed to ReportResult by
+  // InvokeReportResultCallback.
+  void SetReportingLatency(base::TimeDelta delta) {
+    reporting_latency_ = delta;
+  }
+
   // Invokes the ReportResultCallback for the most recent ScoreAd() call with
   // the provided score. WaitForReportResult() must have been invoked first.
   void InvokeReportResultCallback(
@@ -310,6 +324,9 @@
   bool expect_send_pending_signals_requests_called_ = true;
   bool send_pending_signals_requests_called_ = false;
 
+  // To be fed as `reporting_latency` to ReportResult() callback.
+  base::TimeDelta reporting_latency_;
+
   // Receiver is last so that destroying `this` while there's a pending callback
   // over the pipe will not DCHECK.
   mojo::Receiver<auction_worklet::mojom::SellerWorklet> receiver_;
diff --git a/content/browser/loader/cross_site_document_blocking_browsertest.cc b/content/browser/loader/cross_site_document_blocking_browsertest.cc
index 4b9fedf..dc0b27a 100644
--- a/content/browser/loader/cross_site_document_blocking_browsertest.cc
+++ b/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -640,6 +640,8 @@
   EXPECT_EQ("", interceptor.response_body());
 }
 
+// TODO(crbug.com/1448564): Remove support for old header names once API users
+// have switched.
 IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest,
                        FledgeAuctionOnlySignalsNotReadableFromFetch) {
   embedded_test_server()->StartAcceptingConnections();
@@ -663,6 +665,54 @@
   EXPECT_EQ("", interceptor.response_body());
 }
 
+IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest,
+                       FledgeAuctionOnlySignalsNotReadableFromFetchNewName) {
+  embedded_test_server()->StartAcceptingConnections();
+
+  // Navigate to the test page while request interceptor is active.
+  // Note that even same origin requests are blocked.
+  GURL resource_url("http://foo.com/interest_group/auction_only_new_name.json");
+  RequestInterceptor interceptor(resource_url);
+  EXPECT_TRUE(NavigateToURL(shell(), GURL("http://foo.com/title1.html")));
+
+  // Issue the request that will be intercepted.
+  const char kScriptTemplate[] = "fetch($1)";
+  EXPECT_TRUE(ExecJs(shell(), JsReplace(kScriptTemplate, resource_url),
+                     content::EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
+  interceptor.WaitForRequestCompletion();
+
+  // Verify that Ad-Auction-Only blocked the response before it reached the
+  // renderer process.
+  EXPECT_EQ(net::ERR_BLOCKED_BY_RESPONSE,
+            interceptor.completion_status().error_code);
+  EXPECT_EQ("", interceptor.response_body());
+}
+
+IN_PROC_BROWSER_TEST_P(
+    CrossSiteDocumentBlockingTest,
+    FledgeAuctionOnlySignalsNotReadableFromFetchBothNewAndOldNames) {
+  embedded_test_server()->StartAcceptingConnections();
+
+  // Navigate to the test page while request interceptor is active.
+  // Note that even same origin requests are blocked.
+  GURL resource_url(
+      "http://foo.com/interest_group/auction_only_both_new_and_old_names.json");
+  RequestInterceptor interceptor(resource_url);
+  EXPECT_TRUE(NavigateToURL(shell(), GURL("http://foo.com/title1.html")));
+
+  // Issue the request that will be intercepted.
+  const char kScriptTemplate[] = "fetch($1)";
+  EXPECT_TRUE(ExecJs(shell(), JsReplace(kScriptTemplate, resource_url),
+                     content::EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
+  interceptor.WaitForRequestCompletion();
+
+  // Verify that Ad-Auction-Only and X-FLEDGE-Auction-Only blocked the response
+  // before it reached the renderer process.
+  EXPECT_EQ(net::ERR_BLOCKED_BY_RESPONSE,
+            interceptor.completion_status().error_code);
+  EXPECT_EQ("", interceptor.response_body());
+}
+
 IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest, AllowCorsFetches) {
   embedded_test_server()->StartAcceptingConnections();
   GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
@@ -1539,6 +1589,8 @@
       << "PNG in a same-origin webbundle should not be blocked";
 }
 
+// TODO(crbug.com/1448564): Remove support for old header names once API users
+// have switched.
 IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingWebBundleTest,
                        FledgeAuctionOnlySignalsNotReadableFromFetchWebBundle) {
   https_server()->StartAcceptingConnections();
@@ -1564,4 +1616,58 @@
   EXPECT_EQ("", interceptor.response_body());
 }
 
+IN_PROC_BROWSER_TEST_F(
+    CrossSiteDocumentBlockingWebBundleTest,
+    FledgeAuctionOnlySignalsNotReadableFromFetchWebBundleNewName) {
+  https_server()->StartAcceptingConnections();
+
+  // Navigate to the test page while request interceptor is active.
+  // Note that even same origin requests are blocked.
+  GURL subresource_url(
+      "https://foo.com/interest_group/auction_only_in_bundle.json");
+  RequestInterceptor interceptor(subresource_url);
+  EXPECT_TRUE(NavigateToURL(
+      shell(),
+      GURL("https://foo.com/interest_group/auction_only_new_name.html")));
+
+  // Issue the request that will be intercepted.
+  const char kScriptTemplate[] = "fetch($1)";
+  EXPECT_TRUE(ExecJs(shell(), JsReplace(kScriptTemplate, subresource_url),
+                     content::EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
+  interceptor.WaitForRequestCompletion();
+
+  // Verify that Ad-Auction-Only blocked the response before it
+  // reached the renderer process.
+  EXPECT_EQ(net::ERR_BLOCKED_BY_RESPONSE,
+            interceptor.completion_status().error_code);
+  EXPECT_EQ("", interceptor.response_body());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    CrossSiteDocumentBlockingWebBundleTest,
+    FledgeAuctionOnlySignalsNotReadableFromFetchWebBundleBothNewAndOldNames) {
+  https_server()->StartAcceptingConnections();
+
+  // Navigate to the test page while request interceptor is active.
+  // Note that even same origin requests are blocked.
+  GURL subresource_url(
+      "https://foo.com/interest_group/auction_only_in_bundle.json");
+  RequestInterceptor interceptor(subresource_url);
+  EXPECT_TRUE(
+      NavigateToURL(shell(), GURL("https://foo.com/interest_group/"
+                                  "auction_only_both_new_and_old_names.html")));
+
+  // Issue the request that will be intercepted.
+  const char kScriptTemplate[] = "fetch($1)";
+  EXPECT_TRUE(ExecJs(shell(), JsReplace(kScriptTemplate, subresource_url),
+                     content::EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
+  interceptor.WaitForRequestCompletion();
+
+  // Verify that both Ad-Auction-Only and X-FLEDGE-Auction-Only blocked the
+  // response before it reached the renderer process.
+  EXPECT_EQ(net::ERR_BLOCKED_BY_RESPONSE,
+            interceptor.completion_status().error_code);
+  EXPECT_EQ("", interceptor.response_body());
+}
+
 }  // namespace content
diff --git a/content/browser/media/webaudio/OWNERS b/content/browser/media/webaudio/OWNERS
index a7db251..32f919a5 100644
--- a/content/browser/media/webaudio/OWNERS
+++ b/content/browser/media/webaudio/OWNERS
@@ -1,3 +1,4 @@
 hongchan@chromium.org
 mjwilson@chromium.org
-alvinji@chromium.org
\ No newline at end of file
+alvinji@chromium.org
+sinafirooz@chromium.org
\ No newline at end of file
diff --git a/content/browser/network/shared_dictionary_browsertest.cc b/content/browser/network/shared_dictionary_browsertest.cc
index 00f418e..4a753e6 100644
--- a/content/browser/network/shared_dictionary_browsertest.cc
+++ b/content/browser/network/shared_dictionary_browsertest.cc
@@ -6,6 +6,8 @@
 #include "base/files/file_util.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/path_service.h"
+#include "base/strings/strcat.h"
+#include "base/strings/stringprintf.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
@@ -15,7 +17,10 @@
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/url_loader_interceptor.h"
 #include "content/shell/browser/shell.h"
+#include "net/base/url_util.h"
+#include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "third_party/blink/public/common/features.h"
 
@@ -23,40 +28,70 @@
 
 namespace {
 
-void WaitForHistogram(const std::string& histogram_name) {
+// Generated by:
+//  tools/origin_trials/generate_token.py --version 3 --expire-days 3650 \
+//      https://shared-dictionary.test CompressionDictionaryTransport
+// Token details:
+//  Version: 3
+//  Origin: https://shared-dictionary.test:443
+//  Is Subdomain: None
+//  Is Third Party: None
+//  Usage Restriction: None
+//  Feature: CompressionDictionaryTransport
+//  Expiry: 1999843820 (2033-05-16 08:10:20 UTC)
+//  Signature (Base64):
+//      rQhlXQ0eRMV/mXUd7hJ3M+kVYMcsH4YKt2Tk6aNuUwKLooNKKLi0cQLrGnTB6sVPV/pryxXV
+//      DNJ9HZ1z8KNzCw==
+constexpr char kOriginTrialToken[] =
+    "A60IZV0NHkTFf5l1He4SdzPpFWDHLB+GCrdk5OmjblMCi6KDSii4tHEC6xp0werFT1f6a8sV1Q"
+    "zSfR2dc/CjcwsAAABzeyJvcmlnaW4iOiAiaHR0cHM6Ly9zaGFyZWQtZGljdGlvbmFyeS50ZXN0"
+    "OjQ0MyIsICJmZWF0dXJlIjogIkNvbXByZXNzaW9uRGljdGlvbmFyeVRyYW5zcG9ydCIsICJleH"
+    "BpcnkiOiAxOTk5ODQzODIwfQ==";
+
+bool WaitForHistogram(const std::string& histogram_name,
+                      absl::optional<base::TimeDelta> timeout = absl::nullopt) {
   // Need the polling of histogram because ScopedHistogramSampleObserver doesn't
   // support cross process metrics.
+  base::Time start_time = base::Time::Now();
   while (!base::StatisticsRecorder::FindHistogram(histogram_name)) {
     content::FetchHistogramsFromChildProcesses();
     base::PlatformThread::Sleep(base::Milliseconds(5));
+    if (timeout && base::Time::Now() > start_time + *timeout) {
+      return false;
+    }
   }
+  return true;
 }
 
+enum class FeatureState { kDisabled, kBackendOnly, kFullyEnabled };
 enum class BrowserType { kNormal, kOffTheRecord };
+enum class FetchType { kLinkRelDictionary, kFetchApi };
 
-// Tests end to end functionality of "compression dictionary transport" feature.
-class SharedDictionaryBrowserTest
-    : public ContentBrowserTest,
-      public ::testing::WithParamInterface<BrowserType> {
+std::string LinkRelDictionaryScript(const GURL& dictionary_url) {
+  return JsReplace(R"(
+              (()=>{
+                const link = document.createElement('link');
+                link.rel = 'dictionary';
+                link.href = $1;
+                document.body.appendChild(link);
+              })();
+            )",
+                   dictionary_url);
+}
+
+std::string FetchDictionaryScript(const GURL& dictionary_url) {
+  return JsReplace("fetch($1);", dictionary_url);
+}
+
+class SharedDictionaryBrowserTestBase : public ContentBrowserTest {
  public:
-  SharedDictionaryBrowserTest() {
-    scoped_feature_list_.InitWithFeatures(
-        /*enabled_features=*/{blink::features::kCompressionDictionaryTransport,
-                              blink::features::
-                                  kCompressionDictionaryTransportBackend},
-        /*disabled_features=*/{});
-  }
-  SharedDictionaryBrowserTest(const SharedDictionaryBrowserTest&) = delete;
-  SharedDictionaryBrowserTest& operator=(const SharedDictionaryBrowserTest&) =
+  SharedDictionaryBrowserTestBase() = default;
+  SharedDictionaryBrowserTestBase(const SharedDictionaryBrowserTestBase&) =
       delete;
-  // ContentBrowserTest implementation:
-  void SetUpOnMainThread() override {
-    ASSERT_TRUE(embedded_test_server()->Start());
-  }
+  SharedDictionaryBrowserTestBase& operator=(
+      const SharedDictionaryBrowserTestBase&) = delete;
 
  protected:
-  BrowserType GetBrowserType() const { return GetParam(); }
-
   int64_t GetTestDataFileSize(const std::string& name) {
     base::FilePath file_path;
     CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
@@ -70,6 +105,200 @@
     return file_size;
   }
 
+  void RunWriteDictionaryTest(Shell* shell,
+                              FetchType fetch_type,
+                              const GURL& page_url,
+                              const GURL& dictionary_url,
+                              const std::string& histogram_name,
+                              bool expect_success) {
+    EXPECT_TRUE(NavigateToURL(shell, page_url));
+    base::HistogramTester histogram_tester;
+    std::string script;
+    switch (fetch_type) {
+      case FetchType::kLinkRelDictionary:
+        script = LinkRelDictionaryScript(dictionary_url);
+        break;
+      case FetchType::kFetchApi:
+        script = FetchDictionaryScript(dictionary_url);
+        break;
+    }
+    EXPECT_TRUE(ExecJs(shell->web_contents()->GetPrimaryMainFrame(), script));
+
+    if (!expect_success) {
+      EXPECT_FALSE(WaitForHistogram(histogram_name, base::Milliseconds(100)));
+      return;
+    }
+    EXPECT_TRUE(WaitForHistogram(histogram_name));
+    histogram_tester.ExpectBucketCount(
+        histogram_name, GetTestDataFileSize("shared_dictionary/test.dict"),
+        /*expected_count=*/1);
+  }
+};
+
+// Tests end to end functionality of "compression dictionary transport" feature
+// with FeatureState of params.
+// TODO(crbug.com/1413922): Remove this when we fully launch this feature.
+class SharedDictionaryFeatureStateBrowserTest
+    : public SharedDictionaryBrowserTestBase,
+      public ::testing::WithParamInterface<FeatureState> {
+ public:
+  SharedDictionaryFeatureStateBrowserTest() {
+    std::vector<base::test::FeatureRef> enabled_features;
+    switch (GetFeatureState()) {
+      case FeatureState::kDisabled:
+        break;
+      case FeatureState::kBackendOnly:
+        enabled_features.emplace_back(
+            blink::features::kCompressionDictionaryTransportBackend);
+        break;
+      case FeatureState::kFullyEnabled:
+        enabled_features.emplace_back(
+            blink::features::kCompressionDictionaryTransportBackend);
+        enabled_features.emplace_back(
+            blink::features::kCompressionDictionaryTransport);
+        break;
+    }
+    scoped_feature_list_.InitWithFeatures(enabled_features,
+                                          /*disabled_features=*/{});
+  }
+  SharedDictionaryFeatureStateBrowserTest(
+      const SharedDictionaryFeatureStateBrowserTest&) = delete;
+  SharedDictionaryFeatureStateBrowserTest& operator=(
+      const SharedDictionaryFeatureStateBrowserTest&) = delete;
+
+  // ContentBrowserTest implementation:
+  void SetUpOnMainThread() override {
+    https_server_ = std::make_unique<net::EmbeddedTestServer>(
+        net::test_server::EmbeddedTestServer::TYPE_HTTPS);
+    https_server_->AddDefaultHandlers(GetTestDataFilePath());
+    ASSERT_TRUE(https_server_->Start());
+    SharedDictionaryBrowserTestBase::SetUpOnMainThread();
+
+    // Need to use URLLoaderInterceptor to test the behavior of Origin Trial.
+    url_loader_interceptor_.emplace(base::BindRepeating(
+        &SharedDictionaryFeatureStateBrowserTest::InterceptRequest));
+  }
+
+  void TearDownOnMainThread() override { url_loader_interceptor_.reset(); }
+
+ protected:
+  FeatureState GetFeatureState() const { return GetParam(); }
+  net::EmbeddedTestServer* https_server() { return https_server_.get(); }
+
+ private:
+  // URLLoaderInterceptor callback
+  static bool InterceptRequest(URLLoaderInterceptor::RequestParams* params) {
+    if (params->url_request.url.path() != "/blank.html") {
+      return false;
+    }
+    // Find the appropriate origin trial token.
+    base::StringPiece origin_trial_token;
+    std::string origin_trial_query_param;
+    if (net::GetValueForKeyInQuery(params->url_request.url, "ot",
+                                   &origin_trial_query_param)) {
+      if (origin_trial_query_param == "enabled") {
+        origin_trial_token = kOriginTrialToken;
+      }
+    }
+
+    // Construct and send the response.
+    std::string headers =
+        "HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\n";
+    if (!origin_trial_token.empty()) {
+      base::StrAppend(&headers, {"Origin-Trial: ", origin_trial_token, "\n"});
+    }
+    headers += '\n';
+    std::string body = "<!DOCTYPE html><body>Hello world!</body>";
+    URLLoaderInterceptor::WriteResponse(headers, body, params->client.get());
+    return true;
+  }
+
+  std::unique_ptr<net::EmbeddedTestServer> https_server_;
+  base::test::ScopedFeatureList scoped_feature_list_;
+  absl::optional<URLLoaderInterceptor> url_loader_interceptor_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         SharedDictionaryFeatureStateBrowserTest,
+                         testing::Values(FeatureState::kDisabled,
+                                         FeatureState::kBackendOnly,
+                                         FeatureState::kFullyEnabled),
+                         [](const testing::TestParamInfo<FeatureState>& info) {
+                           switch (info.param) {
+                             case FeatureState::kDisabled:
+                               return "Disabled";
+                             case FeatureState::kBackendOnly:
+                               return "BackendOnly";
+                             case FeatureState::kFullyEnabled:
+                               return "FullyEnabled";
+                           }
+                         });
+
+IN_PROC_BROWSER_TEST_P(SharedDictionaryFeatureStateBrowserTest,
+                       LinkRelDictionary) {
+  RunWriteDictionaryTest(
+      shell(), FetchType::kLinkRelDictionary,
+      GURL("https://shared-dictionary.test/blank.html"),
+      https_server()->GetURL("/shared_dictionary/test.dict"),
+      "Net.SharedDictionaryManagerOnDisk.DictionarySize",
+      /*expect_success=*/GetFeatureState() == FeatureState::kFullyEnabled);
+}
+
+IN_PROC_BROWSER_TEST_P(SharedDictionaryFeatureStateBrowserTest,
+                       LinkRelDictionaryWithOriginTrial) {
+  RunWriteDictionaryTest(
+      shell(), FetchType::kLinkRelDictionary,
+      GURL("https://shared-dictionary.test/blank.html?ot=enabled"),
+      https_server()->GetURL("/shared_dictionary/test.dict"),
+      "Net.SharedDictionaryManagerOnDisk.DictionarySize",
+      /*expect_success=*/GetFeatureState() != FeatureState::kDisabled);
+}
+
+IN_PROC_BROWSER_TEST_P(SharedDictionaryFeatureStateBrowserTest, FetchApi) {
+  RunWriteDictionaryTest(
+      shell(), FetchType::kFetchApi,
+      GURL("https://shared-dictionary.test/blank.html"),
+      https_server()->GetURL("/shared_dictionary/test.dict"),
+      "Net.SharedDictionaryManagerOnDisk.DictionarySize",
+      /*expect_success=*/GetFeatureState() == FeatureState::kFullyEnabled);
+}
+
+IN_PROC_BROWSER_TEST_P(SharedDictionaryFeatureStateBrowserTest,
+                       FetchApiWithOriginTrial) {
+  RunWriteDictionaryTest(
+      shell(), FetchType::kFetchApi,
+      GURL("https://shared-dictionary.test/blank.html?ot=enabled"),
+      https_server()->GetURL("/shared_dictionary/test.dict"),
+      "Net.SharedDictionaryManagerOnDisk.DictionarySize",
+      /*expect_success=*/GetFeatureState() != FeatureState::kDisabled);
+}
+
+// Tests end to end functionality of "compression dictionary transport" feature
+// with fully enabled features.
+class SharedDictionaryBrowserTest
+    : public SharedDictionaryBrowserTestBase,
+      public ::testing::WithParamInterface<BrowserType> {
+ public:
+  SharedDictionaryBrowserTest() {
+    scoped_feature_list_.InitWithFeatures(
+        /*enabled_features=*/{blink::features::
+                                  kCompressionDictionaryTransportBackend,
+                              blink::features::kCompressionDictionaryTransport},
+        /*disabled_features=*/{});
+  }
+  SharedDictionaryBrowserTest(const SharedDictionaryBrowserTest&) = delete;
+  SharedDictionaryBrowserTest& operator=(const SharedDictionaryBrowserTest&) =
+      delete;
+
+  // ContentBrowserTest implementation:
+  void SetUpOnMainThread() override {
+    ASSERT_TRUE(embedded_test_server()->Start());
+    host_resolver()->AddRule("*", "127.0.0.1");
+  }
+
+ protected:
+  BrowserType GetBrowserType() const { return GetParam(); }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
 };
@@ -87,31 +316,72 @@
                            }
                          });
 
-IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, LinkRelDictionary) {
-  Shell* target_shell = GetBrowserType() == BrowserType::kNormal
-                            ? shell()
-                            : CreateOffTheRecordBrowser();
-  GURL url = embedded_test_server()->GetURL("/shared_dictionary/blank.html");
-  EXPECT_TRUE(NavigateToURL(target_shell, url));
-
-  base::HistogramTester histogram_tester;
-  EXPECT_TRUE(ExecJs(target_shell->web_contents()->GetPrimaryMainFrame(), R"(
-    (async ()=>{
-      const link = document.createElement('link');
-      link.rel = 'dictionary';
-      link.href = './test.dict';
-      document.body.appendChild(link);
-    })();
-  )"));
-  const std::string histogram_name =
+IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
+                       LinkRelDictionarySecureContext) {
+  // http://127.0.0.1:PORT/ is secure context, so the dictionary should be
+  // written.
+  RunWriteDictionaryTest(
+      GetBrowserType() == BrowserType::kNormal ? shell()
+                                               : CreateOffTheRecordBrowser(),
+      FetchType::kLinkRelDictionary,
+      embedded_test_server()->GetURL("/shared_dictionary/blank.html"),
+      embedded_test_server()->GetURL("/shared_dictionary/test.dict"),
       GetBrowserType() == BrowserType::kNormal
           ? "Net.SharedDictionaryManagerOnDisk.DictionarySize"
-          : "Net.SharedDictionaryWriterInMemory.DictionarySize";
+          : "Net.SharedDictionaryWriterInMemory.DictionarySize",
+      /*expect_success=*/true);
+}
 
-  WaitForHistogram(histogram_name);
-  histogram_tester.ExpectBucketCount(
-      histogram_name, GetTestDataFileSize("shared_dictionary/test.dict"),
-      /*expected_count=*/1);
+IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
+                       FetchDictionarySecureContext) {
+  // http://127.0.0.1:PORT/ is secure context, so the dictionary should be
+  // written.
+  RunWriteDictionaryTest(
+      GetBrowserType() == BrowserType::kNormal ? shell()
+                                               : CreateOffTheRecordBrowser(),
+      FetchType::kFetchApi,
+      embedded_test_server()->GetURL("/shared_dictionary/blank.html"),
+      embedded_test_server()->GetURL("/shared_dictionary/test.dict"),
+      GetBrowserType() == BrowserType::kNormal
+          ? "Net.SharedDictionaryManagerOnDisk.DictionarySize"
+          : "Net.SharedDictionaryWriterInMemory.DictionarySize",
+      /*expect_success=*/true);
+}
+
+IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
+                       LinkRelDictionaryInsecureContext) {
+  // http://www.test/ is insecure context, so the dictionary should not be
+  // written.
+  RunWriteDictionaryTest(
+      GetBrowserType() == BrowserType::kNormal ? shell()
+                                               : CreateOffTheRecordBrowser(),
+      FetchType::kLinkRelDictionary,
+      embedded_test_server()->GetURL("www.test",
+                                     "/shared_dictionary/blank.html"),
+      embedded_test_server()->GetURL("www.test",
+                                     "/shared_dictionary/test.dict"),
+      GetBrowserType() == BrowserType::kNormal
+          ? "Net.SharedDictionaryManagerOnDisk.DictionarySize"
+          : "Net.SharedDictionaryWriterInMemory.DictionarySize",
+      /*expect_success=*/false);
+}
+
+IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
+                       FetchDictionaryInsecureContext) {
+  // http://www.test/ is insecure context, so the dictionary should not be
+  // written.
+  RunWriteDictionaryTest(
+      GetBrowserType() == BrowserType::kNormal ? shell()
+                                               : CreateOffTheRecordBrowser(),
+      FetchType::kFetchApi,
+      embedded_test_server()->GetURL("www.test",
+                                     "/shared_dictionary/blank.html"),
+      embedded_test_server()->GetURL("www.test",
+                                     "/shared_dictionary/test.dict"),
+      GetBrowserType() == BrowserType::kNormal
+          ? "Net.SharedDictionaryManagerOnDisk.DictionarySize"
+          : "Net.SharedDictionaryWriterInMemory.DictionarySize",
+      /*expect_success=*/false);
 }
 
 }  // namespace
diff --git a/content/browser/origin_trials/critical_origin_trials_throttle_unittest.cc b/content/browser/origin_trials/critical_origin_trials_throttle_unittest.cc
index 3529bca..930fe85 100644
--- a/content/browser/origin_trials/critical_origin_trials_throttle_unittest.cc
+++ b/content/browser/origin_trials/critical_origin_trials_throttle_unittest.cc
@@ -17,6 +17,7 @@
 #include "services/network/public/mojom/url_response_head.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/loader/url_loader_throttle.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/common/origin_trials/scoped_test_origin_trial_policy.h"
 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h"
 #include "url/gurl.h"
@@ -69,10 +70,18 @@
     }
   }
 
-  bool IsTrialPersistedForOrigin(const url::Origin& origin,
-                                 const url::Origin& top_level_origin,
-                                 const base::StringPiece trial_name,
-                                 const base::Time current_time) override {
+  bool IsFeaturePersistedForOrigin(const url::Origin& origin,
+                                   const url::Origin& top_level_origin,
+                                   blink::OriginTrialFeature feature,
+                                   const base::Time current_time) override {
+    std::string trial_name = "";
+    switch (feature) {
+      case blink::OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature:
+        trial_name = kPersistentTrialName;
+        break;
+      default:
+        break;
+    }
     const auto& it = persisted_trials_.find(origin);
     return it != persisted_trials_.end() && it->second.contains(trial_name);
   }
diff --git a/content/browser/preloading/prefetch/prefetch_params.cc b/content/browser/preloading/prefetch/prefetch_params.cc
index 5eb259d20..59e41e1e 100644
--- a/content/browser/preloading/prefetch/prefetch_params.cc
+++ b/content/browser/preloading/prefetch/prefetch_params.cc
@@ -228,7 +228,7 @@
     case blink::mojom::SpeculationEagerness::kEager:
       return base::GetFieldTrialParamByFeatureAsBool(
           features::kPrefetchUseContentRefactor,
-          "block_until_head_eager_prefetch", true);
+          "block_until_head_eager_prefetch", false);
     case blink::mojom::SpeculationEagerness::kModerate:
       return base::GetFieldTrialParamByFeatureAsBool(
           features::kPrefetchUseContentRefactor,
diff --git a/content/browser/preloading/prefetch/prefetch_service_unittest.cc b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
index 394dd35..320b38a 100644
--- a/content/browser/preloading/prefetch/prefetch_service_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
@@ -4324,6 +4324,23 @@
                        PreloadingFailureReason::kUnspecified);
 }
 
+class PrefetchServiceAllowRedirectsAndAlwaysBlockUntilHeadTest
+    : public PrefetchServiceTest {
+ public:
+  void InitScopedFeatureList() override {
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {{features::kPrefetchUseContentRefactor,
+          {{"ineligible_decoy_request_probability", "0"},
+           {"prefetch_container_lifetime_s", "-1"},
+           {"block_until_head_eager_prefetch", "true"},
+           {"block_until_head_moderate_prefetch", "true"},
+           {"block_until_head_conservative_prefetch", "true"}}},
+         {features::kPrefetchRedirects, {}}},
+        {network::features::kPrefetchNoVarySearch,
+         ::features::kPreloadingConfig});
+  }
+};
+
 // TODO(crbug.com/1396460): Test flaky on lacros trybots.
 #if BUILDFLAG(IS_CHROMEOS)
 #define MAYBE_RedirectNetworkContextTransitionBlockUntilHead \
@@ -4332,7 +4349,7 @@
 #define MAYBE_RedirectNetworkContextTransitionBlockUntilHead \
   RedirectNetworkContextTransitionBlockUntilHead
 #endif
-TEST_F(PrefetchServiceAllowRedirectTest,
+TEST_F(PrefetchServiceAllowRedirectsAndAlwaysBlockUntilHeadTest,
        MAYBE_RedirectNetworkContextTransitionBlockUntilHead) {
   base::HistogramTester histogram_tester;
 
diff --git a/content/browser/preloading/preloading_decider.cc b/content/browser/preloading/preloading_decider.cc
index 69d08ee..36d6cf8 100644
--- a/content/browser/preloading/preloading_decider.cc
+++ b/content/browser/preloading/preloading_decider.cc
@@ -189,6 +189,9 @@
   auto it = no_vary_search_hint_on_standby_candidates_.find(key_no_vary_search);
   if (it != no_vary_search_hint_on_standby_candidates_.end()) {
     it->second.erase(key);
+    if (it->second.empty()) {
+      no_vary_search_hint_on_standby_candidates_.erase(it);
+    }
   }
   on_standby_candidates_.erase(key);
 }
diff --git a/content/browser/preloading/prerender/prerender_host_registry.cc b/content/browser/preloading/prerender/prerender_host_registry.cc
index 9685ff7b..82fdef1 100644
--- a/content/browser/preloading/prerender/prerender_host_registry.cc
+++ b/content/browser/preloading/prerender/prerender_host_registry.cc
@@ -1592,14 +1592,13 @@
     private_footprint_total_kb += pmd.os_dump().private_footprint_kb;
   }
 
-  // TODO(crbug.com/1382697): Finalize the threshold after the experiment
-  // completes. The default acceptable percent is 10% of the system memory.
+  // The default acceptable percent is 60% of the system memory.
   int acceptable_percent_of_system_memory =
       base::GetFieldTrialParamByFeatureAsInt(
           blink::features::kPrerender2MemoryControls,
           blink::features::
               kPrerender2MemoryAcceptablePercentOfSystemMemoryParamName,
-          10);
+          60);
 
   // When the current memory usage is higher than
   // `acceptable_percent_of_system_memory` % of the system memory, cancel a
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 22816f5..d20ad60 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -40,6 +40,7 @@
 #include "content/browser/renderer_host/media/in_process_video_capture_provider.h"
 #include "content/browser/renderer_host/media/media_capture_devices_impl.h"
 #include "content/browser/renderer_host/media/media_devices_manager.h"
+#include "content/browser/renderer_host/media/media_stream_metrics.h"
 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
 #include "content/browser/renderer_host/media/service_video_capture_provider.h"
 #include "content/browser/renderer_host/media/video_capture_manager.h"
@@ -543,140 +544,6 @@
 }
 #endif
 
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class MediaStreamRequestResult2 {
-  kOk = 0,
-  kPermissionDenied = 1,
-  kPermissionDismissed = 2,
-  kInvalidState = 3,
-  kNoHardware = 4,
-  kInvalidSecurityOrigin = 5,
-  kTabCaptureFailure = 6,
-  kScreenCaptureFailure = 7,
-  kCaptureFailure = 8,
-  kConstraintNotSatisfied = 9,
-  kTrackStartFailureAudio = 10,
-  kTrackStartFailureVideo = 11,
-  kNotSupported = 12,
-  kFailedDueToShutdown = 13,
-  kKillSwitchOn = 14,
-  kSystemPermissionDenied = 15,
-  kDeviceInUse = 16,
-  kMaxValue = kDeviceInUse
-};
-
-void RecordMediaStreamRequestResult2(blink::mojom::MediaStreamType video_type,
-                                     MediaStreamRequestResult2 result2) {
-  switch (video_type) {
-    case blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE:
-      base::UmaHistogramEnumeration(
-          "Media.MediaStreamManager.DesktopVideoDeviceUpdate", result2);
-      return;
-    case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE:
-    case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET:
-      base::UmaHistogramEnumeration(
-          "Media.MediaStreamManager.DisplayVideoDeviceUpdate", result2);
-      return;
-    default:
-      return;
-  }
-}
-
-void RecordMediaDeviceUpdateResponseMetric(
-    blink::mojom::MediaStreamType video_type,
-    MediaStreamRequestResult result) {
-  switch (result) {
-    case MediaStreamRequestResult::OK:
-      RecordMediaStreamRequestResult2(video_type,
-                                      MediaStreamRequestResult2::kOk);
-      return;
-    case MediaStreamRequestResult::PERMISSION_DENIED:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kPermissionDenied);
-      return;
-    case MediaStreamRequestResult::PERMISSION_DISMISSED:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kPermissionDismissed);
-      return;
-    case MediaStreamRequestResult::INVALID_STATE:
-      RecordMediaStreamRequestResult2(video_type,
-                                      MediaStreamRequestResult2::kInvalidState);
-      return;
-    case MediaStreamRequestResult::NO_HARDWARE:
-      RecordMediaStreamRequestResult2(video_type,
-                                      MediaStreamRequestResult2::kNoHardware);
-      return;
-    case MediaStreamRequestResult::INVALID_SECURITY_ORIGIN:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kInvalidSecurityOrigin);
-      return;
-    case MediaStreamRequestResult::TAB_CAPTURE_FAILURE:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kTabCaptureFailure);
-      return;
-    case MediaStreamRequestResult::SCREEN_CAPTURE_FAILURE:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kScreenCaptureFailure);
-      return;
-    case MediaStreamRequestResult::CAPTURE_FAILURE:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kCaptureFailure);
-      return;
-    case MediaStreamRequestResult::CONSTRAINT_NOT_SATISFIED:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kConstraintNotSatisfied);
-      return;
-    case MediaStreamRequestResult::TRACK_START_FAILURE_AUDIO:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kTrackStartFailureAudio);
-      return;
-    case MediaStreamRequestResult::TRACK_START_FAILURE_VIDEO:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kTrackStartFailureVideo);
-      return;
-    case MediaStreamRequestResult::NOT_SUPPORTED:
-      RecordMediaStreamRequestResult2(video_type,
-                                      MediaStreamRequestResult2::kNotSupported);
-      return;
-    case MediaStreamRequestResult::FAILED_DUE_TO_SHUTDOWN:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kFailedDueToShutdown);
-      return;
-    case MediaStreamRequestResult::KILL_SWITCH_ON:
-      RecordMediaStreamRequestResult2(video_type,
-                                      MediaStreamRequestResult2::kKillSwitchOn);
-      return;
-    case MediaStreamRequestResult::SYSTEM_PERMISSION_DENIED:
-      RecordMediaStreamRequestResult2(
-          video_type, MediaStreamRequestResult2::kSystemPermissionDenied);
-      return;
-    case MediaStreamRequestResult::DEVICE_IN_USE:
-      RecordMediaStreamRequestResult2(video_type,
-                                      MediaStreamRequestResult2::kDeviceInUse);
-      return;
-    case MediaStreamRequestResult::NUM_MEDIA_REQUEST_RESULTS:
-      break;
-  }
-  NOTREACHED();
-}
-
-void RecordMediaStreamRequestResponseMetric(
-    blink::mojom::MediaStreamType video_type,
-    blink::MediaStreamRequestType request_type,
-    MediaStreamRequestResult result) {
-  switch (request_type) {
-    case blink::MEDIA_DEVICE_UPDATE:
-      RecordMediaDeviceUpdateResponseMetric(video_type, result);
-      return;
-    case blink::MEDIA_DEVICE_ACCESS:
-    case blink::MEDIA_GENERATE_STREAM:
-    case blink::MEDIA_GET_OPEN_DEVICE:
-    case blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY:
-      return;
-  }
-}
-
 const blink::MediaStreamDevice* GetStreamDevice(
     const blink::mojom::StreamDevices& stream_devices,
     const base::UnguessableToken& session_id) {
@@ -3481,8 +3348,8 @@
       label.c_str(), RequestTypeToString(request->request_type()),
       RequestResultToString(result)));
 
-  RecordMediaStreamRequestResponseMetric(request->video_type(),
-                                         request->request_type(), result);
+  media_stream_metrics::RecordMediaStreamRequestResponseMetric(
+      request->video_type(), request->request_type(), result);
 
   if (request->request_type() == blink::MEDIA_DEVICE_ACCESS) {
     FinalizeMediaAccessRequest(request_it, stream_devices_set);
diff --git a/content/browser/renderer_host/media/media_stream_metrics.cc b/content/browser/renderer_host/media/media_stream_metrics.cc
new file mode 100644
index 0000000..2cb9fa3e
--- /dev/null
+++ b/content/browser/renderer_host/media/media_stream_metrics.cc
@@ -0,0 +1,160 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/media_stream_metrics.h"
+
+#include "base/metrics/histogram_functions.h"
+#include "base/notreached.h"
+#include "url/origin.h"
+
+namespace content::media_stream_metrics {
+
+namespace {
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class MediaStreamRequestResult2 {
+  kOk = 0,
+  kPermissionDenied = 1,
+  kPermissionDismissed = 2,
+  kInvalidState = 3,
+  kNoHardware = 4,
+  kInvalidSecurityOrigin = 5,
+  kTabCaptureFailure = 6,
+  kScreenCaptureFailure = 7,
+  kCaptureFailure = 8,
+  kConstraintNotSatisfied = 9,
+  kTrackStartFailureAudio = 10,
+  kTrackStartFailureVideo = 11,
+  kNotSupported = 12,
+  kFailedDueToShutdown = 13,
+  kKillSwitchOn = 14,
+  kSystemPermissionDenied = 15,
+  kDeviceInUse = 16,
+  kMaxValue = kDeviceInUse
+};
+
+void RecordMediaStreamRequestResult2(blink::mojom::MediaStreamType video_type,
+                                     MediaStreamRequestResult2 result2) {
+  switch (video_type) {
+    case blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE:
+      base::UmaHistogramEnumeration(
+          "Media.MediaStreamManager.DesktopVideoDeviceUpdate", result2);
+      return;
+    case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE:
+    case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET:
+      base::UmaHistogramEnumeration(
+          "Media.MediaStreamManager.DisplayVideoDeviceUpdate", result2);
+      return;
+    default:
+      return;
+  }
+}
+
+void RecordMediaDeviceUpdateResponseMetric(
+    blink::mojom::MediaStreamType video_type,
+    blink::mojom::MediaStreamRequestResult result) {
+  using blink::mojom::MediaStreamRequestResult;
+  switch (result) {
+    case MediaStreamRequestResult::OK:
+      RecordMediaStreamRequestResult2(video_type,
+                                      MediaStreamRequestResult2::kOk);
+      return;
+    case MediaStreamRequestResult::PERMISSION_DENIED:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kPermissionDenied);
+      return;
+    case MediaStreamRequestResult::PERMISSION_DISMISSED:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kPermissionDismissed);
+      return;
+    case MediaStreamRequestResult::INVALID_STATE:
+      RecordMediaStreamRequestResult2(video_type,
+                                      MediaStreamRequestResult2::kInvalidState);
+      return;
+    case MediaStreamRequestResult::NO_HARDWARE:
+      RecordMediaStreamRequestResult2(video_type,
+                                      MediaStreamRequestResult2::kNoHardware);
+      return;
+    case MediaStreamRequestResult::INVALID_SECURITY_ORIGIN:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kInvalidSecurityOrigin);
+      return;
+    case MediaStreamRequestResult::TAB_CAPTURE_FAILURE:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kTabCaptureFailure);
+      return;
+    case MediaStreamRequestResult::SCREEN_CAPTURE_FAILURE:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kScreenCaptureFailure);
+      return;
+    case MediaStreamRequestResult::CAPTURE_FAILURE:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kCaptureFailure);
+      return;
+    case MediaStreamRequestResult::CONSTRAINT_NOT_SATISFIED:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kConstraintNotSatisfied);
+      return;
+    case MediaStreamRequestResult::TRACK_START_FAILURE_AUDIO:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kTrackStartFailureAudio);
+      return;
+    case MediaStreamRequestResult::TRACK_START_FAILURE_VIDEO:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kTrackStartFailureVideo);
+      return;
+    case MediaStreamRequestResult::NOT_SUPPORTED:
+      RecordMediaStreamRequestResult2(video_type,
+                                      MediaStreamRequestResult2::kNotSupported);
+      return;
+    case MediaStreamRequestResult::FAILED_DUE_TO_SHUTDOWN:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kFailedDueToShutdown);
+      return;
+    case MediaStreamRequestResult::KILL_SWITCH_ON:
+      RecordMediaStreamRequestResult2(video_type,
+                                      MediaStreamRequestResult2::kKillSwitchOn);
+      return;
+    case MediaStreamRequestResult::SYSTEM_PERMISSION_DENIED:
+      RecordMediaStreamRequestResult2(
+          video_type, MediaStreamRequestResult2::kSystemPermissionDenied);
+      return;
+    case MediaStreamRequestResult::DEVICE_IN_USE:
+      RecordMediaStreamRequestResult2(video_type,
+                                      MediaStreamRequestResult2::kDeviceInUse);
+      return;
+    case MediaStreamRequestResult::NUM_MEDIA_REQUEST_RESULTS:
+      break;
+  }
+  NOTREACHED();
+}
+
+}  // namespace
+
+void RecordMediaStreamRequestResponseMetric(
+    blink::mojom::MediaStreamType video_type,
+    blink::MediaStreamRequestType request_type,
+    blink::mojom::MediaStreamRequestResult result) {
+  switch (request_type) {
+    case blink::MEDIA_DEVICE_UPDATE:
+      RecordMediaDeviceUpdateResponseMetric(video_type, result);
+      return;
+    case blink::MEDIA_DEVICE_ACCESS:
+    case blink::MEDIA_GENERATE_STREAM:
+    case blink::MEDIA_GET_OPEN_DEVICE:
+    case blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY:
+      return;
+  }
+}
+
+void RecordMediaStreamRequestResponseUKM(
+    const url::Origin& main_frame_origin,
+    blink::mojom::MediaStreamType video_type,
+    blink::MediaStreamRequestType request_type,
+    blink::mojom::MediaStreamRequestResult result) {
+  NOTIMPLEMENTED();
+}
+
+}  // namespace content::media_stream_metrics
diff --git a/content/browser/renderer_host/media/media_stream_metrics.h b/content/browser/renderer_host/media/media_stream_metrics.h
new file mode 100644
index 0000000..79fec2a
--- /dev/null
+++ b/content/browser/renderer_host/media/media_stream_metrics.h
@@ -0,0 +1,29 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_METRICS_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_METRICS_H_
+
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
+
+namespace url {
+class Origin;
+}
+
+namespace content::media_stream_metrics {
+
+void RecordMediaStreamRequestResponseMetric(
+    blink::mojom::MediaStreamType video_type,
+    blink::MediaStreamRequestType request_type,
+    blink::mojom::MediaStreamRequestResult result);
+
+void RecordMediaStreamRequestResponseUKM(
+    const url::Origin& main_frame_origin,
+    blink::mojom::MediaStreamType video_type,
+    blink::MediaStreamRequestType request_type,
+    blink::mojom::MediaStreamRequestResult result);
+
+}  // namespace content::media_stream_metrics
+
+#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_METRICS_H_
diff --git a/content/browser/renderer_host/native_web_keyboard_event_ios.mm b/content/browser/renderer_host/native_web_keyboard_event_ios.mm
index 35cfbcb..0b3a084 100644
--- a/content/browser/renderer_host/native_web_keyboard_event_ios.mm
+++ b/content/browser/renderer_host/native_web_keyboard_event_ios.mm
@@ -13,44 +13,39 @@
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type type,
                                                int modifiers,
                                                base::TimeTicks timestamp)
-    : WebKeyboardEvent(type, modifiers, timestamp),
-      os_event(NULL),
-      skip_in_browser(false) {}
+    : WebKeyboardEvent(type, modifiers, timestamp), skip_in_browser(false) {}
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(
     const blink::WebKeyboardEvent& web_event,
     gfx::NativeView native_view)
-    : WebKeyboardEvent(web_event), os_event(nullptr), skip_in_browser(false) {}
+    : WebKeyboardEvent(web_event), skip_in_browser(false) {}
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event)
-    : WebKeyboardEvent(WebKeyboardEventBuilder::Build(native_event)),
-      os_event([native_event retain]),
+    : WebKeyboardEvent(WebKeyboardEventBuilder::Build(native_event.Get())),
+      os_event(native_event),
       skip_in_browser(false) {}
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(const ui::KeyEvent& key_event)
-    : NativeWebKeyboardEvent(key_event.native_event()) {}
+    : NativeWebKeyboardEvent(
+          base::apple::OwnedUIEvent(key_event.native_event())) {}
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(
     const NativeWebKeyboardEvent& other)
     : WebKeyboardEvent(other),
-      os_event([other.os_event retain]),
+      os_event(other.os_event),
       skip_in_browser(other.skip_in_browser) {}
 
 NativeWebKeyboardEvent& NativeWebKeyboardEvent::operator=(
     const NativeWebKeyboardEvent& other) {
   WebKeyboardEvent::operator=(other);
 
-  UIEvent* previous = os_event;
-  os_event = [other.os_event retain];
-  [previous release];
+  os_event = other.os_event;
 
   skip_in_browser = other.skip_in_browser;
 
   return *this;
 }
 
-NativeWebKeyboardEvent::~NativeWebKeyboardEvent() {
-  [os_event release];
-}
+NativeWebKeyboardEvent::~NativeWebKeyboardEvent() = default;
 
 }  // namespace content
diff --git a/content/browser/renderer_host/native_web_keyboard_event_mac.mm b/content/browser/renderer_host/native_web_keyboard_event_mac.mm
index 8e2f262..c04ec7a 100644
--- a/content/browser/renderer_host/native_web_keyboard_event_mac.mm
+++ b/content/browser/renderer_host/native_web_keyboard_event_mac.mm
@@ -38,19 +38,17 @@
   return text_length;
 }
 
-}  // namepsace
+}  // namespace
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type type,
                                                int modifiers,
                                                base::TimeTicks timestamp)
-    : WebKeyboardEvent(type, modifiers, timestamp),
-      os_event(NULL),
-      skip_in_browser(false) {}
+    : WebKeyboardEvent(type, modifiers, timestamp), skip_in_browser(false) {}
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(
     const blink::WebKeyboardEvent& web_event,
     gfx::NativeView native_view)
-    : WebKeyboardEvent(web_event), os_event(nullptr), skip_in_browser(false) {
+    : WebKeyboardEvent(web_event), skip_in_browser(false) {
   NSEventType type = NSEventTypeKeyUp;
   int flags = modifiersForEvent(web_event.GetModifiers());
   if (web_event.GetType() == blink::WebInputEvent::Type::kChar ||
@@ -77,57 +75,52 @@
                                                 web_event.unmodified_text)
                                      length:unmod_text_length] autorelease];
 
-  os_event = [[NSEvent keyEventWithType:type
-                               location:NSZeroPoint
-                          modifierFlags:flags
-                              timestamp:ui::EventTimeStampToSeconds(
-                                            web_event.TimeStamp())
-                           windowNumber:[[native_view.GetNativeNSView() window]
-                                            windowNumber]
-                                context:nil
-                             characters:text
-            charactersIgnoringModifiers:unmodified_text
-                              isARepeat:NO
-                                keyCode:web_event.native_key_code] retain];
+  os_event = base::apple::OwnedNSEvent([NSEvent
+                 keyEventWithType:type
+                         location:NSZeroPoint
+                    modifierFlags:flags
+                        timestamp:ui::EventTimeStampToSeconds(
+                                      web_event.TimeStamp())
+                     windowNumber:[[native_view.GetNativeNSView() window]
+                                      windowNumber]
+                          context:nil
+                       characters:text
+      charactersIgnoringModifiers:unmodified_text
+                        isARepeat:NO
+                          keyCode:web_event.native_key_code]);
   // The eventRef is necessary for MacOS code (like NSMenu) to work later in the
   // pipeline. As per documentation:
   // https://developer.apple.com/documentation/appkit/nsevent/1525143-eventref
   // "Other NSEvent objects create an EventRef when this property is first
   // accessed, if possible".
-  [os_event eventRef];
+  [os_event.Get() eventRef];
 }
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event)
-    : WebKeyboardEvent(WebKeyboardEventBuilder::Build(native_event)),
-      os_event([native_event retain]),
+    : WebKeyboardEvent(WebKeyboardEventBuilder::Build(native_event.Get())),
+      os_event(native_event),
       skip_in_browser(false) {}
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(const ui::KeyEvent& key_event)
-    : NativeWebKeyboardEvent(key_event.native_event()) {
-}
+    : NativeWebKeyboardEvent(
+          base::apple::OwnedNSEvent(key_event.native_event())) {}
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(
     const NativeWebKeyboardEvent& other)
     : WebKeyboardEvent(other),
-      os_event([other.os_event retain]),
-      skip_in_browser(other.skip_in_browser) {
-}
+      os_event(other.os_event),
+      skip_in_browser(other.skip_in_browser) {}
 
 NativeWebKeyboardEvent& NativeWebKeyboardEvent::operator=(
     const NativeWebKeyboardEvent& other) {
   WebKeyboardEvent::operator=(other);
 
-  NSObject* previous = os_event;
-  os_event = [other.os_event retain];
-  [previous release];
-
+  os_event = other.os_event;
   skip_in_browser = other.skip_in_browser;
 
   return *this;
 }
 
-NativeWebKeyboardEvent::~NativeWebKeyboardEvent() {
-  [os_event release];
-}
+NativeWebKeyboardEvent::~NativeWebKeyboardEvent() = default;
 
 }  // namespace content
diff --git a/content/browser/renderer_host/native_web_keyboard_event_mac_unittest.mm b/content/browser/renderer_host/native_web_keyboard_event_mac_unittest.mm
index 64e19bc..f9ebad4 100644
--- a/content/browser/renderer_host/native_web_keyboard_event_mac_unittest.mm
+++ b/content/browser/renderer_host/native_web_keyboard_event_mac_unittest.mm
@@ -31,8 +31,8 @@
       content::WebKeyboardEventBuilder::Build(ns_event);
   content::NativeWebKeyboardEvent native_event(web_event, gfx::NativeView());
 
-  NSEvent* round_trip_ns_event = native_event.os_event;
-  EXPECT_EQ([round_trip_ns_event type], [ns_event type]);
-  EXPECT_EQ([round_trip_ns_event modifierFlags], [ns_event modifierFlags]);
-  EXPECT_EQ([round_trip_ns_event keyCode], [ns_event keyCode]);
+  NSEvent* round_trip_ns_event = native_event.os_event.Get();
+  EXPECT_EQ(round_trip_ns_event.type, ns_event.type);
+  EXPECT_EQ(round_trip_ns_event.modifierFlags, ns_event.modifierFlags);
+  EXPECT_EQ(round_trip_ns_event.keyCode, ns_event.keyCode);
 }
diff --git a/content/browser/renderer_host/navigation_controller_android.cc b/content/browser/renderer_host/navigation_controller_android.cc
index 135b018c..f3d19d1e 100644
--- a/content/browser/renderer_host/navigation_controller_android.cc
+++ b/content/browser/renderer_host/navigation_controller_android.cc
@@ -15,6 +15,7 @@
 #include "base/debug/dump_without_crashing.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_helpers.h"
+#include "content/browser/android/impression_utils.h"
 #include "content/browser/renderer_host/navigation_controller_impl.h"
 #include "content/browser/renderer_host/navigation_entry_impl.h"
 #include "content/public/android/content_jni_headers/NavigationControllerImpl_jni.h"
@@ -255,6 +256,7 @@
     const JavaParamRef<jobject>& j_initiator_origin,
     jboolean has_user_gesture,
     jboolean should_clear_history_list,
+    const base::android::JavaParamRef<jobject>& j_impression,
     jlong input_start,
     jlong navigation_ui_data_ptr) {
   DCHECK(url);
@@ -275,6 +277,20 @@
   params.has_user_gesture = has_user_gesture;
   params.should_clear_history_list = should_clear_history_list;
 
+  if (j_impression) {
+    params.initiator_frame_token =
+        GetInitiatorFrameTokenFromJavaImpression(env, j_impression);
+    params.initiator_process_id =
+        GetInitiatorProcessIDFromJavaImpression(env, j_impression);
+    blink::Impression impression;
+    impression.attribution_src_token =
+        GetAttributionSrcTokenFromJavaImpression(env, j_impression).value();
+    impression.nav_type = blink::mojom::AttributionNavigationType::kContextMenu;
+    impression.runtime_features =
+        GetAttributionRuntimeFeaturesFromJavaImpression(env, j_impression);
+    params.impression = impression;
+  }
+
   if (extra_headers)
     params.extra_headers = ConvertJavaStringToUTF8(env, extra_headers);
 
diff --git a/content/browser/renderer_host/navigation_controller_android.h b/content/browser/renderer_host/navigation_controller_android.h
index 90fddb87..89cd616 100644
--- a/content/browser/renderer_host/navigation_controller_android.h
+++ b/content/browser/renderer_host/navigation_controller_android.h
@@ -90,6 +90,7 @@
       const base::android::JavaParamRef<jobject>& j_initiator_origin,
       jboolean has_user_gesture,
       jboolean should_clear_history_list,
+      const base::android::JavaParamRef<jobject>& j_impression,
       jlong input_start,
       jlong navigation_ui_data_ptr);
   void ClearSslPreferences(
diff --git a/content/browser/renderer_host/navigation_request_unittest.cc b/content/browser/renderer_host/navigation_request_unittest.cc
index 235bac2..9b428ce 100644
--- a/content/browser/renderer_host/navigation_request_unittest.cc
+++ b/content/browser/renderer_host/navigation_request_unittest.cc
@@ -31,6 +31,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/navigation/navigation_params.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/common/origin_trials/scoped_test_origin_trial_policy.h"
 #include "third_party/blink/public/common/runtime_feature_state/runtime_feature_state_context.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
@@ -1205,10 +1206,10 @@
       const base::Time current_time) override {
     NOTREACHED() << "not used by test";
   }
-  bool IsTrialPersistedForOrigin(const url::Origin& origin,
-                                 const url::Origin& partition_origin,
-                                 const base::StringPiece trial_name,
-                                 const base::Time current_time) override {
+  bool IsFeaturePersistedForOrigin(const url::Origin& origin,
+                                   const url::Origin& partition_origin,
+                                   blink::OriginTrialFeature feature,
+                                   const base::Time current_time) override {
     DCHECK(false) << "Method not implemented for test.";
     return false;
   }
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 12b9553..1deaca8 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -188,6 +188,7 @@
 #include "content/public/common/extra_mojo_js_features.mojom.h"
 #include "content/public/common/isolated_world_ids.h"
 #include "content/public/common/network_service_util.h"
+#include "content/public/common/origin_util.h"
 #include "content/public/common/page_visibility_state.h"
 #include "content/public/common/referrer.h"
 #include "content/public/common/referrer_type_converters.h"
@@ -5481,32 +5482,66 @@
                                     std::move(dialog_closed_callback));
 }
 
-void RenderFrameHostImpl::WillPotentiallyStartOutermostMainFrameNavigation(
-    const GURL& url) {
-  TRACE_EVENT2(
-      "navigation",
-      "RenderFrameHostImpl::WillPotentiallyStartOutermostMainFrameNavigation",
-      "url", url, "render_frame_host", this);
+void RenderFrameHostImpl::MaybeStartOutermostMainFrameNavigation(
+    const std::vector<GURL>& urls) {
+  const bool kStartupEnabled =
+      base::FeatureList::IsEnabled(kSpeculativeServiceWorkerStartup);
+  const bool kWarmUpEnabled =
+      base::FeatureList::IsEnabled(
+          blink::features::kSpeculativeServiceWorkerWarmUp) &&
+      !blink::features::kSpeculativeServiceWorkerWarmUpDryRun.Get();
 
-  GURL filtered_url(url);
-  GetProcess()->FilterURL(/*empty_allowed=*/false, &filtered_url);
-  if (filtered_url == GURL(kBlockedURL))
+  if (!kStartupEnabled && !kWarmUpEnabled) {
     return;
+  }
 
-  // Ask the service worker context to speculatively start a service worker for
-  // the request URL if necessary for optimization purposes. There are cases
-  // where we have already started the service worker (e.g, Prerendering or the
-  // previous navigation already started the service worker), but this call does
-  // nothing if the service worker already started for the URL.
-  if (base::FeatureList::IsEnabled(kSpeculativeServiceWorkerStartup)) {
-    if (ServiceWorkerContext* context =
-            GetStoragePartition()->GetServiceWorkerContext()) {
-      const blink::StorageKey key = blink::StorageKey::CreateFirstParty(
-          url::Origin::Create(filtered_url));
-      if (context->MaybeHasRegistrationForStorageKey(key)) {
-        context->StartServiceWorkerForNavigationHint(filtered_url, key,
-                                                     base::DoNothing());
-      }
+  TRACE_EVENT0("navigation",
+               "RenderFrameHostImpl::MaybeStartOutermostMainFrameNavigation");
+
+  ServiceWorkerContextWrapper* context =
+      GetStoragePartition()->GetServiceWorkerContext();
+
+  if (!context) {
+    return;
+  }
+
+  for (const auto& url : urls) {
+    GURL filtered_url(url);
+
+    GetProcess()->FilterURL(/*empty_allowed=*/false, &filtered_url);
+
+    if (filtered_url.spec() == kBlockedURL) {
+      continue;
+    }
+
+    if (!OriginCanAccessServiceWorkers(filtered_url)) {
+      continue;
+    }
+
+    const blink::StorageKey key =
+        blink::StorageKey::CreateFirstParty(url::Origin::Create(filtered_url));
+
+    if (!context->MaybeHasRegistrationForStorageKey(key)) {
+      continue;
+    }
+
+    // Ask the service worker context to speculatively start a service worker
+    // for the request URL if necessary for optimization purposes. There are
+    // cases where we have already started the service worker (e.g, Prerendering
+    // or the previous navigation already started the service worker), but this
+    // call does nothing if the service worker already started for the URL.
+    if (kStartupEnabled) {
+      context->StartServiceWorkerForNavigationHint(filtered_url, key,
+                                                   base::DoNothing());
+    }
+
+    // Ask the service worker context to speculatively warm-up a service worker
+    // for the request URL if necessary for optimization purposes. There are
+    // cases where we have already started the service worker (e.g, Prerendering
+    // or the previous navigation already started the service worker), but this
+    // call does nothing if the service worker already started for the URL.
+    if (kWarmUpEnabled) {
+      context->WarmUpServiceWorker(filtered_url, key, base::DoNothing());
     }
   }
 }
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 617e2ca..f85223c5 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2336,8 +2336,8 @@
                             RunModalPromptDialogCallback callback) override;
   void RunBeforeUnloadConfirm(bool is_reload,
                               RunBeforeUnloadConfirmCallback callback) override;
-  void WillPotentiallyStartOutermostMainFrameNavigation(
-      const GURL& url) override;
+  void MaybeStartOutermostMainFrameNavigation(
+      const std::vector<GURL>& urls) override;
   void UpdateFaviconURL(
       std::vector<blink::mojom::FaviconURLPtr> favicon_urls) override;
   void DownloadURL(blink::mojom::DownloadURLParamsPtr params) override;
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
index 1835a73..feba607 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -106,6 +106,7 @@
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/common/switches.h"
 #include "third_party/blink/public/mojom/browser_interface_broker.mojom-test-utils.h"
@@ -1116,9 +1117,10 @@
   OriginTrialsControllerDelegate* delegate = GetOriginTrialsDelegate();
 
   url::Origin trial_origin = url::Origin::Create(GURL(kOriginTrialUrl));
-  EXPECT_TRUE(delegate->IsTrialPersistedForOrigin(
+  EXPECT_TRUE(delegate->IsFeaturePersistedForOrigin(
       /*origin=*/trial_origin, /*partition_origin=*/trial_origin,
-      "FrobulatePersistent", validTime));
+      blink::OriginTrialFeature::kOriginTrialsSampleAPIPersistentFeature,
+      validTime));
 }
 
 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplWithTokensBrowserTest,
@@ -1170,9 +1172,11 @@
   // The Trial should be enabled in the context where it was set.
   url::Origin main_origin = url::Origin::Create(GURL(kOriginTrialUrl));
   url::Origin trial_origin = url::Origin::Create(GURL(kThirdPartyScriptUrl));
-  EXPECT_TRUE(delegate->IsTrialPersistedForOrigin(
+  EXPECT_TRUE(delegate->IsFeaturePersistedForOrigin(
       /*origin=*/trial_origin, /*partition_origin=*/main_origin,
-      "FrobulatePersistentThirdPartyDeprecation", validTime));
+      blink::OriginTrialFeature::
+          kOriginTrialsSampleAPIPersistentThirdPartyDeprecationFeature,
+      validTime));
 }
 
 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplWithTokensBrowserTest,
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index 73b31e23..63c29ff 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -96,9 +96,8 @@
 const char kBackForwardCachePageWithFormStorableHistogramName[] =
     "BackForwardCache.PageWithForm.Storable";
 
-bool IsDataOrAbout(const GURL& url) {
-  return url.IsAboutSrcdoc() || url.IsAboutBlank() ||
-         url.scheme() == url::kDataScheme;
+bool IsAbout(const GURL& url) {
+  return url.IsAboutSrcdoc() || url.IsAboutBlank();
 }
 
 // Helper function to determine whether a navigation from `current_rfh` to
@@ -3002,7 +3001,9 @@
   // skip the IsSuitableForUrlInfo() check. Note that it's impossible to
   // have a sandboxed parent but unsandboxed child.
   bool is_data_or_about_and_not_sandboxed =
-      IsDataOrAbout(dest_url_info.url) && !dest_url_info.is_sandboxed;
+      (dest_url_info.url.SchemeIs(url::kDataScheme) ||
+       IsAbout(dest_url_info.url)) &&
+      !dest_url_info.is_sandboxed;
   if (is_data_or_about_and_not_sandboxed)
     return true;
 
@@ -3122,8 +3123,10 @@
   // We use the source SiteInstance in case of data URLs, about:srcdoc pages and
   // about:blank pages because the content is then controlled and/or scriptable
   // by the initiator and therefore needs to stay in the `source_instance`.
-  if (!IsDataOrAbout(dest_url_info.url))
+  if (!dest_url_info.url.SchemeIs(url::kDataScheme) &&
+      !IsAbout(dest_url_info.url)) {
     return false;
+  }
 
   // If `dest_url_info` is sandboxed, then we can't assign it to a SiteInstance
   // that isn't sandboxed. But if the `source_instance` is also sandboxed, then
@@ -3757,7 +3760,7 @@
     }
 
     child->render_manager()->CreateRenderFrameProxy(
-        pair.second->GetSiteInstance(),
+        pair.second->GetSiteInstanceDeprecated(),
         child->current_frame_host()->browsing_context_state());
   }
 }
diff --git a/content/browser/renderer_host/render_frame_proxy_host.cc b/content/browser/renderer_host/render_frame_proxy_host.cc
index 802f6b0..a33f4f78 100644
--- a/content/browser/renderer_host/render_frame_proxy_host.cc
+++ b/content/browser/renderer_host/render_frame_proxy_host.cc
@@ -119,7 +119,7 @@
     FrameTreeNode* frame_tree_node,
     const blink::RemoteFrameToken& frame_token)
     : routing_id_(site_instance->GetProcess()->GetNextRoutingID()),
-      site_instance_(site_instance),
+      site_instance_deprecated_(site_instance),
       site_instance_group_(site_instance->group()),
       process_(site_instance->GetProcess()),
       frame_tree_node_(frame_tree_node),
@@ -382,7 +382,7 @@
 
   if (frame_tree_node_->opener()) {
     frame_tree_node_->opener()->render_manager()->CreateOpenerProxies(
-        GetSiteInstance(), frame_tree_node_,
+        GetSiteInstanceDeprecated(), frame_tree_node_,
         frame_tree_node_->current_frame_host()->browsing_context_state());
   }
 
@@ -758,12 +758,12 @@
   // to PAGE_TRANSITION_FORM_SUBMIT. See https://crbug.com/829827.
   // TODO(https://crbug.com/1261963): Determine which source_site_instance from
   // site_instance_group_ to use for navigations to about:blank, once
-  // RenderFrameProxyHost no longer has a site_instance_.
+  // RenderFrameProxyHost no longer has a site_instance_deprecated_.
   frame_tree_node_->navigator().NavigateFromFrameProxy(
       current_rfh, validated_url,
       base::OptionalToPtr(params->initiator_frame_token), GetProcess()->GetID(),
       params->initiator_origin, params->initiator_base_url,
-      site_instance_.get(), params->referrer.To<content::Referrer>(),
+      GetSiteInstanceDeprecated(), params->referrer.To<content::Referrer>(),
       ui::PAGE_TRANSITION_LINK, params->should_replace_current_entry,
       download_policy, params->post_body ? "POST" : "GET", params->post_body,
       params->extra_headers, std::move(blob_url_loader_factory),
diff --git a/content/browser/renderer_host/render_frame_proxy_host.h b/content/browser/renderer_host/render_frame_proxy_host.h
index 819458e..08c1d72 100644
--- a/content/browser/renderer_host/render_frame_proxy_host.h
+++ b/content/browser/renderer_host/render_frame_proxy_host.h
@@ -137,9 +137,11 @@
 
   // Each RenderFrameProxyHost belongs to a SiteInstanceGroup, where it is a
   // placeholder for a frame in a different SiteInstanceGroup.
-  // TODO(crbug.com/1195535): Remove GetSiteInstance() in favor of
+  // TODO(crbug.com/1195535): Remove GetSiteInstanceDeprecated() in favor of
   // site_instance_group().
-  SiteInstanceImpl* GetSiteInstance() const { return site_instance_.get(); }
+  SiteInstanceImpl* GetSiteInstanceDeprecated() const {
+    return site_instance_deprecated_.get();
+  }
   SiteInstanceGroup* site_instance_group() const {
     return site_instance_group_.get();
   }
@@ -326,14 +328,14 @@
 
   // The SiteInstance this proxy is associated with.
   // TODO(crbug.com/1195535): Remove this in favor of site_instance_group_.
-  scoped_refptr<SiteInstanceImpl> site_instance_;
+  scoped_refptr<SiteInstanceImpl> site_instance_deprecated_;
 
   // The SiteInstanceGroup this RenderFrameProxyHost belongs to, where it is a
   // placeholder for a frame in a different SiteInstanceGroup.
   scoped_refptr<SiteInstanceGroup> site_instance_group_;
 
   // The renderer process this RenderFrameProxyHost is associated with. It is
-  // equivalent to the result of site_instance_->GetProcess(), but that
+  // equivalent to the result of site_instance_group_->GetProcess(), but that
   // method has the side effect of creating the process if it doesn't exist.
   // Cache a pointer to avoid unnecessary process creation.
   raw_ptr<RenderProcessHost> process_;
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 3b059b61..5c37b56 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -555,9 +555,19 @@
     params->type = mojom::ViewWidgetType::kTopLevel;
   }
 
+  // Send the current page's browsing context group to the renderer. It is
+  // guaranteed to be consistent for the entire FrameTree, main frame and
+  // subframes. For this reason we simply use the main frame's browsing context
+  // group. Note that we cannot use this RenderViewHost's site_instance_group(),
+  // which may not match in a popup case. For example, if A opens a
+  // cross-browsing-context-group popup to B, A can have a RenderViewHost in the
+  // popup, but it needs to know B's BrowsingContextGroupInfo, which is the
+  // current page in the popup.
   params->browsing_context_group_info = blink::BrowsingContextGroupInfo(
-      site_instance_group()->browsing_instance_token(),
-      site_instance_group()->coop_related_group_token());
+      frame_tree_->GetMainFrame()->GetSiteInstance()->browsing_instance_token(),
+      frame_tree_->GetMainFrame()
+          ->GetSiteInstance()
+          ->coop_related_group_token());
 
   // RenderViewHostImpl is reused after a crash, so reset any endpoint that
   // might be a leftover from a crash.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index a7cbd153..6fe4b7b3 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -11,6 +11,7 @@
 #include <tuple>
 #include <utility>
 
+#include "base/apple/owned_objc.h"
 #include "base/auto_reset.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
@@ -2146,8 +2147,8 @@
   // close to the original NSEvent, resulting in all sorts of bugs. Use the
   // native event serialization to reconstruct the NSEvent.
   // https://crbug.com/919167,943197,964052
-  [native_event.os_event release];
-  native_event.os_event = [ui::EventFromData(native_event_data) retain];
+  native_event.os_event =
+      base::apple::OwnedNSEvent(ui::EventFromData(native_event_data));
   ForwardKeyboardEventWithCommands(native_event, input_event->latency_info(),
                                    std::move(edit_commands));
 }
diff --git a/content/browser/serial/serial_service.cc b/content/browser/serial/serial_service.cc
index e5de2c8..90bbd37 100644
--- a/content/browser/serial/serial_service.cc
+++ b/content/browser/serial/serial_service.cc
@@ -19,6 +19,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_client.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/device/public/mojom/serial.mojom.h"
 #include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom.h"
 
 namespace content {
@@ -35,6 +36,9 @@
   info->has_usb_product_id = port.has_product_id;
   if (port.has_product_id)
     info->usb_product_id = port.product_id;
+  if (port.bluetooth_service_class_id) {
+    info->bluetooth_service_class_id = port.bluetooth_service_class_id;
+  }
   return info;
 }
 
@@ -96,6 +100,8 @@
 
 void SerialService::RequestPort(
     std::vector<blink::mojom::SerialPortFilterPtr> filters,
+    const std::vector<::device::BluetoothUUID>&
+        allowed_bluetooth_service_class_ids,
     RequestPortCallback callback) {
   SerialDelegate* delegate = GetContentClient()->browser()->GetSerialDelegate();
   if (!delegate) {
@@ -110,6 +116,7 @@
 
   chooser_ = delegate->RunChooser(
       &render_frame_host(), std::move(filters),
+      allowed_bluetooth_service_class_ids,
       base::BindOnce(&SerialService::FinishRequestPort,
                      weak_factory_.GetWeakPtr(), std::move(callback)));
 }
diff --git a/content/browser/serial/serial_service.h b/content/browser/serial/serial_service.h
index f72561e..f1f883f 100644
--- a/content/browser/serial/serial_service.h
+++ b/content/browser/serial/serial_service.h
@@ -41,6 +41,8 @@
       mojo::PendingRemote<blink::mojom::SerialServiceClient> client) override;
   void GetPorts(GetPortsCallback callback) override;
   void RequestPort(std::vector<blink::mojom::SerialPortFilterPtr> filters,
+                   const std::vector<::device::BluetoothUUID>&
+                       allowed_bluetooth_service_class_ids,
                    RequestPortCallback callback) override;
   void OpenPort(const base::UnguessableToken& token,
                 device::mojom::SerialConnectionOptionsPtr options,
diff --git a/content/browser/serial/serial_test_utils.cc b/content/browser/serial/serial_test_utils.cc
index d401aeb..c2b5f85 100644
--- a/content/browser/serial/serial_test_utils.cc
+++ b/content/browser/serial/serial_test_utils.cc
@@ -17,6 +17,7 @@
 std::unique_ptr<SerialChooser> MockSerialDelegate::RunChooser(
     RenderFrameHost* frame,
     std::vector<blink::mojom::SerialPortFilterPtr> filters,
+    std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids,
     SerialChooser::Callback callback) {
   std::move(callback).Run(RunChooserInternal());
   return nullptr;
diff --git a/content/browser/serial/serial_test_utils.h b/content/browser/serial/serial_test_utils.h
index 981adbb1a..4cb0e77 100644
--- a/content/browser/serial/serial_test_utils.h
+++ b/content/browser/serial/serial_test_utils.h
@@ -26,6 +26,7 @@
   std::unique_ptr<SerialChooser> RunChooser(
       RenderFrameHost* frame,
       std::vector<blink::mojom::SerialPortFilterPtr> filters,
+      std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids,
       SerialChooser::Callback callback) override;
 
   MOCK_METHOD0(RunChooserInternal, device::mojom::SerialPortInfoPtr());
diff --git a/content/browser/serial/serial_unittest.cc b/content/browser/serial/serial_unittest.cc
index e864f14..06600c6 100644
--- a/content/browser/serial/serial_unittest.cc
+++ b/content/browser/serial/serial_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/memory/raw_ptr_exclusion.h"
 #include "base/run_loop.h"
 #include "base/test/gmock_callback_support.h"
+#include "base/test/repeating_test_future.h"
 #include "base/test/test_future.h"
 #include "content/browser/serial/serial_test_utils.h"
 #include "content/public/common/content_client.h"
@@ -15,6 +16,7 @@
 #include "content/public/test/navigation_simulator.h"
 #include "content/test/test_render_view_host.h"
 #include "content/test/test_web_contents.h"
+#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/test_support/fake_message_dispatch_context.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
@@ -22,6 +24,7 @@
 #include "services/device/public/cpp/test/fake_serial_port_manager.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/serial/serial.mojom-blink.h"
 #include "url/origin.h"
 
 namespace content {
@@ -30,6 +33,7 @@
 
 using ::base::test::TestFuture;
 using ::testing::_;
+using ::testing::Invoke;
 using ::testing::Return;
 
 const char kTestUrl[] = "https://www.google.com";
@@ -100,6 +104,83 @@
 
 }  // namespace
 
+TEST_F(SerialTest, GetPortsForAllDeviceTypes) {
+  NavigateAndCommit(GURL(kTestUrl));
+
+  mojo::Remote<blink::mojom::SerialService> service;
+  contents()->GetPrimaryMainFrame()->BindSerialService(
+      service.BindNewPipeAndPassReceiver());
+
+  MockSerialServiceClient client;
+  service->SetClient(client.BindNewPipeAndPassRemote());
+  service.FlushForTesting();
+
+  // Platform Serial port
+  auto platform_token = base::UnguessableToken::Create();
+  auto platform_port_info = device::mojom::SerialPortInfo::New();
+  platform_port_info->token = platform_token;
+  port_manager()->AddPort(std::move(platform_port_info));
+
+  // USB Serial port
+  auto usb_token = base::UnguessableToken::Create();
+  auto usb_port_info = device::mojom::SerialPortInfo::New();
+  usb_port_info->token = usb_token;
+  usb_port_info->has_vendor_id = true;
+  usb_port_info->vendor_id = 0x1111;
+  usb_port_info->has_product_id = true;
+  usb_port_info->product_id = 0x2222;
+  port_manager()->AddPort(std::move(usb_port_info));
+
+  // Bluetooth Serial port
+  const device::BluetoothUUID kServiceClassId(
+      "ac822b69-d7e9-4bab-8fa6-ce40c87e1ac4");
+  auto bluetooth_token = base::UnguessableToken::Create();
+  auto bluetooth_port_info = device::mojom::SerialPortInfo::New();
+  bluetooth_port_info->token = bluetooth_token;
+  bluetooth_port_info->bluetooth_service_class_id = kServiceClassId;
+  port_manager()->AddPort(std::move(bluetooth_port_info));
+
+  EXPECT_CALL(delegate(), HasPortPermission(_, _))
+      .Times(3)
+      .WillRepeatedly(Return(true));
+  TestFuture<std::vector<blink::mojom::SerialPortInfoPtr>> future;
+  service->GetPorts(future.GetCallback());
+
+  auto ports = future.Take();
+  // Assert as we need to access all three ports.
+  ASSERT_EQ(ports.size(), 3u);
+  // Ports are not in any particular order so we will loop through and check
+  // according to the token.
+  bool has_platform = false;
+  bool has_usb = false;
+  bool has_bluetooth = false;
+  for (const auto& port : ports) {
+    if (port->token == platform_token) {
+      has_platform = true;
+      EXPECT_EQ(port->has_usb_vendor_id, false);
+      EXPECT_EQ(port->has_usb_product_id, false);
+      EXPECT_FALSE(port->bluetooth_service_class_id.has_value());
+    } else if (port->token == usb_token) {
+      has_usb = true;
+      EXPECT_EQ(port->has_usb_vendor_id, true);
+      EXPECT_EQ(port->usb_vendor_id, 0x1111);
+      EXPECT_EQ(port->has_usb_product_id, true);
+      EXPECT_EQ(port->usb_product_id, 0x2222);
+      EXPECT_FALSE(port->bluetooth_service_class_id.has_value());
+    } else if (port->token == bluetooth_token) {
+      has_bluetooth = true;
+      EXPECT_EQ(port->has_usb_vendor_id, false);
+      EXPECT_EQ(port->has_usb_product_id, false);
+      EXPECT_EQ(port->bluetooth_service_class_id, kServiceClassId);
+    } else {
+      ADD_FAILURE() << "Unexpected port token: " << port->token;
+    }
+  }
+  EXPECT_TRUE(has_platform);
+  EXPECT_TRUE(has_usb);
+  EXPECT_TRUE(has_bluetooth);
+}
+
 TEST_F(SerialTest, OpenAndClosePort) {
   NavigateAndCommit(GURL(kTestUrl));
 
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index 400db46..82ee853 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -4566,9 +4566,10 @@
 
   // Simulate timeout.
   EXPECT_TRUE(version->timeout_timer_.IsRunning());
-  version->start_time_ = base::TimeTicks::Now() -
-                         ServiceWorkerVersion::kWarmUpDuration -
-                         base::Minutes(1);
+  version->start_time_ =
+      base::TimeTicks::Now() -
+      blink::features::kSpeculativeServiceWorkerWarmUpDuration.Get() -
+      base::Minutes(1);
   version->timeout_timer_.user_task().Run();
   while (version->running_status() != EmbeddedWorkerStatus::STOPPED) {
     base::RunLoop().RunUntilIdle();
@@ -4593,6 +4594,259 @@
       static_cast<int>(blink::ServiceWorkerStatusCode::kOk), 1);
 }
 
+// This is a test class to verify an optimization to speculatively
+// warm-up a service worker.
+class ServiceWorkerWarmUpBrowserTestBase : public ServiceWorkerBrowserTest {
+ public:
+  ServiceWorkerWarmUpBrowserTestBase() = default;
+  ~ServiceWorkerWarmUpBrowserTestBase() override = default;
+
+  void SetUpOnMainThread() override {
+    ServiceWorkerBrowserTest::SetUpOnMainThread();
+    StartServerAndNavigateToSetup();
+  }
+
+  WebContents* web_contents() const { return shell()->web_contents(); }
+
+  RenderFrameHost* GetPrimaryMainFrame() {
+    return web_contents()->GetPrimaryMainFrame();
+  }
+
+  scoped_refptr<ServiceWorkerVersion> RegisterServiceWorker(const GURL& url,
+                                                            const GURL& scope) {
+    // Register a service worker.
+    WorkerRunningStatusObserver observer1(public_context());
+    EXPECT_TRUE(NavigateToURL(shell(), url));
+    const base::StringPiece script = R"(
+      (async () => {
+        await navigator.serviceWorker.register('fetch_event.js', {scope: $1});
+        await navigator.serviceWorker.ready;
+        return 'DONE';
+      })();
+    )";
+    EXPECT_EQ("DONE", EvalJs(GetPrimaryMainFrame(), JsReplace(script, scope)));
+    observer1.WaitUntilRunning();
+
+    scoped_refptr<ServiceWorkerVersion> version =
+        wrapper()->GetLiveVersion(observer1.version_id());
+    EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version->running_status());
+
+    // Stop the current running service worker.
+    StopServiceWorker(version.get());
+    EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version->running_status());
+    return version;
+  }
+
+  void AddAnchor(const std::string& id, const GURL& url) {
+    const base::StringPiece script = R"(
+      const a = document.createElement('a');
+      a.id = $1;
+      a.href = $2;
+      a.text = $1;
+      document.body.appendChild(a);
+    )";
+    EXPECT_TRUE(ExecJs(GetPrimaryMainFrame(), JsReplace(script, id, url)));
+  }
+};
+
+// This is a test class to verify an optimization to speculatively
+// warm-up a service worker by anchor visibility.
+class ServiceWorkerWarmUpByVisibilityBrowserTest
+    : public ServiceWorkerWarmUpBrowserTestBase,
+      public testing::WithParamInterface<int> {
+ public:
+  ServiceWorkerWarmUpByVisibilityBrowserTest() {
+    feature_list_.InitWithFeaturesAndParameters(
+        {{blink::features::kSpeculativeServiceWorkerWarmUp,
+          {
+              {blink::features::kSpeculativeServiceWorkerWarmUpMaxCount.name,
+               base::NumberToString(GetServiceWorkerWarmUpMaxCount())},
+              {blink::features::kSpeculativeServiceWorkerWarmUpOnVisible.name,
+               "true"},
+              {blink::features::kSpeculativeServiceWorkerWarmUpOnPointerover
+                   .name,
+               "false"},
+              {blink::features::kSpeculativeServiceWorkerWarmUpOnPointerdown
+                   .name,
+               "false"},
+          }}},
+        {});
+  }
+  ~ServiceWorkerWarmUpByVisibilityBrowserTest() override = default;
+
+  int GetServiceWorkerWarmUpMaxCount() { return GetParam(); }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         ServiceWorkerWarmUpByVisibilityBrowserTest,
+                         testing::Values(/*warm_up_max_count=*/1,
+                                         /*warm_up_max_count=*/2));
+
+IN_PROC_BROWSER_TEST_P(ServiceWorkerWarmUpByVisibilityBrowserTest,
+                       VisibleAnchorWillWarmUpServiceWorker) {
+  const GURL in_scope_url1(
+      embedded_test_server()->GetURL("/service_worker/empty.html"));
+  const GURL in_scope_url2(
+      embedded_test_server()->GetURL("/service_worker/empty2.html"));
+  const GURL out_scope_url(embedded_test_server()->GetURL("/empty.html"));
+  base::RunLoop run_loop;
+
+  scoped_refptr<ServiceWorkerVersion> version1 =
+      RegisterServiceWorker(in_scope_url1, in_scope_url1);
+  scoped_refptr<ServiceWorkerVersion> version2 =
+      RegisterServiceWorker(in_scope_url2, in_scope_url2);
+
+  // Navigate away from the service worker's scope.
+  EXPECT_TRUE(NavigateToURL(shell(), out_scope_url));
+  EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version1->running_status());
+  EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version2->running_status());
+
+  // When an anchor is added to a document, the IntersectionObserver
+  // begins monitoring whether the anchor is visible in the viewport. If
+  // the anchor becomes visible, and if the anchor's href URL registers
+  // a service worker, then the relevant service worker is warmed up.
+  AddAnchor("in_scope_url1", in_scope_url1);
+  AddAnchor("in_scope_url2", in_scope_url2);
+
+  if (GetServiceWorkerWarmUpMaxCount() == 1) {
+    // Wait until version1 or version2 is warmed up.
+    while (!(version1->IsWarmedUp() || version2->IsWarmedUp())) {
+      run_loop.RunUntilIdle();
+    }
+    // Make sure that only one version is warmed up.
+    EXPECT_FALSE(version1->IsWarmedUp() && version2->IsWarmedUp());
+  } else if (GetServiceWorkerWarmUpMaxCount() == 2) {
+    // Wait until version1 and version2 are warmed up.
+    while (!(version1->IsWarmedUp() && version2->IsWarmedUp())) {
+      run_loop.RunUntilIdle();
+    }
+  } else {
+    NOTREACHED();
+  }
+}
+
+// Pointer triggered ServiceWorkerWarmUp is not currently available on Android.
+#if !BUILDFLAG(IS_ANDROID)
+
+struct ServiceWorkerWarmUpByPointerBrowserTestParam {
+  bool enable_warm_up_by_pointerover;
+  bool enable_warm_up_by_pointerdown;
+};
+
+// This is a test class to verify an optimization to speculatively
+// warm-up a service worker by pointer.
+class ServiceWorkerWarmUpByPointerBrowserTest
+    : public ServiceWorkerWarmUpBrowserTestBase,
+      public testing::WithParamInterface<
+          ServiceWorkerWarmUpByPointerBrowserTestParam> {
+ public:
+  ServiceWorkerWarmUpByPointerBrowserTest() {
+    feature_list_.InitWithFeaturesAndParameters(
+        {{blink::features::kSpeculativeServiceWorkerWarmUp,
+          {
+              {blink::features::kSpeculativeServiceWorkerWarmUpMaxCount.name,
+               "10"},
+              {blink::features::kSpeculativeServiceWorkerWarmUpOnVisible.name,
+               "false"},
+              {blink::features::kSpeculativeServiceWorkerWarmUpOnPointerover
+                   .name,
+               GetParam().enable_warm_up_by_pointerover ? "true" : "false"},
+              {blink::features::kSpeculativeServiceWorkerWarmUpOnPointerdown
+                   .name,
+               GetParam().enable_warm_up_by_pointerdown ? "true" : "false"},
+          }}},
+        {});
+  }
+  ~ServiceWorkerWarmUpByPointerBrowserTest() override = default;
+
+  void SimulateMouseEventAndWait(blink::WebInputEvent::Type type,
+                                 blink::WebMouseEvent::Button button,
+                                 const gfx::Point& point) {
+    InputEventAckWaiter waiter(
+        web_contents()->GetPrimaryMainFrame()->GetRenderWidgetHost(), type);
+    SimulateMouseEvent(web_contents(), type, button, point);
+    waiter.Wait();
+  }
+
+  void SimulateMouseMoveWithElementIdAndWait(const std::string& id) {
+    gfx::Point point = gfx::ToFlooredPoint(
+        GetCenterCoordinatesOfElementWithId(web_contents(), id));
+    SimulateMouseEventAndWait(blink::WebMouseEvent::Type::kMouseMove,
+                              blink::WebMouseEvent::Button::kNoButton, point);
+  }
+
+  void SimulateMouseDownWithElementIdAndWait(const std::string& id) {
+    gfx::Point point = gfx::ToFlooredPoint(
+        GetCenterCoordinatesOfElementWithId(web_contents(), id));
+    SimulateMouseEventAndWait(blink::WebMouseEvent::Type::kMouseDown,
+                              blink::WebMouseEvent::Button::kLeft, point);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+const ServiceWorkerWarmUpByPointerBrowserTestParam
+    kServiceWorkerWarmUpByPointerBrowserTestParams[] = {
+        {
+            .enable_warm_up_by_pointerover = true,
+            .enable_warm_up_by_pointerdown = false,
+        },
+        {
+            .enable_warm_up_by_pointerover = false,
+            .enable_warm_up_by_pointerdown = true,
+        },
+        {
+            .enable_warm_up_by_pointerover = true,
+            .enable_warm_up_by_pointerdown = true,
+        },
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    ServiceWorkerWarmUpByPointerBrowserTest,
+    testing::ValuesIn(kServiceWorkerWarmUpByPointerBrowserTestParams));
+
+IN_PROC_BROWSER_TEST_P(ServiceWorkerWarmUpByPointerBrowserTest,
+                       PointeroverOrPointerdownWillWarmUpServiceWorker) {
+  const GURL in_scope_url(
+      embedded_test_server()->GetURL("/service_worker/empty.html"));
+  const GURL out_scope_url(embedded_test_server()->GetURL("/empty.html"));
+  base::RunLoop run_loop;
+
+  scoped_refptr<ServiceWorkerVersion> version =
+      RegisterServiceWorker(in_scope_url, in_scope_url);
+
+  // Navigate away from the service worker's scope.
+  EXPECT_TRUE(NavigateToURL(shell(), out_scope_url));
+  EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version->running_status());
+
+  AddAnchor("in_scope_url", in_scope_url);
+
+  run_loop.RunUntilIdle();
+
+  // To ensure that the pointerover event is triggered, move the pointer away
+  // from the anchor area.
+  SimulateMouseEventAndWait(blink::WebMouseEvent::Type::kMouseMove,
+                            blink::WebMouseEvent::Button::kNoButton,
+                            gfx::Point(1000, 1000));
+
+  SimulateMouseMoveWithElementIdAndWait("in_scope_url");
+
+  if (GetParam().enable_warm_up_by_pointerdown) {
+    SimulateMouseDownWithElementIdAndWait("in_scope_url");
+  }
+
+  while (!version->IsWarmedUp()) {
+    run_loop.RunUntilIdle();
+  }
+}
+
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 class ServiceWorkerBypassFetchHandlerTest
     : public ServiceWorkerBrowserTest,
       public testing::WithParamInterface<
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index 5cd0a30..5692a1a 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -7,6 +7,7 @@
 #include <limits>
 #include <memory>
 #include <set>
+#include <tuple>
 #include <utility>
 
 #include "base/barrier_closure.h"
@@ -215,6 +216,15 @@
   base::OnceClosure callback_;
 };
 
+int GetWarmedUpServiceWorkerCount(
+    const std::map<int64_t, ServiceWorkerVersion*>& live_versions) {
+  return base::ranges::count_if(live_versions, [](const auto& iter) {
+    ServiceWorkerVersion& service_worker_version = *iter.second;
+    return service_worker_version.IsWarmingUp() ||
+           service_worker_version.IsWarmedUp();
+  });
+}
+
 }  // namespace
 
 ServiceWorkerContextCore::ContainerHostIterator::~ContainerHostIterator() =
@@ -696,6 +706,47 @@
   loop.Run();
 }
 
+void ServiceWorkerContextCore::AddWarmUpRequest(
+    const GURL& document_url,
+    const blink::StorageKey& key,
+    ServiceWorkerContextCore::WarmUpServiceWorkerCallback callback) {
+  const size_t kRequestQueueLength =
+      blink::features::kSpeculativeServiceWorkerWarmUpRequestQueueLength.Get();
+
+  warm_up_requests_.emplace_back(document_url, key, std::move(callback));
+
+  while (warm_up_requests_.size() > kRequestQueueLength) {
+    auto [front_url, front_key, front_callback] =
+        std::move(warm_up_requests_.front());
+    std::move(front_callback).Run();
+    warm_up_requests_.pop_front();
+  }
+}
+
+absl::optional<ServiceWorkerContextCore::WarmUpRequest>
+ServiceWorkerContextCore::PopNextWarmUpRequest() {
+  DCHECK(!IsProcessingWarmingUp());
+
+  if (warm_up_requests_.empty()) {
+    return absl::nullopt;
+  }
+
+  if (GetWarmedUpServiceWorkerCount(live_versions_) >=
+      blink::features::kSpeculativeServiceWorkerWarmUpMaxCount.Get()) {
+    warm_up_requests_.clear();
+    return absl::nullopt;
+  }
+
+  // Return the most recent queued request (LIFO order) to prioritize recently
+  // added URLs. For example, the recent mouse-hoverd link will have a higher
+  // chance to navigate than the previously mouse-hoverd link.
+  absl::optional<ServiceWorkerContextCore::WarmUpRequest> request(
+      std::move(warm_up_requests_.back()));
+  warm_up_requests_.pop_back();
+  BeginProcessingWarmingUp();
+  return request;
+}
+
 void ServiceWorkerContextCore::RegistrationComplete(
     const GURL& scope,
     const blink::StorageKey& key,
diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h
index 4c29567..873c26e 100644
--- a/content/browser/service_worker/service_worker_context_core.h
+++ b/content/browser/service_worker/service_worker_context_core.h
@@ -12,6 +12,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/circular_deque.h"
 #include "base/containers/id_map.h"
 #include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
@@ -29,6 +30,7 @@
 #include "content/public/browser/service_worker_context.h"
 #include "mojo/public/cpp/bindings/associated_receiver_set.h"
 #include "mojo/public/cpp/bindings/receiver.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom-forward.h"
 
@@ -68,9 +70,13 @@
                               int64_t registration_id)>;
   using UnregistrationCallback =
       base::OnceCallback<void(blink::ServiceWorkerStatusCode status)>;
+  using WarmUpServiceWorkerCallback = base::OnceCallback<void()>;
   using ContainerHostByClientUUIDMap =
       std::map<std::string, std::unique_ptr<ServiceWorkerContainerHost>>;
 
+  using WarmUpRequest =
+      std::tuple<GURL, blink::StorageKey, WarmUpServiceWorkerCallback>;
+
   // Iterates over ServiceWorkerContainerHost objects in the
   // ContainerHostByClientUUIDMap.
   // Note: As ContainerHostIterator is operating on a member of
@@ -379,6 +385,21 @@
   // which are called in InitializeRegisteredOrigins().
   void WaitForRegistrationsInitializedForTest();
 
+  // Enqueue a warm-up request that consists of a tuple of (document_url, key,
+  // callback). The added request will be consumed in LIFO order. If the
+  // `warm_up_requests_` queue size exceeds the limit, then the older entries
+  // will be removed from the queue, and the removed entry's callbacks will be
+  // triggered.
+  void AddWarmUpRequest(const GURL& document_url,
+                        const blink::StorageKey& key,
+                        WarmUpServiceWorkerCallback callback);
+
+  absl::optional<WarmUpRequest> PopNextWarmUpRequest();
+
+  bool IsProcessingWarmingUp() const { return is_processing_warming_up_; }
+  void BeginProcessingWarmingUp() { is_processing_warming_up_ = true; }
+  void EndProcessingWarmingUp() { is_processing_warming_up_ = false; }
+
  private:
   friend class ServiceWorkerContextCoreTest;
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextCoreTest, FailureInfo);
@@ -500,6 +521,10 @@
   bool registrations_initialized_ = false;
   base::OnceClosure on_registrations_initialized_for_test_;
 
+  base::circular_deque<WarmUpRequest> warm_up_requests_;
+
+  bool is_processing_warming_up_ = false;
+
   base::WeakPtrFactory<ServiceWorkerContextCore> weak_factory_{this};
 };
 
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 5b51392..1445a22b 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -850,6 +850,38 @@
           this, std::move(callback)));
 }
 
+void ServiceWorkerContextWrapper::WarmUpServiceWorker(
+    const GURL& document_url,
+    const blink::StorageKey& key,
+    ServiceWorkerContextCore::WarmUpServiceWorkerCallback callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  if (!context_core_) {
+    std::move(callback).Run();
+    return;
+  }
+
+  // Checking this is for performance optimization. Without this check,
+  // following FindRegistrationForClientUrl() can detect if the given URL has
+  // service worker registration or not. But FindRegistrationForClientUrl()
+  // takes time to compute. Hence avoid calling it when the given URL clearly
+  // doesn't register service workers.
+  if (!OriginCanAccessServiceWorkers(document_url)) {
+    std::move(callback).Run();
+    return;
+  }
+
+  context_core_->AddWarmUpRequest(document_url, key, std::move(callback));
+
+  // If a service worker warm-up process is already running, do not call
+  // `MaybeProcessPendingWarmUpRequest()` here. Instead, expect that
+  // `MaybeProcessPendingWarmUpRequest()` will be called at the end of the
+  // current warm-up process.
+  if (!context_core_->IsProcessingWarmingUp()) {
+    MaybeProcessPendingWarmUpRequest();
+  }
+}
+
 void ServiceWorkerContextWrapper::StopAllServiceWorkersForStorageKey(
     const blink::StorageKey& key) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -1349,6 +1381,32 @@
           include_installing_version, std::move(callback)));
 }
 
+void ServiceWorkerContextWrapper::MaybeProcessPendingWarmUpRequest() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  context_core_->EndProcessingWarmingUp();
+
+  absl::optional<ServiceWorkerContextCore::WarmUpRequest> request =
+      context_core_->PopNextWarmUpRequest();
+
+  if (!request) {
+    return;
+  }
+
+  auto [document_url, key, callback] = std::move(*request);
+
+  DCHECK(document_url.is_valid());
+  TRACE_EVENT1("ServiceWorker",
+               "ServiceWorkerContextWrapper::MaybeProcessPendingWarmUpRequest",
+               "document_url", document_url.spec());
+
+  context_core_->registry()->FindRegistrationForClientUrl(
+      ServiceWorkerRegistry::Purpose::kNotForNavigation,
+      net::SimplifyUrlForRequest(document_url), key,
+      base::BindOnce(&ServiceWorkerContextWrapper::DidFindRegistrationForWarmUp,
+                     this, std::move(callback)));
+}
+
 void ServiceWorkerContextWrapper::DidFindRegistrationForFindImpl(
     bool include_installing_version,
     FindRegistrationCallback callback,
@@ -1522,6 +1580,46 @@
           : StartServiceWorkerForNavigationHintResult::FAILED);
 }
 
+void ServiceWorkerContextWrapper::DidFindRegistrationForWarmUp(
+    ServiceWorkerContextCore::WarmUpServiceWorkerCallback callback,
+    blink::ServiceWorkerStatusCode status,
+    scoped_refptr<ServiceWorkerRegistration> registration) {
+  TRACE_EVENT1("ServiceWorker", "DidFindRegistrationForWarmUp", "status",
+               blink::ServiceWorkerStatusToString(status));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  if (!registration) {
+    CHECK_NE(status, blink::ServiceWorkerStatusCode::kOk);
+  }
+  if (!registration || !registration->active_version() ||
+      registration->active_version()->fetch_handler_existence() ==
+          ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST ||
+      registration->active_version()->running_status() ==
+          EmbeddedWorkerStatus::RUNNING) {
+    std::move(callback).Run();
+    MaybeProcessPendingWarmUpRequest();
+    return;
+  }
+
+  registration->active_version()->StartWorker(
+      ServiceWorkerMetrics::EventType::WARM_UP,
+      base::BindOnce(&ServiceWorkerContextWrapper::DidWarmUpServiceWorker, this,
+                     registration->scope(), std::move(callback)));
+}
+
+void ServiceWorkerContextWrapper::DidWarmUpServiceWorker(
+    const GURL& scope,
+    ServiceWorkerContextCore::WarmUpServiceWorkerCallback callback,
+    blink::ServiceWorkerStatusCode code) {
+  TRACE_EVENT2("ServiceWorker", "DidWarmUpServiceWorker", "url", scope.spec(),
+               "code", blink::ServiceWorkerStatusToString(code));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  std::move(callback).Run();
+
+  MaybeProcessPendingWarmUpRequest();
+}
+
 ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return context_core_.get();
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index 4d67c9a4..62b5325 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -208,6 +208,10 @@
       const GURL& document_url,
       const blink::StorageKey& key,
       StartServiceWorkerForNavigationHintCallback callback) override;
+  void WarmUpServiceWorker(
+      const GURL& document_url,
+      const blink::StorageKey& key,
+      ServiceWorkerContextCore::WarmUpServiceWorkerCallback callback);
   void StopAllServiceWorkersForStorageKey(
       const blink::StorageKey& key) override;
   void StopAllServiceWorkers(base::OnceClosure callback) override;
@@ -433,6 +437,8 @@
                                     bool include_installing_version,
                                     FindRegistrationCallback callback);
 
+  void MaybeProcessPendingWarmUpRequest();
+
   void DidFindRegistrationForFindImpl(
       bool include_installing_version,
       FindRegistrationCallback callback,
@@ -458,11 +464,21 @@
       blink::ServiceWorkerStatusCode status,
       scoped_refptr<ServiceWorkerRegistration> registration);
 
+  void DidFindRegistrationForWarmUp(
+      ServiceWorkerContextCore::WarmUpServiceWorkerCallback callback,
+      blink::ServiceWorkerStatusCode status,
+      scoped_refptr<ServiceWorkerRegistration> registration);
+
   void DidStartServiceWorkerForNavigationHint(
       const GURL& scope,
       StartServiceWorkerForNavigationHintCallback callback,
       blink::ServiceWorkerStatusCode code);
 
+  void DidWarmUpServiceWorker(
+      const GURL& scope,
+      ServiceWorkerContextCore::WarmUpServiceWorkerCallback callback,
+      blink::ServiceWorkerStatusCode code);
+
   void DidFindRegistrationForMessageDispatch(
       blink::TransferableMessage message,
       const GURL& source_origin,
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 7a9d9844..bfa274d 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -254,7 +254,6 @@
 constexpr base::TimeDelta ServiceWorkerVersion::kTimeoutTimerDelay;
 constexpr base::TimeDelta ServiceWorkerVersion::kStartNewWorkerTimeout;
 constexpr base::TimeDelta ServiceWorkerVersion::kStopWorkerTimeout;
-constexpr base::TimeDelta ServiceWorkerVersion::kWarmUpDuration;
 
 ServiceWorkerVersion::MainScriptResponse::MainScriptResponse(
     const network::mojom::URLResponseHead& response_head) {
@@ -2335,7 +2334,8 @@
                                     : kStartNewWorkerTimeout;
 
   if (embedded_worker_->pause_initializing_global_scope()) {
-    start_limit = kWarmUpDuration;
+    start_limit =
+        blink::features::kSpeculativeServiceWorkerWarmUpDuration.Get();
   }
 
   if (GetTickDuration(start_time_) > start_limit) {
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 841075e..2da48ec 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -851,8 +851,6 @@
   static constexpr base::TimeDelta kStartNewWorkerTimeout = base::Minutes(5);
   // Timeout for the worker to stop.
   static constexpr base::TimeDelta kStopWorkerTimeout = base::Seconds(5);
-  // Duration to keep worker warmed-up.
-  static constexpr base::TimeDelta kWarmUpDuration = base::Minutes(10);
 
   ~ServiceWorkerVersion() override;
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index f36fb12..c7b82e0 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1392,10 +1392,15 @@
     view_->SetOverscrollControllerEnabled(CanOverscrollContent());
 }
 
-RenderFrameHostImpl* WebContentsImpl::GetPrimaryMainFrame() {
+const RenderFrameHostImpl* WebContentsImpl::GetPrimaryMainFrame() const {
   return primary_frame_tree_.root()->current_frame_host();
 }
 
+RenderFrameHostImpl* WebContentsImpl::GetPrimaryMainFrame() {
+  return const_cast<RenderFrameHostImpl*>(
+      std::as_const(*this).GetPrimaryMainFrame());
+}
+
 PageImpl& WebContentsImpl::GetPrimaryPage() {
   // We should not be accessing Page during the destruction of this WebContents,
   // as the Page has already been cleared.
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 3eb26a7..359beee 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -340,6 +340,7 @@
   const GURL& GetURL() override;
   const GURL& GetVisibleURL() override;
   const GURL& GetLastCommittedURL() override;
+  const RenderFrameHostImpl* GetPrimaryMainFrame() const override;
   RenderFrameHostImpl* GetPrimaryMainFrame() override;
   PageImpl& GetPrimaryPage() override;
   RenderFrameHostImpl* GetFocusedFrame() override;
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
index 16c9ccf..a9f8cf4 100644
--- a/content/browser/webid/federated_auth_request_impl.cc
+++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -325,11 +325,8 @@
     const url::Origin& top_frame_origin,
     const url::Origin& iframe_origin,
     CompleteRequestWithErrorCallback callback) {
-  // TODO(crbug.com/1418719): Replace exclude_iframe based on client metadata
-  // response.
-  bool exclude_iframe = net::registry_controlled_domains::SameDomainOrHost(
-      top_frame_origin, iframe_origin,
-      net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+  // TOOD(crbug.com/1448566): clean up the logic to allow 3 domains.
+  bool exclude_iframe = true;
   absl::optional<std::string> iframe_for_display = absl::nullopt;
 
   if (!exclude_iframe) {
diff --git a/content/browser/webid/federated_auth_request_impl_multiple_frames_unittest.cc b/content/browser/webid/federated_auth_request_impl_multiple_frames_unittest.cc
index ed184fb..fa038a8 100644
--- a/content/browser/webid/federated_auth_request_impl_multiple_frames_unittest.cc
+++ b/content/browser/webid/federated_auth_request_impl_multiple_frames_unittest.cc
@@ -399,7 +399,6 @@
   EXPECT_EQ(RequestTokenStatus::kSuccess, iframe_callback_helper.status());
   EXPECT_TRUE(iframe_dialog_state.did_show_accounts_dialog);
   EXPECT_EQ("top-frame.example", iframe_dialog_state.top_frame_for_display);
-  EXPECT_EQ("cross-site.example", iframe_dialog_state.iframe_for_display);
 }
 
 // Tests that preventSilentAccess UKM is not recorded if the embedder does not
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index 120fb37..1d1d418 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -219,6 +219,7 @@
     "java/src/org/chromium/content/browser/GestureListenerManagerImpl.java",
     "java/src/org/chromium/content/browser/GpuProcessCallback.java",
     "java/src/org/chromium/content/browser/HostZoomMapImpl.java",
+    "java/src/org/chromium/content/browser/ImpressionUtils.java",
     "java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java",
     "java/src/org/chromium/content/browser/JavascriptInjectorImpl.java",
     "java/src/org/chromium/content/browser/JavascriptInterface.java",
@@ -344,6 +345,7 @@
     "java/src/org/chromium/content_public/browser/ImageDownloadCallback.java",
     "java/src/org/chromium/content_public/browser/ImeAdapter.java",
     "java/src/org/chromium/content_public/browser/ImeEventObserver.java",
+    "java/src/org/chromium/content_public/browser/Impression.java",
     "java/src/org/chromium/content_public/browser/InputMethodManagerWrapper.java",
     "java/src/org/chromium/content_public/browser/InterfaceRegistrar.java",
     "java/src/org/chromium/content_public/browser/JavaScriptCallback.java",
@@ -445,6 +447,7 @@
     "java/src/org/chromium/content/browser/GestureListenerManagerImpl.java",
     "java/src/org/chromium/content/browser/GpuProcessCallback.java",
     "java/src/org/chromium/content/browser/HostZoomMapImpl.java",
+    "java/src/org/chromium/content/browser/ImpressionUtils.java",
     "java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java",
     "java/src/org/chromium/content/browser/JavascriptInjectorImpl.java",
     "java/src/org/chromium/content/browser/LauncherThread.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ImpressionUtils.java b/content/public/android/java/src/org/chromium/content/browser/ImpressionUtils.java
new file mode 100644
index 0000000..3d5f6e9a
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/ImpressionUtils.java
@@ -0,0 +1,46 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import org.chromium.base.UnguessableToken;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.content_public.browser.Impression;
+
+/**
+ * Interface which provides native access to an Impression.
+ */
+@JNINamespace("content")
+public class ImpressionUtils {
+    private ImpressionUtils() {}
+
+    @CalledByNative
+    private static Impression create(UnguessableToken attributionSrcToken,
+            UnguessableToken initiatorFrameToken, int initiatorProcessID,
+            long attributionRuntimeFeatures) {
+        return new Impression(attributionSrcToken, initiatorFrameToken, initiatorProcessID,
+                attributionRuntimeFeatures);
+    }
+
+    @CalledByNative
+    private static UnguessableToken getAttributionSrcToken(Impression impression) {
+        return impression.getAttributionSrcToken();
+    }
+
+    @CalledByNative
+    private static UnguessableToken getInitiatorFrameToken(Impression impression) {
+        return impression.getInitiatorFrameToken();
+    }
+
+    @CalledByNative
+    private static int getInitiatorProcessID(Impression impression) {
+        return impression.getInitiatorProcessID();
+    }
+
+    @CalledByNative
+    private static long getAttributionRuntimeFeatures(Impression impression) {
+        return impression.getAttributionRuntimeFeatures();
+    }
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java
index 063d36a1..f1af3b6 100644
--- a/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java
@@ -14,6 +14,7 @@
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.content_public.browser.Impression;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.NavigationController;
 import org.chromium.content_public.browser.NavigationEntry;
@@ -184,7 +185,7 @@
                     params.getDataUrlAsString(), params.getCanLoadLocalResources(),
                     params.getIsRendererInitiated(), params.getShouldReplaceCurrentEntry(),
                     params.getInitiatorOrigin(), params.getHasUserGesture(),
-                    params.getShouldClearHistoryList(), inputStart,
+                    params.getShouldClearHistoryList(), params.getImpression(), inputStart,
                     params.getNavigationUIDataSupplier() == null
                             ? 0
                             : params.getNavigationUIDataSupplier().get());
@@ -376,7 +377,8 @@
                 ResourceRequestBody postData, String baseUrlForDataUrl, String virtualUrlForDataUrl,
                 String dataUrlAsString, boolean canLoadLocalResources, boolean isRendererInitiated,
                 boolean shouldReplaceCurrentEntry, Origin initiatorOrigin, boolean hasUserGesture,
-                boolean shouldClearHistoryList, long inputStart, long navigationUIDataPtr);
+                boolean shouldClearHistoryList, Impression impression, long inputStart,
+                long navigationUIDataPtr);
         void clearHistory(long nativeNavigationControllerAndroid, NavigationControllerImpl caller);
         int getNavigationHistory(long nativeNavigationControllerAndroid,
                 NavigationControllerImpl caller, Object history);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/Impression.java b/content/public/android/java/src/org/chromium/content_public/browser/Impression.java
new file mode 100644
index 0000000..20ad486
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content_public/browser/Impression.java
@@ -0,0 +1,42 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content_public.browser;
+
+import org.chromium.base.UnguessableToken;
+
+/**
+ * Holds parameters for NavigationController::LoadUrlParams::Impression. This is used to route
+ * Attribution Reporting API parameters on navigations.
+ */
+public class Impression {
+    private final UnguessableToken mAttributionSrcToken;
+    private final UnguessableToken mInitiatorFrameToken;
+    private final long mAttributionRuntimeFeatures;
+    private final int mInitiatorProcessID;
+
+    public Impression(UnguessableToken attributionSrcToken, UnguessableToken initiatorFrameToken,
+            int initiatorProcessID, long attributionRuntimeFeatures) {
+        mAttributionSrcToken = attributionSrcToken;
+        mInitiatorFrameToken = initiatorFrameToken;
+        mInitiatorProcessID = initiatorProcessID;
+        mAttributionRuntimeFeatures = attributionRuntimeFeatures;
+    }
+
+    public UnguessableToken getAttributionSrcToken() {
+        return mAttributionSrcToken;
+    }
+
+    public UnguessableToken getInitiatorFrameToken() {
+        return mInitiatorFrameToken;
+    }
+
+    public int getInitiatorProcessID() {
+        return mInitiatorProcessID;
+    }
+
+    public long getAttributionRuntimeFeatures() {
+        return mAttributionRuntimeFeatures;
+    }
+}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java b/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java
index 07d42f4..bdcf2bf 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java
@@ -53,6 +53,8 @@
     private long mInputStartTimestamp;
     private boolean mHasUserGesture;
     private boolean mShouldClearHistoryList;
+    @Nullable
+    private Impression mImpression;
     private Supplier<Long> mNavigationUIDataSupplier;
 
     /**
@@ -129,6 +131,7 @@
         copy.mInputStartTimestamp = other.mInputStartTimestamp;
         copy.mHasUserGesture = other.mHasUserGesture;
         copy.mShouldClearHistoryList = other.mShouldClearHistoryList;
+        copy.mImpression = other.mImpression;
         return copy;
     }
 
@@ -602,6 +605,23 @@
         return mShouldClearHistoryList;
     }
 
+    /**
+     * Set the attribution impression associated with the load.
+     *
+     * @param impression Attribution impression associated with the load.
+     */
+    public void setImpression(Impression impression) {
+        mImpression = impression;
+    }
+
+    /**
+     * @return The attribution impression associated with the load.
+     */
+    @Nullable
+    public Impression getImpression() {
+        return mImpression;
+    }
+
     public boolean isBaseUrlDataScheme() {
         // If there's no base url set, but this is a data load then
         // treat the scheme as data:.
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index d95a0af..9b78e9cb 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -589,6 +589,7 @@
       "android/compositor_client.h",
       "android/devtools_auth.h",
       "android/gpu_video_accelerator_factories_provider.h",
+      "android/impression_android.h",
       "android/java_interfaces.h",
       "android/media_url_interceptor_register.cc",
       "android/media_url_interceptor_register.h",
diff --git a/content/public/browser/android/impression_android.h b/content/public/browser/android/impression_android.h
new file mode 100644
index 0000000..e053a27
--- /dev/null
+++ b/content/public/browser/android/impression_android.h
@@ -0,0 +1,27 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_ANDROID_IMPRESSION_ANDROID_H_
+#define CONTENT_PUBLIC_BROWSER_ANDROID_IMPRESSION_ANDROID_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/unguessable_token.h"
+#include "content/common/content_export.h"
+#include "services/network/public/cpp/attribution_reporting_runtime_features.h"
+#include "third_party/blink/public/common/tokens/tokens.h"
+
+namespace content {
+
+CONTENT_EXPORT base::android::ScopedJavaLocalRef<jobject> CreateJavaImpression(
+    JNIEnv* env,
+    base::UnguessableToken attribution_src_token,
+    base::UnguessableToken initiator_frame_token,
+    int initiator_process_id,
+    const network::AttributionReportingRuntimeFeatures& features);
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_ANDROID_IMPRESSION_ANDROID_H_
diff --git a/content/public/browser/origin_trials_controller_delegate.h b/content/public/browser/origin_trials_controller_delegate.h
index 93ef9e96..999c0bb5 100644
--- a/content/public/browser/origin_trials_controller_delegate.h
+++ b/content/public/browser/origin_trials_controller_delegate.h
@@ -11,18 +11,19 @@
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "content/common/content_export.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "url/origin.h"
 
 namespace content {
 
-// The |OriginTrialsControllerDelegate| interface exposes the functionality
+// The `OriginTrialsControllerDelegate` interface exposes the functionality
 // of the origin_trials component to the browser process.
 //
 // Use this class to check if a given persistent origin trial has been enabled
 // for the current profile.
 //
-// See |components/origin_trials/README.md| for more information.
-// TODO(https://crbug.com/1410180): Switch |partition_origin| to use Cookie
+// See `components/origin_trials/README.md` for more information.
+// TODO(https://crbug.com/1410180): Switch `partition_origin` to use Cookie
 // partitioning. This interface uses the last committed origin from the
 // outermost frame or document as partitioning as an interim measure to get a
 // stable partitioning key until cookie partitioning is fully rolled out.
@@ -30,16 +31,16 @@
  public:
   virtual ~OriginTrialsControllerDelegate() = default;
 
-  // Persist all enabled and persistable tokens in the |header_tokens|.
+  // Persist all enabled and persistable tokens in the `header_tokens`.
   //
-  // Token persistence is partitioned based on |partition_origin|, meaning that
-  // the storage keeps track of which |partition_origin|s have been seen when
+  // Token persistence is partitioned based on `partition_origin`, meaning that
+  // the storage keeps track of which `partition_origin`s have been seen when
   // persisting tokens for a given trial and origin.
   //
   // Subsequent calls to this method will update the registration of a token
-  // for an origin. Passing an empty |header_tokens| will effectively clear the
-  // persistence of tokens for the |origin| and |partition_origin|.
-  // TODO(https://crbug.com/1410180): Switch |partition_origin| to use Cookie
+  // for an origin. Passing an empty `header_tokens` will effectively clear the
+  // persistence of tokens for the `origin` and `partition_origin`.
+  // TODO(https://crbug.com/1410180): Switch `partition_origin` to use Cookie
   // partitioning.
   virtual void PersistTrialsFromTokens(
       const url::Origin& origin,
@@ -47,12 +48,12 @@
       const base::span<const std::string> header_tokens,
       const base::Time current_time) = 0;
 
-  // Appends all enabled and persistable |tokens| to the set of already enabled
-  // trials for |origin|. By passing |script_origins|, this method can be used
-  // to append third-party origin trials as well. If a token in |tokens| is a
+  // Appends all enabled and persistable `tokens` to the set of already enabled
+  // trials for `origin`. By passing `script_origins`, this method can be used
+  // to append third-party origin trials as well. If a token in `tokens` is a
   // third-party origin trial token, and the corresponding origin is present in
-  // |script_tokens|, then the trial will be enabled for the origin stored in
-  // the token itself, rather than any origin found in |script_origins|. This
+  // `script_tokens`, then the trial will be enabled for the origin stored in
+  // the token itself, rather than any origin found in `script_origins`. This
   // limitation means that subdomain matching does not work for third-party
   // origin trial tokens using this method.
   virtual void PersistAdditionalTrialsFromTokens(
@@ -62,21 +63,21 @@
       const base::span<const std::string> tokens,
       const base::Time current_time) = 0;
 
-  // Returns |true| if |trial_name| has been persisted for |origin|,
-  // partitioned by |partition_origin| and is still valid. This method should
+  // Returns `true` if `feature` has been persistently enabled for `origin`,
+  // partitioned by `partition_origin` and is still valid. This method should
   // be used by origin trial owners to check if the feature under trial should
   // be enabled.
-  // TODO(https://crbug.com/1410180): Switch |partition_origin| to use Cookie
+  // TODO(https://crbug.com/1410180): Switch `partition_origin` to use Cookie
   // partitioning.
-  virtual bool IsTrialPersistedForOrigin(const url::Origin& origin,
-                                         const url::Origin& partition_origin,
-                                         const base::StringPiece trial_name,
-                                         const base::Time current_time) = 0;
+  virtual bool IsFeaturePersistedForOrigin(const url::Origin& origin,
+                                           const url::Origin& partition_origin,
+                                           blink::OriginTrialFeature feature,
+                                           const base::Time current_time) = 0;
 
   // Return the list of persistent origin trials that have been saved for
-  // |origin|, partitioned by |partition_origin|, and haven't expired given the
-  // |current_time| parameter.
-  // TODO(https://crbug.com/1410180): Switch |partition_origin| to use Cookie
+  // `origin`, partitioned by `partition_origin`, and haven't expired given the
+  // `current_time` parameter.
+  // TODO(https://crbug.com/1410180): Switch `partition_origin` to use Cookie
   // partitioning.
   virtual base::flat_set<std::string> GetPersistedTrialsForOrigin(
       const url::Origin& origin,
diff --git a/content/public/browser/serial_delegate.h b/content/public/browser/serial_delegate.h
index 8f2e008f..eacc35a 100644
--- a/content/public/browser/serial_delegate.h
+++ b/content/public/browser/serial_delegate.h
@@ -44,6 +44,7 @@
   virtual std::unique_ptr<SerialChooser> RunChooser(
       RenderFrameHost* frame,
       std::vector<blink::mojom::SerialPortFilterPtr> filters,
+      std::vector<device::BluetoothUUID> allowed_bluetooth_service_class_ids,
       SerialChooser::Callback callback) = 0;
 
   // Returns whether |frame| has permission to request access to a port.
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index c998b081..eb08556 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -393,6 +393,7 @@
   // non-null except during WebContents destruction. This WebContents may
   // have additional main frames for prerendered pages, bfcached pages, etc.
   // See docs/frame_trees.md for more details.
+  virtual const RenderFrameHost* GetPrimaryMainFrame() const = 0;
   virtual RenderFrameHost* GetPrimaryMainFrame() = 0;
 
   // Returns the current page in the primary frame tree of this WebContents.
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 41e33b3..4feb7de4 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -839,6 +839,9 @@
 // In debug builds, asserts that the stream of input events is valid.
 const char kValidateInputEventStream[] = "validate-input-event-stream";
 
+// Causes tests to attempt to verify pixel output.
+const char kVerifyPixels[] = "browser-ui-tests-verify-pixels";
+
 // Will add kWaitForDebugger to every child processes. If a value is passed, it
 // will be used as a filter to determine if the child process should have the
 // kWaitForDebugger flag passed on or not.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index e992dab..f693867 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -228,6 +228,7 @@
 CONTENT_EXPORT extern const char kUtilitySubType[];
 CONTENT_EXPORT extern const char kV8CacheOptions[];
 CONTENT_EXPORT extern const char kValidateInputEventStream[];
+CONTENT_EXPORT extern const char kVerifyPixels[];
 CONTENT_EXPORT extern const char kWaitForDebuggerChildren[];
 CONTENT_EXPORT extern const char kWaitForDebuggerOnNavigation[];
 CONTENT_EXPORT extern const char kWaitForDebuggerWebUI[];
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index ede14ce2..0c3a9b41 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -86,7 +86,9 @@
 #include "services/tracing/public/cpp/trace_startup.h"
 #include "ui/base/ui_base_features.h"
 #include "ui/compositor/compositor_switches.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/display/display_switches.h"
+#include "ui/gfx/animation/animation_test_api.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_switches.h"
 
@@ -371,6 +373,16 @@
     command_line->AppendSwitch(switches::kDisableGLDrawingForTests);
 #endif
 
+  // Disable animations when verifying pixel output, as they make tests flaky.
+  if (command_line->HasSwitch(switches::kVerifyPixels)) {
+    disable_layer_animations_ =
+        std::make_unique<ui::ScopedAnimationDurationScaleMode>(
+            ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
+    disable_rich_animations_ =
+        gfx::AnimationTestApi::SetRichAnimationRenderMode(
+            gfx::Animation::RichAnimationRenderMode::FORCE_DISABLED);
+  }
+
   bool use_software_gl = true;
 
   // We usually use software GL as this works on all bots. The command
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h
index c26945f..4b38c78d 100644
--- a/content/public/test/browser_test_base.h
+++ b/content/public/test/browser_test_base.h
@@ -20,6 +20,7 @@
 #include <string>
 #include <utility>
 
+#include "base/auto_reset.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -37,6 +38,7 @@
 #include "storage/browser/quota/quota_settings.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/gfx/animation/animation.h"
 
 namespace base {
 class CommandLine;
@@ -48,6 +50,10 @@
 class ScopedDisableCrosapiForTesting;
 }
 
+namespace ui {
+class ScopedAnimationDurationScaleMode;
+}
+
 namespace content {
 class BrowserMainParts;
 class ContentMainDelegate;
@@ -268,6 +274,12 @@
   // the --force-device-scale-factor flag in SetUp.
   float force_device_scale_factor_ = 0.f;
 
+  // When verifying pixel output, animations are disabled to reduce flakiness.
+  std::unique_ptr<ui::ScopedAnimationDurationScaleMode>
+      disable_layer_animations_;
+  std::unique_ptr<base::AutoReset<gfx::Animation::RichAnimationRenderMode>>
+      disable_rich_animations_;
+
   // When true, do compositing with the software backend instead of using GL.
   bool use_software_compositing_ = false;
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3134ee7..5a68737 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5193,10 +5193,10 @@
     }
   }
 
-  if (frame_->IsOutermostMainFrame() && url.SchemeIsHTTPOrHTTPS() &&
-      !url.is_empty() &&
+  if (frame_->IsOutermostMainFrame() && url.is_valid() &&
+      url.SchemeIsHTTPOrHTTPS() &&
       base::FeatureList::IsEnabled(kSpeculativeServiceWorkerStartup)) {
-    frame_->WillPotentiallyStartOutermostMainFrameNavigation(url);
+    frame_->MaybeStartOutermostMainFrameNavigation(WebVector<WebURL>({url}));
   }
 
   // Depending on navigation policy, send one of three IPCs to the browser
diff --git a/content/renderer/render_view_browsertest_mac.mm b/content/renderer/render_view_browsertest_mac.mm
index fbdd782..4b0ab7e 100644
--- a/content/renderer/render_view_browsertest_mac.mm
+++ b/content/renderer/render_view_browsertest_mac.mm
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/apple/owned_objc.h"
 #include "base/run_loop.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -97,7 +98,8 @@
   const char* kArrowDownScrollDown = "40,false,false,true,false\n9844";
   blink_widget->AddEditCommandForNextKeyEvent(
       blink::WebString::FromLatin1("moveToEndOfDocument"), blink::WebString());
-  SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown));
+  SendNativeKeyEvent(
+      NativeWebKeyboardEvent(base::apple::OwnedNSEvent(arrowDownKeyDown)));
   base::RunLoop().RunUntilIdle();
   ExecuteJavaScriptForTests("scroll.textContent = window.pageYOffset");
   output = TestWebFrameContentDumper::DumpWebViewAsText(web_view_,
@@ -109,7 +111,8 @@
   blink_widget->AddEditCommandForNextKeyEvent(
       blink::WebString::FromLatin1("moveToBeginningOfDocument"),
       blink::WebString());
-  SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown));
+  SendNativeKeyEvent(
+      NativeWebKeyboardEvent(base::apple::OwnedNSEvent(arrowUpKeyDown)));
   base::RunLoop().RunUntilIdle();
   ExecuteJavaScriptForTests("scroll.textContent = window.pageYOffset");
   output = TestWebFrameContentDumper::DumpWebViewAsText(web_view_,
@@ -125,7 +128,8 @@
   const char* kArrowDownNoScroll = "40,false,false,true,false\n100";
   blink_widget->AddEditCommandForNextKeyEvent(
       blink::WebString::FromLatin1("moveToEndOfDocument"), blink::WebString());
-  SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown));
+  SendNativeKeyEvent(
+      NativeWebKeyboardEvent(base::apple::OwnedNSEvent(arrowDownKeyDown)));
   base::RunLoop().RunUntilIdle();
   ExecuteJavaScriptForTests("scroll.textContent = window.pageYOffset");
   output = TestWebFrameContentDumper::DumpWebViewAsText(web_view_,
@@ -137,7 +141,8 @@
   blink_widget->AddEditCommandForNextKeyEvent(
       blink::WebString::FromLatin1("moveToBeginningOfDocument"),
       blink::WebString());
-  SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown));
+  SendNativeKeyEvent(
+      NativeWebKeyboardEvent(base::apple::OwnedNSEvent(arrowUpKeyDown)));
   base::RunLoop().RunUntilIdle();
   ExecuteJavaScriptForTests("scroll.textContent = window.pageYOffset");
   output = TestWebFrameContentDumper::DumpWebViewAsText(web_view_,
diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc
index 2f4232e..358b0326b 100644
--- a/content/services/auction_worklet/bidder_worklet.cc
+++ b/content/services/auction_worklet/bidder_worklet.cc
@@ -21,6 +21,7 @@
 #include "base/task/bind_post_task.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
+#include "base/timer/elapsed_timer.h"
 #include "base/trace_event/trace_event.h"
 #include "base/types/optional_util.h"
 #include "content/services/auction_worklet/auction_v8_helper.h"
@@ -629,6 +630,7 @@
     ReportWinCallbackInternal callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
   TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "post_v8_task", trace_id);
+  base::ElapsedTimer elapsed_timer;
 
   AuctionV8Helper::FullIsolateScope isolate_scope(v8_helper_.get());
   v8::Isolate* isolate = v8_helper_->isolate();
@@ -651,6 +653,7 @@
     PostReportWinCallbackToUserThread(std::move(callback),
                                       /*report_url=*/absl::nullopt,
                                       /*ad_beacon_map=*/{}, /*pa_requests=*/{},
+                                      base::TimeDelta(),
                                       /*errors=*/std::vector<std::string>());
     return;
   }
@@ -717,6 +720,7 @@
     PostReportWinCallbackToUserThread(std::move(callback),
                                       /*report_url=*/absl::nullopt,
                                       /*ad_beacon_map=*/{}, /*pa_requests=*/{},
+                                      base::TimeDelta(),
                                       /*errors=*/std::vector<std::string>());
     return;
   }
@@ -738,6 +742,7 @@
     PostReportWinCallbackToUserThread(std::move(callback),
                                       /*report_url=*/absl::nullopt,
                                       /*ad_beacon_map=*/{}, /*pa_requests=*/{},
+                                      base::TimeDelta(),
                                       /*errors=*/std::move(errors_out));
     return;
   }
@@ -759,7 +764,7 @@
     PostReportWinCallbackToUserThread(
         std::move(callback), /*report_url=*/absl::nullopt,
         /*ad_beacon_map=*/{},
-        /*pa_requests=*/{}, std::move(errors_out));
+        /*pa_requests=*/{}, elapsed_timer.Elapsed(), std::move(errors_out));
     return;
   }
 
@@ -792,7 +797,7 @@
         /*ad_beacon_map=*/{},
         context_recycler.private_aggregation_bindings()
             ->TakePrivateAggregationRequests(),
-        std::move(errors_out));
+        elapsed_timer.Elapsed(), std::move(errors_out));
     return;
   }
 
@@ -803,7 +808,7 @@
       context_recycler.register_ad_beacon_bindings()->TakeAdBeaconMap(),
       context_recycler.private_aggregation_bindings()
           ->TakePrivateAggregationRequests(),
-      std::move(errors_out));
+      elapsed_timer.Elapsed(), std::move(errors_out));
 }
 
 void BidderWorklet::V8State::GenerateBid(
@@ -1364,12 +1369,14 @@
     const absl::optional<GURL>& report_url,
     base::flat_map<std::string, GURL> ad_beacon_map,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta reporting_latency,
     std::vector<std::string> errors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
   user_thread_->PostTask(
-      FROM_HERE, base::BindOnce(std::move(callback), std::move(report_url),
-                                std::move(ad_beacon_map),
-                                std::move(pa_requests), std::move(errors)));
+      FROM_HERE,
+      base::BindOnce(std::move(callback), std::move(report_url),
+                     std::move(ad_beacon_map), std::move(pa_requests),
+                     reporting_latency, std::move(errors)));
 }
 
 void BidderWorklet::V8State::PostErrorBidCallbackToUserThread(
@@ -1888,13 +1895,14 @@
     absl::optional<GURL> report_url,
     base::flat_map<std::string, GURL> ad_beacon_map,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta reporting_latency,
     std::vector<std::string> errors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
   errors.insert(errors.end(), load_code_error_msgs_.begin(),
                 load_code_error_msgs_.end());
   std::move(task->callback)
       .Run(std::move(report_url), std::move(ad_beacon_map),
-           std::move(pa_requests), std::move(errors));
+           std::move(pa_requests), reporting_latency, std::move(errors));
   report_win_tasks_.erase(task);
 }
 
diff --git a/content/services/auction_worklet/bidder_worklet.h b/content/services/auction_worklet/bidder_worklet.h
index b92374b..1e519cb 100644
--- a/content/services/auction_worklet/bidder_worklet.h
+++ b/content/services/auction_worklet/bidder_worklet.h
@@ -338,6 +338,7 @@
         base::OnceCallback<void(absl::optional<GURL> report_url,
                                 base::flat_map<std::string, GURL> ad_beacon_map,
                                 PrivateAggregationRequests pa_requests,
+                                base::TimeDelta reporting_latency,
                                 std::vector<std::string> errors)>;
 
     // Matches GenerateBidCallbackInternal, but with only one
@@ -480,6 +481,7 @@
         const absl::optional<GURL>& report_url,
         base::flat_map<std::string, GURL> ad_beacon_map,
         PrivateAggregationRequests pa_requests,
+        base::TimeDelta reporting_latency,
         std::vector<std::string> errors);
 
     void PostErrorBidCallbackToUserThread(
@@ -613,6 +615,7 @@
       absl::optional<GURL> report_url,
       base::flat_map<std::string, GURL> ad_beacon_map,
       PrivateAggregationRequests pa_requests,
+      base::TimeDelta reporting_latency,
       std::vector<std::string> errors);
 
   // Returns true if unpaused and the script and WASM helper (if needed) have
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc
index e7ab0ac..f82b6545 100644
--- a/content/services/auction_worklet/bidder_worklet_unittest.cc
+++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -515,12 +515,15 @@
 
   // Runs reportWin() on an already loaded worklet,  verifies the return
   // value and invokes `done_closure` when done. Expects something else to
-  // spin the event loop.
+  // spin the event loop. If `expected_reporting_latency_timeout` is true,
+  // the timeout will be (extremely loosely) compared against normal script
+  // timeout.
   void RunReportWinExpectingResultAsync(
       mojom::BidderWorklet* bidder_worklet,
       const absl::optional<GURL>& expected_report_url,
       const base::flat_map<std::string, GURL>& expected_ad_beacon_map,
       PrivateAggregationRequests expected_pa_requests,
+      bool expected_reporting_latency_timeout,
       const std::vector<std::string>& expected_errors,
       base::OnceClosure done_closure) {
     bidder_worklet->ReportWin(
@@ -540,21 +543,29 @@
             [](const absl::optional<GURL>& expected_report_url,
                const base::flat_map<std::string, GURL>& expected_ad_beacon_map,
                PrivateAggregationRequests expected_pa_requests,
+               bool expected_reporting_latency_timeout,
                const std::vector<std::string>& expected_errors,
                base::OnceClosure done_closure,
                const absl::optional<GURL>& report_url,
                const base::flat_map<std::string, GURL>& ad_beacon_map,
                PrivateAggregationRequests pa_requests,
+               base::TimeDelta reporting_latency,
                const std::vector<std::string>& errors) {
               EXPECT_EQ(expected_report_url, report_url);
               EXPECT_EQ(expected_errors, errors);
               EXPECT_EQ(expected_ad_beacon_map, ad_beacon_map);
               EXPECT_EQ(expected_pa_requests, pa_requests);
+              if (expected_reporting_latency_timeout) {
+                // We only know that about the time of the timeout should have
+                // elapsed, and there may also be some thread skew.
+                EXPECT_GE(reporting_latency,
+                          AuctionV8Helper::kScriptTimeout * 0.9);
+              }
               std::move(done_closure).Run();
             },
             expected_report_url, expected_ad_beacon_map,
-            std::move(expected_pa_requests), expected_errors,
-            std::move(done_closure)));
+            std::move(expected_pa_requests), expected_reporting_latency_timeout,
+            expected_errors, std::move(done_closure)));
   }
 
   // Loads and runs a reportWin() with the provided return line, expecting the
@@ -570,10 +581,11 @@
     ASSERT_TRUE(bidder_worklet);
 
     base::RunLoop run_loop;
-    RunReportWinExpectingResultAsync(bidder_worklet.get(), expected_report_url,
-                                     expected_ad_beacon_map,
-                                     std::move(expected_pa_requests),
-                                     expected_errors, run_loop.QuitClosure());
+    RunReportWinExpectingResultAsync(
+        bidder_worklet.get(), expected_report_url, expected_ad_beacon_map,
+        std::move(expected_pa_requests),
+        /*expected_reporting_latency_timeout=*/false, expected_errors,
+        run_loop.QuitClosure());
     run_loop.Run();
   }
 
@@ -3546,6 +3558,7 @@
           [&run_loop](const absl::optional<GURL>& report_url,
                       const base::flat_map<std::string, GURL>& ad_beacon_map,
                       PrivateAggregationRequests pa_requests,
+                      base::TimeDelta reporting_latency,
                       const std::vector<std::string>& errors) {
             run_loop.Quit();
           }));
@@ -3578,6 +3591,7 @@
       bidder_worklet.get(), GURL("https://foo.test"),
       /*expected_ad_beacon_map=*/{},
       /*expected_pa_requests=*/{},
+      /*expected_reporting_latency_timeout=*/false,
       /*expected_errors=*/{},
       base::BindLambdaForTesting([&run_loop]() { run_loop.Quit(); }));
   task_environment_.RunUntilIdle();
@@ -4809,6 +4823,7 @@
       base::BindOnce([](const absl::optional<GURL>& report_url,
                         const base::flat_map<std::string, GURL>& ad_beacon_map,
                         PrivateAggregationRequests pa_requests,
+                        base::TimeDelta reporting_latency,
                         const std::vector<std::string>& errors) {
         ADD_FAILURE() << "Callback should not be invoked since worklet deleted";
       }));
@@ -4861,6 +4876,7 @@
                   const absl::optional<GURL>& report_url,
                   const base::flat_map<std::string, GURL>& ad_beacon_map,
                   PrivateAggregationRequests pa_requests,
+                  base::TimeDelta reporting_latency,
                   const std::vector<std::string>& errors) {
                 EXPECT_EQ(GURL(base::StringPrintf("https://foo.test/%zu", i)),
                           report_url);
@@ -4910,6 +4926,7 @@
             [](const absl::optional<GURL>& report_url,
                const base::flat_map<std::string, GURL>& ad_beacon_map,
                PrivateAggregationRequests pa_requests,
+               base::TimeDelta reporting_latency,
                const std::vector<std::string>& errors) {
               ADD_FAILURE() << "Callback should not be invoked.";
             }));
@@ -5002,9 +5019,10 @@
     mojo::Remote<mojom::BidderWorklet> bidder_worklet = CreateWorklet();
     url_loader_factory_.ClearResponses();
     auto run_loop = std::make_unique<base::RunLoop>();
-    RunReportWinExpectingResultAsync(bidder_worklet.get(),
-                                     GURL("https://foo.test/"), {}, {}, {},
-                                     run_loop->QuitClosure());
+    RunReportWinExpectingResultAsync(
+        bidder_worklet.get(), GURL("https://foo.test/"), {}, {},
+        /*expected_reporting_latency_timeout=*/false, {},
+        run_loop->QuitClosure());
     for (size_t i = 0; i < std::size(kResponses); ++i) {
       SCOPED_TRACE(i);
       const Response& response =
@@ -5285,6 +5303,7 @@
             [&run_loop](const absl::optional<GURL>& report_url,
                         const base::flat_map<std::string, GURL>& ad_beacon_map,
                         PrivateAggregationRequests pa_requests,
+                        base::TimeDelta reporting_latency,
                         const std::vector<std::string>& errors) {
               EXPECT_EQ(GURL("https://23.test/"), report_url);
               EXPECT_TRUE(errors.empty());
@@ -5717,8 +5736,9 @@
 
   // Now ask for reporting. This should hit the other breakpoint.
   base::RunLoop run_loop;
-  RunReportWinExpectingResultAsync(worklet.get(), GURL("https://foo.test/"), {},
-                                   {}, {}, run_loop.QuitClosure());
+  RunReportWinExpectingResultAsync(
+      worklet.get(), GURL("https://foo.test/"), {}, {},
+      /*expected_reporting_latency_timeout=*/false, {}, run_loop.QuitClosure());
 
   TestDevToolsAgentClient::Event breakpoint_hit2 =
       debug.WaitForMethodNotification("Debugger.paused");
@@ -6044,6 +6064,7 @@
       base::BindOnce([](const absl::optional<GURL>& report_url,
                         const base::flat_map<std::string, GURL>& ad_beacon_map,
                         PrivateAggregationRequests pa_requests,
+                        base::TimeDelta reporting_latency,
                         const std::vector<std::string>& errors) {
         ADD_FAILURE() << "Callback should not be invoked.";
       }));
@@ -7719,14 +7740,14 @@
   EXPECT_THAT(bid_errors_, testing::ElementsAre());
 }
 
-class GenerateBidLatenciesTest : public BidderWorkletTest {
+class BidderWorkletLatenciesTest : public BidderWorkletTest {
  public:
   // We use MockTime to control the reported latencies.
-  GenerateBidLatenciesTest()
+  BidderWorkletLatenciesTest()
       : BidderWorkletTest(TaskEnvironment::TimeSource::MOCK_TIME) {}
 };
 
-TEST_F(GenerateBidLatenciesTest, GenerateBidLatenciesAreReturned) {
+TEST_F(BidderWorkletLatenciesTest, GenerateBidLatenciesAreReturned) {
   interest_group_trusted_bidding_signals_url_ =
       GURL("https://url.test/trustedsignals");
   interest_group_trusted_bidding_signals_keys_ = {"1"};
@@ -7788,6 +7809,27 @@
       *generate_bid_dependency_latencies_->trusted_bidding_signals_latency);
 }
 
+TEST_F(BidderWorkletTest, ReportWinLatency) {
+  // We use an infinite loop since we have some notion of how long a timeout
+  // should take.
+  AddJavascriptResponse(&url_loader_factory_, interest_group_bidding_url_,
+                        CreateReportWinScript("while (true) {}"));
+
+  mojo::Remote<mojom::BidderWorklet> bidder_worklet = CreateWorklet();
+
+  base::RunLoop run_loop;
+  RunReportWinExpectingResultAsync(
+      bidder_worklet.get(),
+      /*expected_report_url=*/absl::nullopt,
+      /*expected_ad_beacon_map=*/{},
+      /*expected_pa_requests=*/{},
+      /*expected_reporting_latency_timeout=*/true,
+      /*expected_errors=*/
+      {"https://url.test/ execution of `reportWin` timed out."},
+      run_loop.QuitClosure());
+  run_loop.Run();
+}
+
 // The sequence when GenerateBidClient gets destroyed w/o getting to
 // FinalizeGenerateBid() needs to do some extra cleaning up, so exercise it.
 TEST_F(BidderWorkletTest, CloseGenerateBidClientBeforeFinalize) {
diff --git a/content/services/auction_worklet/direct_from_seller_signals_requester.cc b/content/services/auction_worklet/direct_from_seller_signals_requester.cc
index b03c51d..221fdf1 100644
--- a/content/services/auction_worklet/direct_from_seller_signals_requester.cc
+++ b/content/services/auction_worklet/direct_from_seller_signals_requester.cc
@@ -35,28 +35,52 @@
 
 namespace {
 
-// Validates that the X-FLEDGE-Auction-Only header is present. Returns
-// absl::nullopt upon success. Upon failure, returns an error string.
+// Validates that the Ad-Auction-Only (or deprecated X-FLEDGE-Auction-Only)
+// header is present. Returns absl::nullopt upon success. Upon failure, returns
+// an error string.
 //
 // NOTE: This check is *NOT* directly part of the DirectFromSellerSignals
 // security model, and serves more as a convenience check for developers: the
 // network service and browser process ensure that resources that have the
-// "X-FLEDGE-Auction-Only: true" header are only usable in FLEDGE auctions. This
+// "Ad-Auction-Only: true" header are only usable in FLEDGE auctions. This
 // check reminds developers using DirectFromSellerSignals to use
-// X-FLEDGE-Auction-Only on subresource responses to ensure that these responses
+// Ad-Auction-Only on subresource responses to ensure that these responses
 // are protected (by the browser and network stack) from being using outside
 // FLEDGE.
 absl::optional<std::string> CheckHeader(
     scoped_refptr<net::HttpResponseHeaders> headers) {
-  std::string auction_only;
-  if (!headers->GetNormalizedHeader("X-FLEDGE-Auction-Only", &auction_only)) {
-    return "Missing X-FLEDGE-Auction-Only header.";
+  // TODO(crbug.com/1448564): Remove support for old header names once API users
+  // have switched.
+  std::string old_header_value;
+  std::string new_header_value;
+  // TODO(crbug.com/1448564): Remove old names once API users have migrated to
+  // new names.
+  const bool got_new_header =
+      headers->GetNormalizedHeader("Ad-Auction-Only", &new_header_value);
+  const bool got_old_header =
+      headers->GetNormalizedHeader("X-FLEDGE-Auction-Only", &old_header_value);
+  if (!got_new_header && !got_old_header) {
+    return "Missing Ad-Auction-Only (or deprecated X-FLEDGE-Auction-Only) "
+           "header.";
   }
-  if (!base::EqualsCaseInsensitiveASCII(auction_only, "true")) {
+  if (got_old_header) {
+    if (got_new_header) {
+      if (old_header_value != new_header_value) {
+        return base::StringPrintf(
+            "Ad-Auction-Only: %s does not match deprecated header "
+            "X-FLEDGE-Auction-Only: %s.",
+            new_header_value.c_str(), old_header_value.c_str());
+      }
+    } else {
+      new_header_value = std::move(old_header_value);
+    }
+  }
+  if (!base::EqualsCaseInsensitiveASCII(new_header_value, "true")) {
     return base::StringPrintf(
-        "Wrong X-FLEDGE-Auction-Only header value. Expected \"true\", found "
+        "Wrong Ad-Auction-Only (or deprecated X-FLEDGE-Auction-Only) header "
+        "value. Expected \"true\", found "
         "\"%s\".",
-        auction_only.c_str());
+        new_header_value.c_str());
   }
 
   return absl::nullopt;
diff --git a/content/services/auction_worklet/direct_from_seller_signals_requester_unittest.cc b/content/services/auction_worklet/direct_from_seller_signals_requester_unittest.cc
index db6ec383..cd5c8da 100644
--- a/content/services/auction_worklet/direct_from_seller_signals_requester_unittest.cc
+++ b/content/services/auction_worklet/direct_from_seller_signals_requester_unittest.cc
@@ -31,9 +31,21 @@
 constexpr char kRequiredHeaders[] =
     "X-Allow-FLEDGE: true\nX-FLEDGE-Auction-Only: true";
 
+constexpr char kRequiredHeadersNewName[] =
+    "X-Allow-FLEDGE: true\nAd-Auction-Only: true";
+
+constexpr char kRequiredHeadersBothNewAndOldNames[] =
+    "X-Allow-FLEDGE: true\nAd-Auction-Only: true\nX-FLEDGE-Auction-Only: true";
+
+constexpr char kRequiredHeadersBothNewAndOldNamesMismatch[] =
+    "X-Allow-FLEDGE: true\nAd-Auction-Only: true\nX-FLEDGE-Auction-Only: false";
+
 constexpr char kFalseAuctionOnly[] =
     "X-Allow-FLEDGE: true\nX-FLEDGE-Auction-Only: false";
 
+constexpr char kFalseAuctionOnlyNewName[] =
+    "X-Allow-FLEDGE: true\nAd-Auction-Only: false";
+
 // The signals URL and response are arbitrary, from the point of
 // DirectFromSellerSignalsRequester.
 constexpr char kSignalsUrl[] = "https://seller.com/signals?sellerSignals";
@@ -419,7 +431,38 @@
   AddResponse(&url_loader_factory_, GURL(kSignalsUrl), kJsonMimeType,
               kUtf8Charset, kSignalsResponse, kAllowFledgeHeader);
   Result result = LoadSignalsAndWait(requester, GURL(kSignalsUrl));
-  EXPECT_EQ("Missing X-FLEDGE-Auction-Only header.", ExtractSignals(result));
+  EXPECT_EQ(
+      "Missing Ad-Auction-Only (or deprecated X-FLEDGE-Auction-Only) header.",
+      ExtractSignals(result));
+}
+
+TEST_F(DirectFromSellerSignalsRequesterTest, NewHeaderName) {
+  DirectFromSellerSignalsRequester requester;
+  AddResponse(&url_loader_factory_, GURL(kSignalsUrl), kJsonMimeType,
+              kUtf8Charset, kSignalsResponse, kRequiredHeadersNewName);
+  Result result = LoadSignalsAndWait(requester, GURL(kSignalsUrl));
+  EXPECT_EQ(kSignalsResponse, ExtractSignals(result));
+}
+
+TEST_F(DirectFromSellerSignalsRequesterTest, BothNewAndOldHeaderNames) {
+  DirectFromSellerSignalsRequester requester;
+  AddResponse(&url_loader_factory_, GURL(kSignalsUrl), kJsonMimeType,
+              kUtf8Charset, kSignalsResponse,
+              kRequiredHeadersBothNewAndOldNames);
+  Result result = LoadSignalsAndWait(requester, GURL(kSignalsUrl));
+  EXPECT_EQ(kSignalsResponse, ExtractSignals(result));
+}
+
+TEST_F(DirectFromSellerSignalsRequesterTest, BothNewAndOldHeaderNamesMismatch) {
+  DirectFromSellerSignalsRequester requester;
+  AddResponse(&url_loader_factory_, GURL(kSignalsUrl), kJsonMimeType,
+              kUtf8Charset, kSignalsResponse,
+              kRequiredHeadersBothNewAndOldNamesMismatch);
+  Result result = LoadSignalsAndWait(requester, GURL(kSignalsUrl));
+  EXPECT_EQ(
+      "Ad-Auction-Only: true does not match deprecated header "
+      "X-FLEDGE-Auction-Only: false.",
+      ExtractSignals(result));
 }
 
 TEST_F(DirectFromSellerSignalsRequesterTest, BadAuctionOnly) {
@@ -428,7 +471,20 @@
               kUtf8Charset, kSignalsResponse, kFalseAuctionOnly);
   Result result = LoadSignalsAndWait(requester, GURL(kSignalsUrl));
   EXPECT_EQ(
-      "Wrong X-FLEDGE-Auction-Only header value. Expected \"true\", found "
+      "Wrong Ad-Auction-Only (or deprecated X-FLEDGE-Auction-Only) header "
+      "value. Expected \"true\", found "
+      "\"false\".",
+      ExtractSignals(result));
+}
+
+TEST_F(DirectFromSellerSignalsRequesterTest, BadAuctionOnlyNewName) {
+  DirectFromSellerSignalsRequester requester;
+  AddResponse(&url_loader_factory_, GURL(kSignalsUrl), kJsonMimeType,
+              kUtf8Charset, kSignalsResponse, kFalseAuctionOnlyNewName);
+  Result result = LoadSignalsAndWait(requester, GURL(kSignalsUrl));
+  EXPECT_EQ(
+      "Wrong Ad-Auction-Only (or deprecated X-FLEDGE-Auction-Only) header "
+      "value. Expected \"true\", found "
       "\"false\".",
       ExtractSignals(result));
 }
diff --git a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
index 595e3ad..424aa752 100644
--- a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
+++ b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
@@ -529,6 +529,9 @@
   //
   // `pa_requests` The various requests made to the Private Aggregation API.
   //
+  // `reporting_latency` How long it took to run the JavaScript for
+  // `reportWin()` (including the top-level).
+  //
   // `errors` is an array of any errors that occurred while attempting
   //  to run the worklet's reportWin() method. These are too sensitive for
   //  the renderer to see. There may be errors even when a `report_url` is
@@ -561,6 +564,7 @@
           url.mojom.Url? report_url,
           map<string, url.mojom.Url> ad_beacon_map,
           array<PrivateAggregationRequest> pa_requests,
+          mojo_base.mojom.TimeDelta reporting_latency,
           array<string> errors);
 
   // Establishes a debugger connection to the worklet.
diff --git a/content/services/auction_worklet/public/mojom/seller_worklet.mojom b/content/services/auction_worklet/public/mojom/seller_worklet.mojom
index cf074e2c..66d1cd0 100644
--- a/content/services/auction_worklet/public/mojom/seller_worklet.mojom
+++ b/content/services/auction_worklet/public/mojom/seller_worklet.mojom
@@ -97,6 +97,12 @@
   //
   // `pa_requests` The various requests made to the Private Aggregation API.
   //
+  // `scoring_latency` How long it took to execute the scoreAd() JavaScript,
+  //  (including the top-level).
+  //
+  // `trusted_signals_fetch_latency` How long it took to fetch the trusted
+  //  scoring signals, if any. 0 if there weren't any.
+  //
   // `errors` are various error messages to be used for debugging. These are too
   //  sensitive for the renderers to see. `errors` should not be assumed to be
   //  empty if `score` is positive, nor should it be assumed to be non-empty if
@@ -110,6 +116,8 @@
                     url.mojom.Url? debug_loss_report_url,
                     url.mojom.Url? debug_win_report_url,
                     array<PrivateAggregationRequest> pa_requests,
+                    mojo_base.mojom.TimeDelta scoring_latency,
+                    mojo_base.mojom.TimeDelta trusted_signals_fetch_latency,
                     array<string> errors);
 };
 
@@ -302,6 +310,9 @@
   //
   // `pa_requests` The various requests made to the Private Aggregation API.
   //
+  // `reporting_latency` How long it took to run `reportResult()` JS, including
+  //  the top-level.
+  //
   // `errors` are various error messages to be used for debugging. These are too
   //  sensitive for the renderers to see. `errors` should not be assumed to be
   //  empty if the other values are populated, nor should it be assumed to be
@@ -329,6 +340,7 @@
            url.mojom.Url? report_url,
            map<string, url.mojom.Url> ad_beacon_map,
            array<PrivateAggregationRequest> pa_requests,
+           mojo_base.mojom.TimeDelta reporting_latency,
            array<string> error_msgs);
 
   // Establishes a debugger connection to the worklet.
diff --git a/content/services/auction_worklet/seller_worklet.cc b/content/services/auction_worklet/seller_worklet.cc
index 452ab73a..75b5a15 100644
--- a/content/services/auction_worklet/seller_worklet.cc
+++ b/content/services/auction_worklet/seller_worklet.cc
@@ -22,6 +22,7 @@
 #include "base/task/bind_post_task.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
+#include "base/timer/elapsed_timer.h"
 #include "base/trace_event/trace_event.h"
 #include "content/services/auction_worklet/auction_v8_helper.h"
 #include "content/services/auction_worklet/context_recycler.h"
@@ -796,10 +797,11 @@
     uint32_t browser_signal_bidding_duration_msecs,
     const absl::optional<base::TimeDelta> seller_timeout,
     uint64_t trace_id,
+    base::TimeDelta trusted_signals_fetch_latency,
     base::ScopedClosureRunner cleanup_score_ad_task,
     ScoreAdCallbackInternal callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
-  base::TimeTicks start = base::TimeTicks::Now();
+  base::ElapsedTimer elapsed_timer;
 
   TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "post_v8_task", trace_id);
 
@@ -922,7 +924,10 @@
         /*scoring_signals_data_version=*/absl::nullopt,
         /*debug_loss_report_url=*/absl::nullopt,
         /*debug_win_report_url=*/absl::nullopt,
-        /*pa_requests=*/{}, std::move(errors_out));
+        /*pa_requests=*/{},
+        /*scoring_latency=*/elapsed_timer.Elapsed(),
+        /*trusted_signals_fetch_latency=*/trusted_signals_fetch_latency,
+        std::move(errors_out));
     return;
   }
   context_recycler.AddForDebuggingOnlyBindings();
@@ -945,8 +950,8 @@
           .ToLocal(&score_ad_result);
 
   TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "score_ad", trace_id);
-  base::UmaHistogramTimes("Ads.InterestGroup.Auction.ScoreAdTime",
-                          base::TimeTicks::Now() - start);
+  base::TimeDelta elapsed = elapsed_timer.Elapsed();
+  base::UmaHistogramTimes("Ads.InterestGroup.Auction.ScoreAdTime", elapsed);
 
   if (!success) {
     // Keep debug loss reports and Private Aggregation API requests since
@@ -962,6 +967,8 @@
         /*debug_win_report_url=*/absl::nullopt,
         context_recycler.private_aggregation_bindings()
             ->TakePrivateAggregationRequests(),
+        /*scoring_latency=*/elapsed,
+        /*trusted_signals_fetch_latency=*/trusted_signals_fetch_latency,
         std::move(errors_out));
     return;
   }
@@ -1190,6 +1197,8 @@
         context_recycler.for_debugging_only_bindings()->TakeWinReportUrl(),
         context_recycler.private_aggregation_bindings()
             ->TakePrivateAggregationRequests(),
+        /*scoring_latency=*/elapsed,
+        /*trusted_signals_fetch_latency=*/trusted_signals_fetch_latency,
         std::move(errors_out));
     return;
   }
@@ -1237,6 +1246,8 @@
       context_recycler.for_debugging_only_bindings()->TakeWinReportUrl(),
       context_recycler.private_aggregation_bindings()
           ->TakePrivateAggregationRequests(),
+      /*scoring_latency=*/elapsed,
+      /*trusted_signals_fetch_latency=*/trusted_signals_fetch_latency,
       std::move(errors_out));
 }
 
@@ -1265,6 +1276,7 @@
     ReportResultCallbackInternal callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
   TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "post_v8_task", trace_id);
+  base::ElapsedTimer elapsed_timer;
 
   AuctionV8Helper::FullIsolateScope isolate_scope(v8_helper_.get());
   v8::Isolate* isolate = v8_helper_->isolate();
@@ -1284,7 +1296,7 @@
                                          /*signals_for_winner=*/absl::nullopt,
                                          /*report_url=*/absl::nullopt,
                                          /*ad_beacon_map=*/{},
-                                         /*pa_requests=*/{},
+                                         /*pa_requests=*/{}, base::TimeDelta(),
                                          /*errors=*/std::vector<std::string>());
     return;
   }
@@ -1323,7 +1335,7 @@
                                          /*signals_for_winner=*/absl::nullopt,
                                          /*report_url=*/absl::nullopt,
                                          /*ad_beacon_map=*/{},
-                                         /*pa_requests=*/{},
+                                         /*pa_requests=*/{}, base::TimeDelta(),
                                          /*errors=*/std::vector<std::string>());
     return;
   }
@@ -1344,7 +1356,7 @@
           /*signals_for_winner=*/absl::nullopt,
           /*report_url=*/absl::nullopt,
           /*ad_beacon_map=*/{},
-          /*pa_requests=*/{},
+          /*pa_requests=*/{}, base::TimeDelta(),
           /*errors=*/std::vector<std::string>());
       return;
     }
@@ -1367,7 +1379,7 @@
                                          /*signals_for_winner=*/absl::nullopt,
                                          /*report_url=*/absl::nullopt,
                                          /*ad_beacon_map=*/{},
-                                         /*pa_requests=*/{},
+                                         /*pa_requests=*/{}, base::TimeDelta(),
                                          /*errors=*/errors_out);
     return;
   }
@@ -1389,7 +1401,7 @@
     PostReportResultCallbackToUserThread(
         std::move(callback), /*signals_for_winner=*/absl::nullopt,
         /*report_url=*/absl::nullopt, /*ad_beacon_map=*/{},
-        /*pa_requests=*/{}, std::move(errors_out));
+        /*pa_requests=*/{}, elapsed_timer.Elapsed(), std::move(errors_out));
     return;
   }
 
@@ -1424,7 +1436,7 @@
         /*report_url=*/absl::nullopt, /*ad_beacon_map=*/{},
         context_recycler.private_aggregation_bindings()
             ->TakePrivateAggregationRequests(),
-        std::move(errors_out));
+        elapsed_timer.Elapsed(), std::move(errors_out));
     return;
   }
 
@@ -1442,7 +1454,7 @@
       context_recycler.register_ad_beacon_bindings()->TakeAdBeaconMap(),
       context_recycler.private_aggregation_bindings()
           ->TakePrivateAggregationRequests(),
-      std::move(errors_out));
+      elapsed_timer.Elapsed(), std::move(errors_out));
 }
 
 void SellerWorklet::V8State::ConnectDevToolsAgent(
@@ -1491,7 +1503,8 @@
       /*scoring_signals_data_version=*/absl::nullopt,
       /*debug_loss_report_url=*/absl::nullopt,
       /*debug_win_report_url=*/absl::nullopt, std::move(pa_requests),
-      std::move(errors));
+      /*scoring_latency=*/base::TimeDelta(),
+      /*trusted_signals_fetch_latency=*/base::TimeDelta(), std::move(errors));
 }
 
 void SellerWorklet::V8State::PostScoreAdCallbackToUserThread(
@@ -1505,6 +1518,8 @@
     absl::optional<GURL> debug_loss_report_url,
     absl::optional<GURL> debug_win_report_url,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta scoring_latency,
+    base::TimeDelta trusted_signals_fetch_latency,
     std::vector<std::string> errors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
   user_thread_->PostTask(
@@ -1514,6 +1529,7 @@
                      bid_in_seller_currency, scoring_signals_data_version,
                      std::move(debug_loss_report_url),
                      std::move(debug_win_report_url), std::move(pa_requests),
+                     scoring_latency, trusted_signals_fetch_latency,
                      std::move(errors)));
 }
 
@@ -1523,13 +1539,15 @@
     absl::optional<GURL> report_url,
     base::flat_map<std::string, GURL> ad_beacon_map,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta reporting_latency,
     std::vector<std::string> errors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
   user_thread_->PostTask(
       FROM_HERE,
       base::BindOnce(std::move(callback), std::move(signals_for_winner),
                      std::move(report_url), std::move(ad_beacon_map),
-                     std::move(pa_requests), std::move(errors)));
+                     std::move(pa_requests), reporting_latency,
+                     std::move(errors)));
 }
 
 void SellerWorklet::ResumeIfPaused() {
@@ -1727,6 +1745,7 @@
           std::move(task->browser_signal_ad_components),
           task->browser_signal_bidding_duration_msecs,
           std::move(task->seller_timeout), task->trace_id,
+          task->wait_trusted_signals,
           base::ScopedClosureRunner(std::move(cleanup_score_ad_task)),
           base::BindOnce(&SellerWorklet::DeliverScoreAdCallbackOnUserThread,
                          weak_ptr_factory_.GetWeakPtr(), task)));
@@ -1743,6 +1762,8 @@
     absl::optional<GURL> debug_loss_report_url,
     absl::optional<GURL> debug_win_report_url,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta scoring_latency,
+    base::TimeDelta trusted_signals_fetch_latency,
     std::vector<std::string> errors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
   if (load_script_error_msg_)
@@ -1760,7 +1781,7 @@
       score, reject_reason, std::move(component_auction_modified_bid_params),
       std::move(bid_in_seller_currency), scoring_signals_data_version,
       debug_loss_report_url, debug_win_report_url, std::move(pa_requests),
-      std::move(errors));
+      scoring_latency, trusted_signals_fetch_latency, std::move(errors));
   score_ad_tasks_.erase(task);
 }
 
@@ -1856,6 +1877,7 @@
     const absl::optional<GURL> report_url,
     base::flat_map<std::string, GURL> ad_beacon_map,
     PrivateAggregationRequests pa_requests,
+    base::TimeDelta reporting_latency,
     std::vector<std::string> errors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
 
@@ -1864,7 +1886,7 @@
 
   std::move(task->callback)
       .Run(signals_for_winner, report_url, ad_beacon_map,
-           std::move(pa_requests), std::move(errors));
+           std::move(pa_requests), reporting_latency, std::move(errors));
   report_result_tasks_.erase(task);
 }
 
diff --git a/content/services/auction_worklet/seller_worklet.h b/content/services/auction_worklet/seller_worklet.h
index 59ba0e8..b1246444 100644
--- a/content/services/auction_worklet/seller_worklet.h
+++ b/content/services/auction_worklet/seller_worklet.h
@@ -267,12 +267,15 @@
         absl::optional<GURL> debug_loss_report_url,
         absl::optional<GURL> debug_win_report_url,
         PrivateAggregationRequests pa_requests,
+        base::TimeDelta scoring_latency,
+        base::TimeDelta trusted_signals_fetch_latency,
         std::vector<std::string> errors)>;
     using ReportResultCallbackInternal =
         base::OnceCallback<void(absl::optional<std::string> signals_for_winner,
                                 absl::optional<GURL> report_url,
                                 base::flat_map<std::string, GURL> ad_beacon_map,
                                 PrivateAggregationRequests pa_requests,
+                                base::TimeDelta reporting_latency,
                                 std::vector<std::string> errors)>;
 
     V8State(
@@ -308,6 +311,7 @@
         uint32_t browser_signal_bidding_duration_msecs,
         const absl::optional<base::TimeDelta> seller_timeout,
         uint64_t trace_id,
+        base::TimeDelta trusted_signals_fetch_latency,
         base::ScopedClosureRunner cleanup_score_ad_task,
         ScoreAdCallbackInternal callback);
 
@@ -364,6 +368,8 @@
         absl::optional<GURL> debug_loss_report_url,
         absl::optional<GURL> debug_win_report_url,
         PrivateAggregationRequests pa_requests,
+        base::TimeDelta scoring_latency,
+        base::TimeDelta trusted_signals_fetch_latency,
         std::vector<std::string> errors);
 
     void PostReportResultCallbackToUserThread(
@@ -372,6 +378,7 @@
         absl::optional<GURL> report_url,
         base::flat_map<std::string, GURL> ad_beacon_map,
         PrivateAggregationRequests pa_requests,
+        base::TimeDelta reporting_latency,
         std::vector<std::string> errors);
 
     static void PostResumeToUserThread(
@@ -445,6 +452,8 @@
       absl::optional<GURL> debug_loss_report_url,
       absl::optional<GURL> debug_win_report_url,
       PrivateAggregationRequests pa_requests,
+      base::TimeDelta scoring_latency,
+      base::TimeDelta trusted_signals_fetch_latency,
       std::vector<std::string> errors);
 
   // Removes `task` from `score_ad_tasks_` only. Used in case where the
@@ -474,6 +483,7 @@
       absl::optional<GURL> report_url,
       base::flat_map<std::string, GURL> ad_beacon_map,
       PrivateAggregationRequests pa_requests,
+      base::TimeDelta reporting_latency,
       std::vector<std::string> errors);
 
   // Returns true if unpaused and the script has loaded.
diff --git a/content/services/auction_worklet/seller_worklet_unittest.cc b/content/services/auction_worklet/seller_worklet_unittest.cc
index 3d26e2a..b54fae8 100644
--- a/content/services/auction_worklet/seller_worklet_unittest.cc
+++ b/content/services/auction_worklet/seller_worklet_unittest.cc
@@ -118,6 +118,8 @@
       const absl::optional<GURL>& debug_loss_report_url,
       const absl::optional<GURL>& debug_win_report_url,
       PrivateAggregationRequests pa_requests,
+      base::TimeDelta scoring_latency,
+      base::TimeDelta trusted_signals_fetch_latency,
       const std::vector<std::string>& errors)>;
 
   explicit TestScoreAdClient(ScoreAdCompleteCallback score_ad_complete_callback)
@@ -145,13 +147,16 @@
                          const absl::optional<GURL>& debug_loss_report_url,
                          const absl::optional<GURL>& debug_win_report_url,
                          PrivateAggregationRequests pa_requests,
+                         base::TimeDelta scoring_latency,
+                         base::TimeDelta trusted_signals_fetch_latency,
                          const std::vector<std::string>& errors) override {
     std::move(score_ad_complete_callback_)
         .Run(score, reject_reason,
              std::move(component_auction_modified_bid_params),
              std::move(bid_in_seller_currency),
              std::move(scoring_signals_data_version), debug_loss_report_url,
-             debug_win_report_url, std::move(pa_requests), errors);
+             debug_win_report_url, std::move(pa_requests), scoring_latency,
+             trusted_signals_fetch_latency, errors);
   }
 
   static ScoreAdCompleteCallback ScoreAdNeverInvokedCallback() {
@@ -164,6 +169,8 @@
            const absl::optional<GURL>& debug_loss_report_url,
            const absl::optional<GURL>& debug_win_report_url,
            PrivateAggregationRequests pa_requests,
+           base::TimeDelta scoring_latency,
+           base::TimeDelta trusted_signals_fetch_latency,
            const std::vector<std::string>& errors) {
           ADD_FAILURE() << "Callback should not be invoked";
         });
@@ -299,6 +306,8 @@
         expected_data_version, expected_debug_loss_report_url,
         expected_debug_win_report_url, expected_reject_reason,
         std::move(expected_pa_requests), expected_bid_in_seller_currency,
+        /*expected_score_ad_timeout=*/false,
+        /*expected_signals_fetch_latency=*/absl::nullopt,
         run_loop.QuitClosure());
     task_environment_.FastForwardBy(expected_duration - kTinyTime);
     EXPECT_FALSE(run_loop.AnyQuitCalled());
@@ -349,6 +358,8 @@
       mojom::RejectReason expected_reject_reason,
       PrivateAggregationRequests expected_pa_requests,
       absl::optional<double> expected_bid_in_seller_currency,
+      bool expected_score_ad_timeout,
+      absl::optional<base::TimeDelta> expected_signals_fetch_latency,
       base::OnceClosure done_closure) {
     seller_worklet->ScoreAd(
         ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
@@ -368,6 +379,8 @@
                const absl::optional<GURL>& expected_debug_win_report_url,
                PrivateAggregationRequests expected_pa_requests,
                absl::optional<double> expected_bid_in_seller_currency,
+               absl::optional<base::TimeDelta> expected_score_ad_timeout,
+               absl::optional<base::TimeDelta> expected_signals_fetch_latency,
                std::vector<std::string> expected_errors,
                base::OnceClosure done_closure, double score,
                mojom::RejectReason reject_reason,
@@ -378,6 +391,8 @@
                const absl::optional<GURL>& debug_loss_report_url,
                const absl::optional<GURL>& debug_win_report_url,
                PrivateAggregationRequests pa_requests,
+               base::TimeDelta scoring_latency,
+               base::TimeDelta trusted_signals_fetch_latency,
                const std::vector<std::string>& errors) {
               EXPECT_EQ(expected_score, score);
               EXPECT_EQ(static_cast<int>(expected_reject_reason),
@@ -403,6 +418,12 @@
               EXPECT_EQ(expected_bid_in_seller_currency,
                         bid_in_seller_currency);
               EXPECT_EQ(expected_pa_requests, pa_requests);
+              if (expected_score_ad_timeout) {
+                // We only know that about the time of the timeout should have
+                // elapsed, and there may also be some thread skew.
+                EXPECT_GE(scoring_latency,
+                          expected_score_ad_timeout.value() * 0.9);
+              }
               EXPECT_EQ(expected_errors, errors);
               std::move(done_closure).Run();
             },
@@ -410,7 +431,12 @@
             std::move(expected_component_auction_modified_bid_params),
             expected_data_version, expected_debug_loss_report_url,
             expected_debug_win_report_url, std::move(expected_pa_requests),
-            expected_bid_in_seller_currency, expected_errors,
+            expected_bid_in_seller_currency,
+            expected_score_ad_timeout
+                ? absl::make_optional(
+                      seller_timeout_.value_or(AuctionV8Helper::kScriptTimeout))
+                : absl::nullopt,
+            expected_signals_fetch_latency, expected_errors,
             std::move(done_closure))));
   }
 
@@ -452,6 +478,8 @@
         expected_data_version, expected_debug_loss_report_url,
         expected_debug_win_report_url, expected_reject_reason,
         std::move(expected_pa_requests), expected_bid_in_seller_currency,
+        /*expected_score_ad_timeout=*/false,
+        /*expected_signals_fetch_latency=*/absl::nullopt,
         run_loop.QuitClosure());
     run_loop.Run();
   }
@@ -532,6 +560,7 @@
       const absl::optional<GURL>& expected_report_url,
       const base::flat_map<std::string, GURL>& expected_ad_beacon_map,
       PrivateAggregationRequests expected_pa_requests,
+      bool expected_reporting_latency_timeout,
       const std::vector<std::string>& expected_errors,
       base::OnceClosure done_closure) {
     seller_worklet->ReportResult(
@@ -553,12 +582,14 @@
                const absl::optional<GURL>& expected_report_url,
                const base::flat_map<std::string, GURL>& expected_ad_beacon_map,
                PrivateAggregationRequests expected_pa_requests,
+               bool expected_reporting_latency_timeout,
                const std::vector<std::string>& expected_errors,
                base::OnceClosure done_closure,
                const absl::optional<std::string>& signals_for_winner,
                const absl::optional<GURL>& report_url,
                const base::flat_map<std::string, GURL>& ad_beacon_map,
                PrivateAggregationRequests pa_requests,
+               base::TimeDelta reporting_latency,
                const std::vector<std::string>& errors) {
               if (signals_for_winner && expected_signals_for_winner) {
                 // If neither is null, used fancy base::Value comparison, which
@@ -573,12 +604,19 @@
               EXPECT_EQ(expected_report_url, report_url);
               EXPECT_EQ(expected_ad_beacon_map, ad_beacon_map);
               EXPECT_EQ(expected_pa_requests, pa_requests);
+              if (expected_reporting_latency_timeout) {
+                // We only know that about the time of the timeout should have
+                // elapsed, and there may also be some thread skew.
+                EXPECT_GE(reporting_latency,
+                          AuctionV8Helper::kScriptTimeout * 0.9);
+              }
               EXPECT_EQ(expected_errors, errors);
               std::move(done_closure).Run();
             },
             expected_signals_for_winner, expected_report_url,
             expected_ad_beacon_map, std::move(expected_pa_requests),
-            expected_errors, std::move(done_closure)));
+            expected_reporting_latency_timeout, expected_errors,
+            std::move(done_closure)));
   }
 
   void RunReportResultExpectingCallbackNeverInvoked(
@@ -602,6 +640,7 @@
                const absl::optional<GURL>& report_url,
                const base::flat_map<std::string, GURL>& ad_beacon_map,
                PrivateAggregationRequests pa_requests,
+               base::TimeDelta reporting_latency,
                const std::vector<std::string>& errors) {
               ADD_FAILURE() << "This should not be invoked";
             }));
@@ -623,7 +662,8 @@
     RunReportResultExpectingResultAsync(
         seller_worklet.get(), expected_signals_for_winner, expected_report_url,
         expected_ad_beacon_map, std::move(expected_pa_requests),
-        expected_errors, run_loop.QuitClosure());
+        /*expected_reporting_latency_timeout=*/false, expected_errors,
+        run_loop.QuitClosure());
     run_loop.Run();
   }
 
@@ -1597,6 +1637,38 @@
       /*expected_data_version=*/5);
 }
 
+TEST_F(SellerWorkletTest, ScoreAdTrustedScoringSignalsLatency) {
+  const base::TimeDelta kDelay = base::Milliseconds(135);
+  trusted_scoring_signals_url_ =
+      GURL("https://url.test/trusted_scoring_signals");
+  // Trusted scoring signals URL without any component ads.
+  const GURL kNoComponentSignalsUrl = GURL(
+      "https://url.test/trusted_scoring_signals?hostname=window.test"
+      "&renderUrls=https%3A%2F%2Frender.url.test%2F");
+
+  AddJavascriptResponse(&url_loader_factory_, decision_logic_url_,
+                        CreateScoreAdScript(/*raw_return_value=*/"1", ""));
+  auto seller_worklet = CreateWorklet();
+  ASSERT_TRUE(seller_worklet);
+  base::RunLoop run_loop;
+  RunScoreAdOnWorkletAsync(
+      seller_worklet.get(), /*expected_score=*/1,
+      /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
+      /*expected_data_version=*/1,
+      /*expected_debug_loss_report_url=*/absl::nullopt,
+      /*expected_debug_win_report_url=*/absl::nullopt,
+      mojom::RejectReason::kNotAvailable,
+      /*expected_pa_requests=*/{},
+      /*expected_bid_in_seller_currency=*/absl::nullopt,
+      /*expected_score_ad_timeout=*/false,
+      /*expected_signals_fetch_latency=*/kDelay, run_loop.QuitClosure());
+  task_environment_.RunUntilIdle();
+  task_environment_.FastForwardBy(kDelay);
+  AddVersionedJsonResponse(&url_loader_factory_, kNoComponentSignalsUrl,
+                           kTrustedScoringSignalsResponse, /*data_version=*/1);
+  run_loop.Run();
+}
+
 TEST_F(SellerWorkletTest, ScoreAdDataVersion) {
   trusted_scoring_signals_url_ =
       GURL("https://url.test/trusted_scoring_signals");
@@ -1654,6 +1726,8 @@
                              mojom::RejectReason::kNotAvailable,
                              /*expected_pa_requests=*/{},
                              /*expected_bid_in_seller_currency=*/absl::nullopt,
+                             /*expected_score_ad_timeout=*/false,
+                             /*expected_signals_fetch_latency=*/absl::nullopt,
                              base::BindLambdaForTesting([&]() {
                                ++num_completed_worklets;
                                if (num_completed_worklets == kNumWorklets)
@@ -1699,6 +1773,8 @@
                              mojom::RejectReason::kNotAvailable,
                              /*expected_pa_requests=*/{},
                              /*expected_bid_in_seller_currency=*/absl::nullopt,
+                             /*expected_score_ad_timeout=*/false,
+                             /*expected_signals_fetch_latency=*/absl::nullopt,
                              base::BindLambdaForTesting([&]() {
                                ++num_completed_worklets;
                                if (num_completed_worklets == kNumWorklets)
@@ -1766,6 +1842,8 @@
                              mojom::RejectReason::kNotAvailable,
                              /*expected_pa_requests=*/{},
                              /*expected_bid_in_seller_currency=*/absl::nullopt,
+                             /*expected_score_ad_timeout=*/false,
+                             /*expected_signals_fetch_latency=*/absl::nullopt,
                              base::BindLambdaForTesting([&]() {
                                ++num_completed_worklets;
                                if (num_completed_worklets == kNumWorklets)
@@ -1836,6 +1914,8 @@
                              mojom::RejectReason::kNotAvailable,
                              /*expected_pa_requests=*/{},
                              /*expected_bid_in_seller_currency=*/absl::nullopt,
+                             /*expected_score_ad_timeout=*/false,
+                             /*expected_signals_fetch_latency=*/absl::nullopt,
                              base::BindLambdaForTesting([&]() {
                                ++num_completed_worklets;
                                if (num_completed_worklets == kNumWorklets)
@@ -1897,6 +1977,8 @@
                              mojom::RejectReason::kNotAvailable,
                              /*expected_pa_requests=*/{},
                              /*expected_bid_in_seller_currency=*/absl::nullopt,
+                             /*expected_score_ad_timeout=*/false,
+                             /*expected_signals_fetch_latency=*/absl::nullopt,
                              base::BindLambdaForTesting([&]() {
                                ++num_completed_worklets;
                                if (num_completed_worklets == kNumWorklets)
@@ -1967,6 +2049,8 @@
                              mojom::RejectReason::kNotAvailable,
                              /*expected_pa_requests=*/{},
                              /*expected_bid_in_seller_currency=*/absl::nullopt,
+                             /*expected_score_ad_timeout=*/false,
+                             /*expected_signals_fetch_latency=*/absl::nullopt,
                              base::BindLambdaForTesting([&]() {
                                ++num_completed_worklets;
                                if (num_completed_worklets == kNumWorklets)
@@ -2065,6 +2149,8 @@
                              mojom::RejectReason::kNotAvailable,
                              /*expected_pa_requests=*/{},
                              /*expected_bid_in_seller_currency=*/absl::nullopt,
+                             /*expected_score_ad_timeout=*/false,
+                             /*expected_signals_fetch_latency=*/absl::nullopt,
                              run_loop->QuitClosure());
     for (size_t i = 0; i < std::size(kResponses); ++i) {
       SCOPED_TRACE(i);
@@ -2165,6 +2251,8 @@
                            mojom::RejectReason::kNotAvailable,
                            /*expected_pa_requests=*/{},
                            /*expected_bid_in_seller_currency=*/absl::nullopt,
+                           /*expected_score_ad_timeout=*/false,
+                           /*expected_signals_fetch_latency=*/absl::nullopt,
                            run_loop->QuitClosure());
   run_loop->Run();
 
@@ -2179,6 +2267,8 @@
                            mojom::RejectReason::kNotAvailable,
                            /*expected_pa_requests=*/{},
                            /*expected_bid_in_seller_currency=*/absl::nullopt,
+                           /*expected_score_ad_timeout=*/false,
+                           /*expected_signals_fetch_latency=*/absl::nullopt,
                            run_loop->QuitClosure());
   run_loop->Run();
 }
@@ -2210,6 +2300,7 @@
           GURL("https://" + base::NumberToString(bid_)),
           /*expected_ad_beacon_map=*/{},
           /*expected_pa_requests=*/{},
+          /*expected_reporting_latency_timeout=*/false,
           /*expected_errors=*/{},
           base::BindLambdaForTesting([&run_loop, &num_report_result_calls]() {
             ++num_report_result_calls;
@@ -2997,6 +3088,7 @@
     RunReportResultExpectingResultAsync(
         seller_worklet.get(), "1", GURL("https://foo.test/"),
         /*expected_ad_beacon_map=*/{}, /*expected_pa_requests=*/{},
+        /*expected_reporting_latency_timeout=*/false,
         /*expected_errors=*/{}, run_loop->QuitClosure());
     for (size_t i = 0; i < std::size(kResponses); ++i) {
       SCOPED_TRACE(i);
@@ -3069,6 +3161,8 @@
                           const absl::optional<GURL>& debug_loss_report_url,
                           const absl::optional<GURL>& debug_win_report_url,
                           PrivateAggregationRequests pa_requests,
+                          base::TimeDelta scoring_latency,
+                          base::TimeDelta trusted_signals_fetch_latency,
                           const std::vector<std::string>& errors) {
                 EXPECT_EQ(2, score);
                 EXPECT_FALSE(scoring_signals_data_version.has_value());
@@ -3101,6 +3195,7 @@
                   const absl::optional<GURL>& report_url,
                   const base::flat_map<std::string, GURL>& ad_beacon_map,
                   PrivateAggregationRequests pa_requests,
+                  base::TimeDelta reporting_latency,
                   const std::vector<std::string>& errors) {
                 EXPECT_EQ("2", signals_for_winner);
                 EXPECT_TRUE(errors.empty());
@@ -3161,6 +3256,7 @@
                         const absl::optional<GURL>& report_url,
                         const base::flat_map<std::string, GURL>& ad_beacon_map,
                         PrivateAggregationRequests pa_requests,
+                        base::TimeDelta reporting_latency,
                         const std::vector<std::string>& errors) {
         ADD_FAILURE() << "Callback should not be invoked since worklet deleted";
       }));
@@ -3183,17 +3279,18 @@
   // Queue a ScoreAd() call, which should not happen immediately since loading
   // is paused.
   base::RunLoop run_loop;
-  RunScoreAdOnWorkletAsync(worklet.get(), /*expected_score=*/10,
-                           /*expected_errors=*/{},
-                           mojom::ComponentAuctionModifiedBidParamsPtr(),
-                           /*expected_data_version=*/absl::nullopt,
-                           /*expected_debug_loss_report_url=*/absl::nullopt,
-                           /*expected_debug_win_report_url=*/absl::nullopt,
-                           /*expected_reject_reason=*/
-                           mojom::RejectReason::kNotAvailable,
-                           /*expected_pa_requests=*/{},
-                           /*expected_bid_in_seller_currency=*/absl::nullopt,
-                           run_loop.QuitClosure());
+  RunScoreAdOnWorkletAsync(
+      worklet.get(), /*expected_score=*/10,
+      /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
+      /*expected_data_version=*/absl::nullopt,
+      /*expected_debug_loss_report_url=*/absl::nullopt,
+      /*expected_debug_win_report_url=*/absl::nullopt,
+      /*expected_reject_reason=*/
+      mojom::RejectReason::kNotAvailable,
+      /*expected_pa_requests=*/{},
+      /*expected_bid_in_seller_currency=*/absl::nullopt,
+      /*expected_score_ad_timeout=*/false,
+      /*expected_signals_fetch_latency=*/absl::nullopt, run_loop.QuitClosure());
 
   // Give it a chance to fetch.
   task_environment_.RunUntilIdle();
@@ -3279,6 +3376,8 @@
                            mojom::RejectReason::kNotAvailable,
                            /*expected_pa_requests=*/{},
                            /*expected_bid_in_seller_currency=*/absl::nullopt,
+                           /*expected_score_ad_timeout=*/false,
+                           /*expected_signals_fetch_latency=*/absl::nullopt,
                            run_loop1.QuitClosure());
 
   decision_logic_url_ = kUrl2;
@@ -3296,6 +3395,8 @@
                            mojom::RejectReason::kNotAvailable,
                            /*expected_pa_requests=*/{},
                            /*expected_bid_in_seller_currency=*/absl::nullopt,
+                           /*expected_score_ad_timeout=*/false,
+                           /*expected_signals_fetch_latency=*/absl::nullopt,
                            run_loop2.QuitClosure());
 
   int id1 = worklet_impl1->context_group_id_for_testing();
@@ -3420,6 +3521,8 @@
                            mojom::RejectReason::kNotAvailable,
                            /*expected_pa_requests=*/{},
                            /*expected_bid_in_seller_currency=*/absl::nullopt,
+                           /*expected_score_ad_timeout=*/false,
+                           /*expected_signals_fetch_latency=*/absl::nullopt,
                            run_loop1.QuitClosure());
 
   decision_logic_url_ = GURL(kUrl2);
@@ -3436,6 +3539,8 @@
                            mojom::RejectReason::kNotAvailable,
                            /*expected_pa_requests=*/{},
                            /*expected_bid_in_seller_currency=*/absl::nullopt,
+                           /*expected_score_ad_timeout=*/false,
+                           /*expected_signals_fetch_latency=*/absl::nullopt,
                            run_loop2.QuitClosure());
 
   mojo::AssociatedRemote<blink::mojom::DevToolsAgent> agent1, agent2;
@@ -3578,17 +3683,18 @@
   decision_logic_url_ = GURL(kUrl);
   auto worklet = CreateWorklet(/*pause_for_debugger_on_start=*/true);
   base::RunLoop run_loop;
-  RunScoreAdOnWorkletAsync(worklet.get(), /*expected_score=*/1.0,
-                           /*expected_errors=*/{},
-                           mojom::ComponentAuctionModifiedBidParamsPtr(),
-                           /*expected_data_version=*/absl::nullopt,
-                           /*expected_debug_loss_report_url=*/absl::nullopt,
-                           /*expected_debug_win_report_url=*/absl::nullopt,
-                           /*expected_reject_reason=*/
-                           mojom::RejectReason::kNotAvailable,
-                           /*expected_pa_requests=*/{},
-                           /*expected_bid_in_seller_currency=*/absl::nullopt,
-                           run_loop.QuitClosure());
+  RunScoreAdOnWorkletAsync(
+      worklet.get(), /*expected_score=*/1.0,
+      /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
+      /*expected_data_version=*/absl::nullopt,
+      /*expected_debug_loss_report_url=*/absl::nullopt,
+      /*expected_debug_win_report_url=*/absl::nullopt,
+      /*expected_reject_reason=*/
+      mojom::RejectReason::kNotAvailable,
+      /*expected_pa_requests=*/{},
+      /*expected_bid_in_seller_currency=*/absl::nullopt,
+      /*expected_score_ad_timeout=*/false,
+      /*expected_signals_fetch_latency=*/absl::nullopt, run_loop.QuitClosure());
 
   mojo::AssociatedRemote<blink::mojom::DevToolsAgent> agent;
   worklet->ConnectDevToolsAgent(agent.BindNewEndpointAndPassReceiver());
@@ -3642,6 +3748,7 @@
   RunReportResultExpectingResultAsync(
       worklet.get(), "1", GURL("https://foo.test/"),
       /*expected_ad_beacon_map=*/{}, /*expected_pa_requests=*/{},
+      /*expected_reporting_latency_timeout=*/false,
       /*expected_errors=*/{}, run_loop2.QuitClosure());
   TestDevToolsAgentClient::Event breakpoint_hit2 =
       debug.WaitForMethodNotification("Debugger.paused");
@@ -3670,6 +3777,8 @@
                            mojom::RejectReason::kNotAvailable,
                            /*expected_pa_requests=*/{},
                            /*expected_bid_in_seller_currency=*/absl::nullopt,
+                           /*expected_score_ad_timeout=*/false,
+                           /*expected_signals_fetch_latency=*/absl::nullopt,
                            run_loop3.QuitClosure());
 
   TestDevToolsAgentClient::Event breakpoint_hit3 =
@@ -3736,7 +3845,9 @@
       /*expected_reject_reason=*/
       mojom::RejectReason::kNotAvailable,
       /*expected_pa_requests=*/{},
-      /*expected_bid_in_seller_currency=*/absl::nullopt, base::BindOnce([]() {
+      /*expected_bid_in_seller_currency=*/absl::nullopt,
+      /*expected_score_ad_timeout=*/false,
+      /*expected_signals_fetch_latency=*/absl::nullopt, base::BindOnce([]() {
         ADD_FAILURE() << "scoreAd shouldn't actually get to finish.";
       }));
 
@@ -4089,9 +4200,26 @@
 // `scoreAd` should time out due to AuctionV8Helper's default script timeout (50
 // ms).
 TEST_F(SellerWorkletRealTimeTest, ScoreAdTimedOut) {
-  RunScoreAdWithJavascriptExpectingResult(
-      CreateScoreAdScript(/*raw_return_value=*/"", R"(while (1))"), 0,
-      {"https://url.test/ execution of `scoreAd` timed out."});
+  AddJavascriptResponse(
+      &url_loader_factory_, decision_logic_url_,
+      CreateScoreAdScript(/*raw_return_value=*/"", R"(while (1))"));
+  auto seller_worklet = CreateWorklet();
+  ASSERT_TRUE(seller_worklet);
+  base::RunLoop run_loop;
+  RunScoreAdOnWorkletAsync(
+      seller_worklet.get(), /*expected_score=*/0,
+      /*expected_errors=*/
+      {"https://url.test/ execution of `scoreAd` timed out."},
+      mojom::ComponentAuctionModifiedBidParamsPtr(),
+      /*expected_data_version=*/absl::nullopt,
+      /*expected_debug_loss_report_url=*/absl::nullopt,
+      /*expected_debug_win_report_url=*/absl::nullopt,
+      mojom::RejectReason::kNotAvailable,
+      /*expected_pa_requests=*/{},
+      /*expected_bid_in_seller_currency=*/absl::nullopt,
+      /*expected_score_ad_timeout=*/true,
+      /*expected_signals_fetch_latency=*/absl::nullopt, run_loop.QuitClosure());
+  run_loop.Run();
 }
 
 TEST_F(SellerWorkletRealTimeTest, ScoreAdSellerTimeoutFromAuctionConfig) {
@@ -4111,9 +4239,48 @@
   task_environment_.RunUntilIdle();
 
   seller_timeout_ = base::Milliseconds(20);
-  RunScoreAdWithJavascriptExpectingResult(
-      CreateScoreAdScript(/*raw_return_value=*/"", R"(while (1))"), 0,
-      {"https://url.test/ execution of `scoreAd` timed out."});
+  AddJavascriptResponse(
+      &url_loader_factory_, decision_logic_url_,
+      CreateScoreAdScript(/*raw_return_value=*/"", R"(while (1))"));
+  auto seller_worklet = CreateWorklet();
+  ASSERT_TRUE(seller_worklet);
+  base::RunLoop run_loop;
+  RunScoreAdOnWorkletAsync(
+      seller_worklet.get(), /*expected_score=*/0,
+      /*expected_errors=*/
+      {"https://url.test/ execution of `scoreAd` timed out."},
+      mojom::ComponentAuctionModifiedBidParamsPtr(),
+      /*expected_data_version=*/absl::nullopt,
+      /*expected_debug_loss_report_url=*/absl::nullopt,
+      /*expected_debug_win_report_url=*/absl::nullopt,
+      mojom::RejectReason::kNotAvailable,
+      /*expected_pa_requests=*/{},
+      /*expected_bid_in_seller_currency=*/absl::nullopt,
+      /*expected_score_ad_timeout=*/true,
+      /*expected_signals_fetch_latency=*/absl::nullopt, run_loop.QuitClosure());
+  run_loop.Run();
+}
+
+TEST_F(SellerWorkletRealTimeTest, ReportResultLatency) {
+  // We use an infinite loop since we have some notion of how long a timeout
+  // should take.
+  AddJavascriptResponse(&url_loader_factory_, decision_logic_url_,
+                        CreateReportToScript("1", "while (true) {}"));
+
+  mojo::Remote<mojom::SellerWorklet> seller_worklet = CreateWorklet();
+
+  base::RunLoop run_loop;
+  RunReportResultExpectingResultAsync(
+      seller_worklet.get(),
+      /*expected_signals_for_winner=*/absl::nullopt,
+      /*expected_report_url=*/absl::nullopt,
+      /*expected_ad_beacon_map=*/{},
+      /*expected_pa_requests=*/{},
+      /*expected_reporting_latency_timeout=*/true,
+      /*expected_errors=*/
+      {"https://url.test/ execution of `reportResult` timed out."},
+      run_loop.QuitClosure());
+  run_loop.Run();
 }
 
 class SellerWorkletBiddingAndScoringDebugReportingAPIEnabledTest
@@ -4374,6 +4541,8 @@
                         const absl::optional<GURL>& debug_loss_report_url,
                         const absl::optional<GURL>& debug_win_report_url,
                         PrivateAggregationRequests pa_requests,
+                        base::TimeDelta scoring_latency,
+                        base::TimeDelta trusted_signals_fetch_latency,
                         const std::vector<std::string>& errors) {
               if (score == 1) {
                 EXPECT_TRUE(debug_loss_report_url.has_value());
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 1e96da7..d50bb63 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -367,7 +367,10 @@
   }
 
   if (is_mac) {
-    deps += [ "//ui/display:test_support" ]
+    deps += [
+      "//base:base_arc",
+      "//ui/display:test_support",
+    ]
   }
 
   if (is_ios) {
diff --git a/content/shell/browser/shell_platform_delegate_mac.mm b/content/shell/browser/shell_platform_delegate_mac.mm
index df2594685..29faa9d 100644
--- a/content/shell/browser/shell_platform_delegate_mac.mm
+++ b/content/shell/browser/shell_platform_delegate_mac.mm
@@ -345,14 +345,15 @@
 
   // The event handling to get this strictly right is a tangle; cheat here a bit
   // by just letting the menus have a chance at it.
-  if (event.os_event.type == NSEventTypeKeyDown) {
-    if ((event.os_event.modifierFlags & NSEventModifierFlagCommand) &&
-        [event.os_event.characters isEqual:@"l"]) {
+  NSEvent* ns_event = event.os_event.Get();
+  if (ns_event.type == NSEventTypeKeyDown) {
+    if ((ns_event.modifierFlags & NSEventModifierFlagCommand) &&
+        [ns_event.characters isEqual:@"l"]) {
       [shell_data.delegate.window makeFirstResponder:shell_data.url_edit_view];
       return true;
     }
 
-    [NSApp.mainMenu performKeyEquivalent:event.os_event];
+    [NSApp.mainMenu performKeyEquivalent:ns_event];
     return true;
   }
   return false;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index c304b8d..eb3e2ac 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -2974,6 +2974,7 @@
 
   if (is_mac) {
     data_deps += [ "//device/fido/strings:fido_test_strings" ]
+    deps += [ "//base:base_arc" ]
   }
 
   if (is_posix) {
diff --git a/content/test/content_browser_test_utils_internal.cc b/content/test/content_browser_test_utils_internal.cc
index b36858b..b17c475c18 100644
--- a/content/test/content_browser_test_utils_internal.cc
+++ b/content/test/content_browser_test_utils_internal.cc
@@ -266,7 +266,7 @@
     std::vector<SiteInstance*> site_instances;
     for (const auto& proxy_pair :
          node->render_manager()->GetAllProxyHostsForTesting()) {
-      site_instances.push_back(proxy_pair.second->GetSiteInstance());
+      site_instances.push_back(proxy_pair.second->GetSiteInstanceDeprecated());
     }
     std::sort(site_instances.begin(), site_instances.end(),
               [](SiteInstance* lhs, SiteInstance* rhs) {
@@ -358,7 +358,7 @@
       std::vector<std::string> sorted_proxy_hosts;
       for (const auto& proxy_pair : proxy_host_map) {
         sorted_proxy_hosts.push_back(
-            GetName(proxy_pair.second->GetSiteInstance()));
+            GetName(proxy_pair.second->GetSiteInstanceDeprecated()));
       }
       std::sort(sorted_proxy_hosts.begin(), sorted_proxy_hosts.end());
       for (std::string& proxy_name : sorted_proxy_hosts) {
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist
index 777039e..01c30d2c 100644
--- a/content/test/content_test_bundle_data.filelist
+++ b/content/test/content_test_bundle_data.filelist
@@ -6045,6 +6045,18 @@
 data/interest_group/auction_only.json.mock-http-headers
 data/interest_group/auction_only.wbn
 data/interest_group/auction_only.wbn.mock-http-headers
+data/interest_group/auction_only_both_new_and_old_names.har
+data/interest_group/auction_only_both_new_and_old_names.html
+data/interest_group/auction_only_both_new_and_old_names.json
+data/interest_group/auction_only_both_new_and_old_names.json.mock-http-headers
+data/interest_group/auction_only_both_new_and_old_names.wbn
+data/interest_group/auction_only_both_new_and_old_names.wbn.mock-http-headers
+data/interest_group/auction_only_new_name.har
+data/interest_group/auction_only_new_name.html
+data/interest_group/auction_only_new_name.json
+data/interest_group/auction_only_new_name.json.mock-http-headers
+data/interest_group/auction_only_new_name.wbn
+data/interest_group/auction_only_new_name.wbn.mock-http-headers
 data/interest_group/bidding_argument_validator.js
 data/interest_group/bidding_argument_validator.js.mock-http-headers
 data/interest_group/bidding_logic.js
@@ -6556,6 +6568,7 @@
 data/service_worker/echo_request_headers.js.mock-http-headers
 data/service_worker/empty.html
 data/service_worker/empty.js
+data/service_worker/empty2.html
 data/service_worker/empty_fetch_event.js
 data/service_worker/empty_isolated.js
 data/service_worker/empty_isolated.js.mock-http-headers
diff --git a/content/test/data/gpu/webgl2_conformance_tests_output.json b/content/test/data/gpu/webgl2_conformance_tests_output.json
index 61859a7..452e10d 100644
--- a/content/test/data/gpu/webgl2_conformance_tests_output.json
+++ b/content/test/data/gpu/webgl2_conformance_tests_output.json
@@ -1,2795 +1,2848 @@
 {
   "times": {
-    "WebglExtension_EXT_color_buffer_float": 0.1446,
-    "WebglExtension_EXT_color_buffer_half_float": 0.339,
-    "WebglExtension_EXT_disjoint_timer_query_webgl2": 5.4755,
-    "WebglExtension_EXT_float_blend": 0.3712,
-    "WebglExtension_EXT_texture_compression_bptc": 0.4344,
-    "WebglExtension_EXT_texture_compression_rgtc": 0.1007,
-    "WebglExtension_EXT_texture_filter_anisotropic": 0.0623,
-    "WebglExtension_EXT_texture_norm16": 1.634,
-    "WebglExtension_KHR_parallel_shader_compile": 0.1973,
-    "WebglExtension_OES_draw_buffers_indexed": 0.3682,
-    "WebglExtension_OES_texture_float_linear": 0.2114,
-    "WebglExtension_OVR_multiview2": 0.0,
-    "WebglExtension_TestCoverage": 1.8417,
-    "WebglExtension_WEBGL_compressed_texture_astc": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_etc": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_etc1": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_pvrtc": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_s3tc": 0.2082,
-    "WebglExtension_WEBGL_compressed_texture_s3tc_srgb": 0.0,
-    "WebglExtension_WEBGL_debug_renderer_info": 0.0776,
-    "WebglExtension_WEBGL_debug_shaders": 6.2764,
-    "WebglExtension_WEBGL_draw_instanced_base_vertex_base_instance": 0.176,
-    "WebglExtension_WEBGL_lose_context": 0.0706,
-    "WebglExtension_WEBGL_multi_draw": 0.1945,
-    "WebglExtension_WEBGL_multi_draw_instanced_base_vertex_base_instance": 0.2916,
-    "WebglExtension_WEBGL_video_texture": 0.0669,
-    "conformance/attribs/gl-bindAttribLocation-aliasing.html": 0.4895,
-    "conformance/attribs/gl-bindAttribLocation-matrix.html": 0.3794,
-    "conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html": 0.4129,
-    "conformance/attribs/gl-bindAttribLocation-repeated.html": 0.3472,
-    "conformance/attribs/gl-disabled-vertex-attrib-update.html": 0.4586,
-    "conformance/attribs/gl-disabled-vertex-attrib.html": 0.995,
-    "conformance/attribs/gl-enable-vertex-attrib.html": 0.223,
-    "conformance/attribs/gl-matrix-attributes.html": 0.5769,
-    "conformance/attribs/gl-vertex-attrib-context-switch.html": 0.5057,
-    "conformance/attribs/gl-vertex-attrib-render.html": 0.2694,
-    "conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html": 0.3603,
-    "conformance/attribs/gl-vertex-attrib-zero-issues.html": 0.6158,
-    "conformance/attribs/gl-vertexattribpointer-offsets.html": 0.8643,
-    "conformance/attribs/gl-vertexattribpointer.html": 1.3879,
-    "conformance/buffers/buffer-bind-test.html": 0.2172,
-    "conformance/buffers/buffer-data-and-buffer-sub-data.html": 1.2211,
-    "conformance/buffers/buffer-data-array-buffer-delete.html": 2.4015,
-    "conformance/buffers/buffer-data-dynamic-delay.html": 0.7789,
-    "conformance/buffers/buffer-uninitialized.html": 1.0194,
-    "conformance/buffers/element-array-buffer-delete-recreate.html": 0.2787,
-    "conformance/buffers/index-validation-copies-indices.html": 0.2881,
-    "conformance/buffers/index-validation-crash-with-buffer-sub-data.html": 0.0851,
-    "conformance/buffers/index-validation-large-buffer.html": 0.3838,
-    "conformance/buffers/index-validation-verifies-too-many-indices.html": 0.1526,
-    "conformance/buffers/index-validation-with-resized-buffer.html": 0.297,
-    "conformance/buffers/index-validation.html": 0.191,
-    "conformance/buffers/vertex-buffer-updated-after-draw.html": 1.9063,
-    "conformance/canvas/buffer-offscreen-test.html": 0.3196,
-    "conformance/canvas/buffer-preserve-test.html": 0.2688,
-    "conformance/canvas/canvas-test.html": 0.4515,
-    "conformance/canvas/canvas-zero-size.html": 0.289,
-    "conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html": 0.9275,
-    "conformance/canvas/draw-webgl-to-canvas-test.html": 0.8584,
-    "conformance/canvas/drawingbuffer-hd-dpi-test.html": 0.8333,
-    "conformance/canvas/drawingbuffer-static-canvas-test.html": 0.5107,
-    "conformance/canvas/drawingbuffer-test.html": 0.1335,
-    "conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html": 0.4639,
-    "conformance/canvas/framebuffer-bindings-unaffected-on-resize.html": 0.2776,
-    "conformance/canvas/rapid-resizing.html": 2.605,
-    "conformance/canvas/render-after-resize-test.html": 0.2717,
-    "conformance/canvas/texture-bindings-unaffected-on-resize.html": 0.291,
-    "conformance/canvas/to-data-url-test.html": 0.6358,
-    "conformance/canvas/viewport-unchanged-upon-resize.html": 0.3316,
-    "conformance/canvas/webgl-to-2d-canvas.html": 0.5602,
-    "conformance/context/context-attribute-preserve-drawing-buffer.html": 0.6075,
-    "conformance/context/context-attributes-alpha-depth-stencil-antialias.html": 1.0126,
-    "conformance/context/context-creation-and-destruction.html": 1.5589,
-    "conformance/context/context-creation.html": 1.1439,
-    "conformance/context/context-eviction-with-garbage-collection.html": 1.6105,
-    "conformance/context/context-hidden-alpha.html": 0.2025,
-    "conformance/context/context-lost-restored.html": 0.288,
-    "conformance/context/context-lost.html": 1.0573,
-    "conformance/context/context-no-alpha-fbo-with-alpha.html": 0.2481,
-    "conformance/context/context-release-upon-reload.html": 1.7807,
-    "conformance/context/context-release-with-workers.html": 2.213,
-    "conformance/context/context-size-change.html": 0.1493,
-    "conformance/context/deleted-object-behavior.html": 0.6698,
-    "conformance/context/incorrect-context-object-behaviour.html": 0.4213,
-    "conformance/context/premultiplyalpha-test.html": 1.0625,
-    "conformance/context/user-defined-properties-on-context.html": 0.2104,
-    "conformance/context/zero-sized-canvas.html": 0.069,
-    "conformance/extensions/ext-color-buffer-half-float.html": 0.0,
-    "conformance/extensions/ext-disjoint-timer-query.html": 0.1016,
-    "conformance/extensions/ext-float-blend.html": 0.2848,
-    "conformance/extensions/ext-texture-compression-bptc.html": 0.315,
-    "conformance/extensions/ext-texture-compression-rgtc.html": 0.1444,
-    "conformance/extensions/ext-texture-filter-anisotropic.html": 0.1643,
-    "conformance/extensions/get-extension.html": 0.4339,
-    "conformance/extensions/oes-texture-float-linear.html": 0.4881,
-    "conformance/extensions/s3tc-and-rgtc.html": 4.6884,
-    "conformance/extensions/webgl-compressed-texture-astc.html": 0.227,
-    "conformance/extensions/webgl-compressed-texture-etc.html": 0.2149,
-    "conformance/extensions/webgl-compressed-texture-etc1.html": 0.1875,
-    "conformance/extensions/webgl-compressed-texture-pvrtc.html": 0.1104,
-    "conformance/extensions/webgl-compressed-texture-s3tc-srgb.html": 1.717,
-    "conformance/extensions/webgl-compressed-texture-size-limit.html": 5.9294,
-    "conformance/extensions/webgl-debug-renderer-info.html": 0.1108,
-    "conformance/extensions/webgl-debug-shaders.html": 0.2096,
-    "conformance/extensions/webgl-multi-draw.html": 1.611,
-    "conformance/glsl/bugs/angle-ambiguous-function-call.html": 0.2301,
-    "conformance/glsl/bugs/angle-constructor-invalid-parameters.html": 0.2836,
-    "conformance/glsl/bugs/angle-d3d11-compiler-error.html": 0.3521,
-    "conformance/glsl/bugs/angle-dx-variable-bug.html": 0.0745,
-    "conformance/glsl/bugs/array-of-struct-with-int-first-position.html": 0.312,
-    "conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html": 0.3659,
-    "conformance/glsl/bugs/bool-type-cast-bug-int-float.html": 3.0214,
-    "conformance/glsl/bugs/character-set.html": 0.3041,
-    "conformance/glsl/bugs/compare-loop-index-to-uniform.html": 0.1749,
-    "conformance/glsl/bugs/complex-glsl-does-not-crash.html": 3.041,
-    "conformance/glsl/bugs/compound-assignment-type-combination.html": 1.5136,
-    "conformance/glsl/bugs/conditional-discard-in-loop.html": 0.5011,
-    "conformance/glsl/bugs/conditional-discard-optimization.html": 0.2688,
-    "conformance/glsl/bugs/conditional-texture-fetch.html": 0.3407,
-    "conformance/glsl/bugs/constant-precision-qualifier.html": 0.5494,
-    "conformance/glsl/bugs/floor-div-cos-should-not-truncate.html": 0.5171,
-    "conformance/glsl/bugs/floored-division-accuracy.html": 0.5226,
-    "conformance/glsl/bugs/fragcoord-linking-bug.html": 0.0931,
-    "conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html": 0.644,
-    "conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html": 0.391,
-    "conformance/glsl/bugs/if-return-and-elseif.html": 0.1594,
-    "conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html": 0.2757,
-    "conformance/glsl/bugs/init-array-with-loop.html": 0.3403,
-    "conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html": 0.4131,
-    "conformance/glsl/bugs/logic-inside-block-without-braces.html": 0.3268,
-    "conformance/glsl/bugs/long-expressions-should-not-crash.html": 0.7808,
-    "conformance/glsl/bugs/loop-if-loop-gradient.html": 0.31,
-    "conformance/glsl/bugs/modulo-arithmetic-accuracy.html": 0.4432,
-    "conformance/glsl/bugs/multiplication-assignment.html": 0.1757,
-    "conformance/glsl/bugs/nested-functions-should-not-crash.html": 0.5921,
-    "conformance/glsl/bugs/nested-loops-with-break-and-continue.html": 0.5785,
-    "conformance/glsl/bugs/nested-sequence-operator.html": 0.4366,
-    "conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html": 0.5392,
-    "conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html": 0.3955,
-    "conformance/glsl/bugs/qualcomm-crash.html": 0.3475,
-    "conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html": 0.3541,
-    "conformance/glsl/bugs/sampler-array-struct-function-arg.html": 0.4902,
-    "conformance/glsl/bugs/sampler-array-using-loop-index.html": 0.3675,
-    "conformance/glsl/bugs/sampler-struct-function-arg.html": 0.4003,
-    "conformance/glsl/bugs/sequence-operator-evaluation-order.html": 0.341,
-    "conformance/glsl/bugs/sketchfab-lighting-shader-crash.html": 0.3448,
-    "conformance/glsl/bugs/struct-constructor-highp-bug.html": 0.4313,
-    "conformance/glsl/bugs/struct-with-single-member-constructor.html": 0.2464,
-    "conformance/glsl/bugs/temp-expressions-should-not-crash.html": 1.4905,
-    "conformance/glsl/bugs/unary-minus-operator-float-bug.html": 0.5167,
-    "conformance/glsl/bugs/undefined-index-should-not-crash.html": 0.3446,
-    "conformance/glsl/bugs/uniforms-should-not-lose-values.html": 0.4116,
-    "conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html": 0.4057,
-    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html": 0.3038,
-    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html": 0.4566,
-    "conformance/glsl/constructors/glsl-construct-bvec2.html": 1.1621,
-    "conformance/glsl/constructors/glsl-construct-bvec3.html": 1.1095,
-    "conformance/glsl/constructors/glsl-construct-bvec4.html": 1.1536,
-    "conformance/glsl/constructors/glsl-construct-ivec2.html": 0.8524,
-    "conformance/glsl/constructors/glsl-construct-ivec3.html": 0.9845,
-    "conformance/glsl/constructors/glsl-construct-ivec4.html": 1.3377,
-    "conformance/glsl/constructors/glsl-construct-mat2.html": 0.8593,
-    "conformance/glsl/constructors/glsl-construct-mat3.html": 0.9434,
-    "conformance/glsl/constructors/glsl-construct-mat4.html": 0.824,
-    "conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html": 0.4875,
-    "conformance/glsl/constructors/glsl-construct-vec-mat-index.html": 0.3762,
-    "conformance/glsl/constructors/glsl-construct-vec2.html": 0.7901,
-    "conformance/glsl/constructors/glsl-construct-vec3.html": 1.3774,
-    "conformance/glsl/constructors/glsl-construct-vec4.html": 1.3519,
-    "conformance/glsl/functions/glsl-function-abs.html": 0.8284,
-    "conformance/glsl/functions/glsl-function-acos.html": 0.8312,
-    "conformance/glsl/functions/glsl-function-asin.html": 0.865,
-    "conformance/glsl/functions/glsl-function-atan-xy.html": 1.0475,
-    "conformance/glsl/functions/glsl-function-atan.html": 1.0772,
-    "conformance/glsl/functions/glsl-function-ceil.html": 0.7161,
-    "conformance/glsl/functions/glsl-function-clamp-float.html": 0.8463,
-    "conformance/glsl/functions/glsl-function-clamp-gentype.html": 0.9166,
-    "conformance/glsl/functions/glsl-function-cos.html": 1.0381,
-    "conformance/glsl/functions/glsl-function-cross.html": 0.5805,
-    "conformance/glsl/functions/glsl-function-distance.html": 0.9042,
-    "conformance/glsl/functions/glsl-function-dot.html": 0.8602,
-    "conformance/glsl/functions/glsl-function-faceforward.html": 1.1866,
-    "conformance/glsl/functions/glsl-function-floor.html": 0.9898,
-    "conformance/glsl/functions/glsl-function-fract.html": 0.8808,
-    "conformance/glsl/functions/glsl-function-length.html": 0.8301,
-    "conformance/glsl/functions/glsl-function-max-float.html": 0.8771,
-    "conformance/glsl/functions/glsl-function-max-gentype.html": 1.057,
-    "conformance/glsl/functions/glsl-function-min-float.html": 0.8541,
-    "conformance/glsl/functions/glsl-function-min-gentype.html": 0.7176,
-    "conformance/glsl/functions/glsl-function-mix-float.html": 0.9797,
-    "conformance/glsl/functions/glsl-function-mix-gentype.html": 0.751,
-    "conformance/glsl/functions/glsl-function-mod-float.html": 0.7948,
-    "conformance/glsl/functions/glsl-function-mod-gentype.html": 0.6914,
-    "conformance/glsl/functions/glsl-function-normalize.html": 0.7828,
-    "conformance/glsl/functions/glsl-function-reflect.html": 0.8241,
-    "conformance/glsl/functions/glsl-function-sign.html": 0.7659,
-    "conformance/glsl/functions/glsl-function-sin.html": 0.831,
-    "conformance/glsl/functions/glsl-function-smoothstep-float.html": 0.8082,
-    "conformance/glsl/functions/glsl-function-smoothstep-gentype.html": 0.8956,
-    "conformance/glsl/functions/glsl-function-step-float.html": 0.8082,
-    "conformance/glsl/functions/glsl-function-step-gentype.html": 0.7362,
-    "conformance/glsl/functions/glsl-function.html": 0.8774,
-    "conformance/glsl/implicit/add_int_float.vert.html": 0.4669,
-    "conformance/glsl/implicit/add_int_mat2.vert.html": 0.3664,
-    "conformance/glsl/implicit/add_int_mat3.vert.html": 0.4483,
-    "conformance/glsl/implicit/add_int_mat4.vert.html": 0.439,
-    "conformance/glsl/implicit/add_int_vec2.vert.html": 0.4223,
-    "conformance/glsl/implicit/add_int_vec3.vert.html": 0.4367,
-    "conformance/glsl/implicit/add_int_vec4.vert.html": 0.4457,
-    "conformance/glsl/implicit/add_ivec2_vec2.vert.html": 0.4617,
-    "conformance/glsl/implicit/add_ivec3_vec3.vert.html": 0.4304,
-    "conformance/glsl/implicit/add_ivec4_vec4.vert.html": 0.2706,
-    "conformance/glsl/implicit/assign_int_to_float.vert.html": 0.4795,
-    "conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html": 0.2609,
-    "conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html": 0.0958,
-    "conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html": 0.441,
-    "conformance/glsl/implicit/construct_struct.vert.html": 0.3721,
-    "conformance/glsl/implicit/divide_int_float.vert.html": 0.4406,
-    "conformance/glsl/implicit/divide_int_mat2.vert.html": 0.459,
-    "conformance/glsl/implicit/divide_int_mat3.vert.html": 0.4584,
-    "conformance/glsl/implicit/divide_int_mat4.vert.html": 0.2481,
-    "conformance/glsl/implicit/divide_int_vec2.vert.html": 0.4643,
-    "conformance/glsl/implicit/divide_int_vec3.vert.html": 0.3318,
-    "conformance/glsl/implicit/divide_int_vec4.vert.html": 0.2886,
-    "conformance/glsl/implicit/divide_ivec2_vec2.vert.html": 0.198,
-    "conformance/glsl/implicit/divide_ivec3_vec3.vert.html": 0.2115,
-    "conformance/glsl/implicit/divide_ivec4_vec4.vert.html": 0.2602,
-    "conformance/glsl/implicit/equal_int_float.vert.html": 0.4401,
-    "conformance/glsl/implicit/equal_ivec2_vec2.vert.html": 0.28,
-    "conformance/glsl/implicit/equal_ivec3_vec3.vert.html": 0.4677,
-    "conformance/glsl/implicit/equal_ivec4_vec4.vert.html": 0.1936,
-    "conformance/glsl/implicit/function_int_float.vert.html": 0.1064,
-    "conformance/glsl/implicit/function_ivec2_vec2.vert.html": 0.1103,
-    "conformance/glsl/implicit/function_ivec3_vec3.vert.html": 0.2541,
-    "conformance/glsl/implicit/function_ivec4_vec4.vert.html": 0.1767,
-    "conformance/glsl/implicit/greater_than.vert.html": 0.2212,
-    "conformance/glsl/implicit/greater_than_equal.vert.html": 0.192,
-    "conformance/glsl/implicit/less_than.vert.html": 0.2212,
-    "conformance/glsl/implicit/less_than_equal.vert.html": 0.1708,
-    "conformance/glsl/implicit/multiply_int_float.vert.html": 0.1796,
-    "conformance/glsl/implicit/multiply_int_mat2.vert.html": 0.1052,
-    "conformance/glsl/implicit/multiply_int_mat3.vert.html": 0.2136,
-    "conformance/glsl/implicit/multiply_int_mat4.vert.html": 0.2222,
-    "conformance/glsl/implicit/multiply_int_vec2.vert.html": 0.4773,
-    "conformance/glsl/implicit/multiply_int_vec3.vert.html": 0.1356,
-    "conformance/glsl/implicit/multiply_int_vec4.vert.html": 0.4785,
-    "conformance/glsl/implicit/multiply_ivec2_vec2.vert.html": 0.2363,
-    "conformance/glsl/implicit/multiply_ivec3_vec3.vert.html": 0.1335,
-    "conformance/glsl/implicit/multiply_ivec4_vec4.vert.html": 0.1903,
-    "conformance/glsl/implicit/not_equal_int_float.vert.html": 0.1752,
-    "conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html": 0.2073,
-    "conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html": 0.1577,
-    "conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html": 0.1997,
-    "conformance/glsl/implicit/subtract_int_float.vert.html": 0.1245,
-    "conformance/glsl/implicit/subtract_int_mat2.vert.html": 0.1228,
-    "conformance/glsl/implicit/subtract_int_mat3.vert.html": 0.2576,
-    "conformance/glsl/implicit/subtract_int_mat4.vert.html": 0.2012,
-    "conformance/glsl/implicit/subtract_int_vec2.vert.html": 0.1392,
-    "conformance/glsl/implicit/subtract_int_vec3.vert.html": 0.1209,
-    "conformance/glsl/implicit/subtract_int_vec4.vert.html": 0.1254,
-    "conformance/glsl/implicit/subtract_ivec2_vec2.vert.html": 0.1105,
-    "conformance/glsl/implicit/subtract_ivec3_vec3.vert.html": 0.1897,
-    "conformance/glsl/implicit/subtract_ivec4_vec4.vert.html": 0.113,
-    "conformance/glsl/implicit/ternary_int_float.vert.html": 0.1375,
-    "conformance/glsl/implicit/ternary_ivec2_vec2.vert.html": 0.2385,
-    "conformance/glsl/implicit/ternary_ivec3_vec3.vert.html": 0.1474,
-    "conformance/glsl/implicit/ternary_ivec4_vec4.vert.html": 0.2302,
-    "conformance/glsl/literals/float_literal.vert.html": 0.0948,
-    "conformance/glsl/literals/literal_precision.html": 0.1684,
-    "conformance/glsl/literals/overflow_leak.vert.html": 0.1469,
-    "conformance/glsl/matrices/glsl-mat3-construction.html": 0.2523,
-    "conformance/glsl/matrices/glsl-mat4-to-mat3.html": 0.3233,
-    "conformance/glsl/matrices/matrix-compound-multiply.html": 0.3388,
-    "conformance/glsl/misc/boolean_precision.html": 0.1941,
-    "conformance/glsl/misc/const-variable-initialization.html": 1.5408,
-    "conformance/glsl/misc/embedded-struct-definitions-forbidden.html": 0.3347,
-    "conformance/glsl/misc/empty-declaration.html": 0.237,
-    "conformance/glsl/misc/empty_main.vert.html": 0.2195,
-    "conformance/glsl/misc/expression-list-in-declarator-initializer.html": 0.5647,
-    "conformance/glsl/misc/fragcolor-fragdata-invariant.html": 0.4964,
-    "conformance/glsl/misc/gl_position_unset.vert.html": 0.1935,
-    "conformance/glsl/misc/global-variable-init.html": 0.523,
-    "conformance/glsl/misc/glsl-function-nodes.html": 0.4583,
-    "conformance/glsl/misc/glsl-long-variable-names.html": 0.1952,
-    "conformance/glsl/misc/glsl-vertex-branch.html": 0.5753,
-    "conformance/glsl/misc/large-loop-compile.html": 0.6931,
-    "conformance/glsl/misc/local-variable-shadowing-outer-function.html": 0.3474,
-    "conformance/glsl/misc/non-ascii-comments.vert.html": 0.4314,
-    "conformance/glsl/misc/non-ascii.vert.html": 0.3597,
-    "conformance/glsl/misc/re-compile-re-link.html": 0.3326,
-    "conformance/glsl/misc/sampler-operand.html": 0.2456,
-    "conformance/glsl/misc/sequence-operator-returns-constant.html": 0.1999,
-    "conformance/glsl/misc/shader-precision-format-obeyed.html": 0.3936,
-    "conformance/glsl/misc/shader-struct-scope.html": 0.2901,
-    "conformance/glsl/misc/shader-uniform-packing-restrictions.html": 3.7248,
-    "conformance/glsl/misc/shader-varying-packing-restrictions.html": 0.8898,
-    "conformance/glsl/misc/shader-with-256-character-define.html": 0.2663,
-    "conformance/glsl/misc/shader-with-256-character-identifier.frag.html": 0.5193,
-    "conformance/glsl/misc/shader-with-_webgl-identifier.vert.html": 0.3245,
-    "conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html": 0.4265,
-    "conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html": 0.2754,
-    "conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html": 0.3348,
-    "conformance/glsl/misc/shader-with-array-of-structs-uniform.html": 0.3434,
-    "conformance/glsl/misc/shader-with-attrib-array.vert.html": 0.1666,
-    "conformance/glsl/misc/shader-with-attrib-struct.vert.html": 0.2106,
-    "conformance/glsl/misc/shader-with-clipvertex.vert.html": 0.3668,
-    "conformance/glsl/misc/shader-with-comma-assignment.html": 0.1207,
-    "conformance/glsl/misc/shader-with-comma-conditional-assignment.html": 0.4367,
-    "conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html": 0.3736,
-    "conformance/glsl/misc/shader-with-conditional-scoping-negative.html": 0.3607,
-    "conformance/glsl/misc/shader-with-conditional-scoping.html": 0.2103,
-    "conformance/glsl/misc/shader-with-default-precision.frag.html": 0.4185,
-    "conformance/glsl/misc/shader-with-default-precision.vert.html": 0.3749,
-    "conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html": 0.3656,
-    "conformance/glsl/misc/shader-with-dfdx.frag.html": 0.4711,
-    "conformance/glsl/misc/shader-with-do-loop.html": 0.2024,
-    "conformance/glsl/misc/shader-with-error-directive.html": 0.4718,
-    "conformance/glsl/misc/shader-with-explicit-int-cast.vert.html": 0.3355,
-    "conformance/glsl/misc/shader-with-float-return-value.frag.html": 0.3475,
-    "conformance/glsl/misc/shader-with-for-loop.html": 0.488,
-    "conformance/glsl/misc/shader-with-for-scoping.html": 0.2942,
-    "conformance/glsl/misc/shader-with-frag-depth.frag.html": 0.2329,
-    "conformance/glsl/misc/shader-with-function-recursion.frag.html": 0.1895,
-    "conformance/glsl/misc/shader-with-function-scoped-struct.html": 0.1785,
-    "conformance/glsl/misc/shader-with-functional-scoping.html": 0.4807,
-    "conformance/glsl/misc/shader-with-glcolor.vert.html": 0.4859,
-    "conformance/glsl/misc/shader-with-gles-1.frag.html": 0.1646,
-    "conformance/glsl/misc/shader-with-gles-symbol.frag.html": 0.3333,
-    "conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html": 0.1884,
-    "conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html": 0.4312,
-    "conformance/glsl/misc/shader-with-hex-int-constant-macro.html": 0.1978,
-    "conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html": 0.231,
-    "conformance/glsl/misc/shader-with-include.vert.html": 0.2379,
-    "conformance/glsl/misc/shader-with-int-return-value.frag.html": 0.4418,
-    "conformance/glsl/misc/shader-with-invalid-identifier.frag.html": 0.0904,
-    "conformance/glsl/misc/shader-with-ivec2-return-value.frag.html": 0.1299,
-    "conformance/glsl/misc/shader-with-ivec3-return-value.frag.html": 0.2529,
-    "conformance/glsl/misc/shader-with-ivec4-return-value.frag.html": 0.1261,
-    "conformance/glsl/misc/shader-with-limited-indexing.frag.html": 0.207,
-    "conformance/glsl/misc/shader-with-long-line.html": 0.5647,
-    "conformance/glsl/misc/shader-with-non-ascii-error.frag.html": 0.2984,
-    "conformance/glsl/misc/shader-with-non-reserved-words.html": 24.5731,
-    "conformance/glsl/misc/shader-with-precision.frag.html": 0.4102,
-    "conformance/glsl/misc/shader-with-preprocessor-whitespace.html": 0.3581,
-    "conformance/glsl/misc/shader-with-quoted-error.frag.html": 0.1949,
-    "conformance/glsl/misc/shader-with-reserved-words.html": 3.5616,
-    "conformance/glsl/misc/shader-with-short-circuiting-operators.html": 0.7058,
-    "conformance/glsl/misc/shader-with-similar-uniform-array-names.html": 0.5579,
-    "conformance/glsl/misc/shader-with-too-many-uniforms.html": 0.7147,
-    "conformance/glsl/misc/shader-with-two-initializer-types.html": 0.0933,
-    "conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html": 0.0994,
-    "conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html": 0.1855,
-    "conformance/glsl/misc/shader-with-vec2-return-value.frag.html": 0.1923,
-    "conformance/glsl/misc/shader-with-vec3-return-value.frag.html": 0.2326,
-    "conformance/glsl/misc/shader-with-vec4-return-value.frag.html": 0.2824,
-    "conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html": 0.1068,
-    "conformance/glsl/misc/shader-with-version-100.frag.html": 0.3557,
-    "conformance/glsl/misc/shader-with-version-100.vert.html": 0.3608,
-    "conformance/glsl/misc/shader-with-version-120.vert.html": 0.3765,
-    "conformance/glsl/misc/shader-with-version-130.vert.html": 0.2631,
-    "conformance/glsl/misc/shader-with-webgl-identifier.vert.html": 0.354,
-    "conformance/glsl/misc/shader-with-while-loop.html": 0.4428,
-    "conformance/glsl/misc/shader-without-precision.frag.html": 0.2672,
-    "conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html": 0.5665,
-    "conformance/glsl/misc/shaders-with-invariance.html": 0.5648,
-    "conformance/glsl/misc/shaders-with-mis-matching-uniforms.html": 0.6591,
-    "conformance/glsl/misc/shaders-with-mis-matching-varyings.html": 0.2648,
-    "conformance/glsl/misc/shaders-with-missing-varyings.html": 0.5394,
-    "conformance/glsl/misc/shaders-with-name-conflicts.html": 0.2408,
-    "conformance/glsl/misc/shaders-with-uniform-structs.html": 0.3083,
-    "conformance/glsl/misc/shaders-with-varyings.html": 0.2468,
-    "conformance/glsl/misc/shared.html": 0.2872,
-    "conformance/glsl/misc/struct-as-inout-parameter.html": 0.5966,
-    "conformance/glsl/misc/struct-as-out-parameter.html": 0.4828,
-    "conformance/glsl/misc/struct-assign.html": 0.3487,
-    "conformance/glsl/misc/struct-equals.html": 0.4301,
-    "conformance/glsl/misc/struct-mixed-array-declarators.html": 0.7232,
-    "conformance/glsl/misc/struct-nesting-exceeds-maximum.html": 0.5163,
-    "conformance/glsl/misc/struct-nesting-of-variable-names.html": 1.5487,
-    "conformance/glsl/misc/struct-nesting-under-maximum.html": 0.3882,
-    "conformance/glsl/misc/struct-specifiers-in-uniforms.html": 0.3926,
-    "conformance/glsl/misc/struct-unary-operators.html": 0.6256,
-    "conformance/glsl/misc/ternary-operator-on-arrays.html": 0.0924,
-    "conformance/glsl/misc/ternary-operators-in-global-initializers.html": 0.5131,
-    "conformance/glsl/misc/ternary-operators-in-initializers.html": 0.4914,
-    "conformance/glsl/misc/uninitialized-local-global-variables.html": 0.4744,
-    "conformance/glsl/preprocessor/comments.html": 0.4767,
-    "conformance/glsl/preprocessor/macro-expansion-tricky.html": 0.3929,
-    "conformance/glsl/reserved/_webgl_field.vert.html": 0.3942,
-    "conformance/glsl/reserved/_webgl_function.vert.html": 0.4717,
-    "conformance/glsl/reserved/_webgl_struct.vert.html": 0.4779,
-    "conformance/glsl/reserved/_webgl_variable.vert.html": 0.3865,
-    "conformance/glsl/reserved/webgl_field.vert.html": 0.2591,
-    "conformance/glsl/reserved/webgl_function.vert.html": 0.4175,
-    "conformance/glsl/reserved/webgl_struct.vert.html": 0.1721,
-    "conformance/glsl/reserved/webgl_variable.vert.html": 0.373,
-    "conformance/glsl/samplers/glsl-function-texture2d-bias.html": 0.532,
-    "conformance/glsl/samplers/glsl-function-texture2dlod.html": 0.4188,
-    "conformance/glsl/samplers/glsl-function-texture2dproj.html": 0.6005,
-    "conformance/glsl/samplers/glsl-function-texture2dprojlod.html": 0.9578,
-    "conformance/glsl/variables/gl-fragcoord-xy-values.html": 0.4841,
-    "conformance/glsl/variables/gl-fragcoord.html": 0.3376,
-    "conformance/glsl/variables/gl-fragdata-and-fragcolor.html": 0.3513,
-    "conformance/glsl/variables/gl-frontfacing.html": 0.1422,
-    "conformance/glsl/variables/gl-pointcoord.html": 0.3862,
-    "conformance/glsl/variables/glsl-built-ins.html": 0.5214,
-    "conformance/limits/gl-line-width.html": 0.3252,
-    "conformance/limits/gl-max-texture-dimensions.html": 0.5233,
-    "conformance/limits/gl-min-attribs.html": 0.2764,
-    "conformance/limits/gl-min-textures.html": 0.2667,
-    "conformance/limits/gl-min-uniforms.html": 0.323,
-    "conformance/misc/bad-arguments-test.html": 0.2999,
-    "conformance/misc/boolean-argument-conversion.html": 0.2967,
-    "conformance/misc/delayed-drawing.html": 1.4444,
-    "conformance/misc/error-reporting.html": 0.1056,
-    "conformance/misc/expando-loss.html": 0.3118,
-    "conformance/misc/functions-returning-strings.html": 0.2009,
-    "conformance/misc/invalid-passed-params.html": 0.2076,
-    "conformance/misc/is-object.html": 0.1392,
-    "conformance/misc/null-object-behaviour.html": 0.3171,
-    "conformance/misc/object-deletion-behaviour.html": 0.6722,
-    "conformance/misc/shader-precision-format.html": 0.3142,
-    "conformance/misc/type-conversion-test.html": 0.0,
-    "conformance/misc/uninitialized-test.html": 0.58,
-    "conformance/misc/webgl-specific-stencil-settings.html": 0.7486,
-    "conformance/misc/webgl-specific.html": 0.1152,
-    "conformance/more/conformance/constants.html": 0.1519,
-    "conformance/more/conformance/getContext.html": 0.1571,
-    "conformance/more/conformance/methods.html": 0.1915,
-    "conformance/more/conformance/quickCheckAPI-A.html": 0.2608,
-    "conformance/more/conformance/quickCheckAPI-B1.html": 0.5021,
-    "conformance/more/conformance/quickCheckAPI-B2.html": 0.3133,
-    "conformance/more/conformance/quickCheckAPI-B3.html": 0.4429,
-    "conformance/more/conformance/quickCheckAPI-B4.html": 0.2515,
-    "conformance/more/conformance/quickCheckAPI-C.html": 0.2303,
-    "conformance/more/conformance/quickCheckAPI-D_G.html": 0.4424,
-    "conformance/more/conformance/quickCheckAPI-G_I.html": 0.4384,
-    "conformance/more/conformance/quickCheckAPI-L_S.html": 0.3755,
-    "conformance/more/conformance/quickCheckAPI-S_V.html": 0.5229,
-    "conformance/more/conformance/webGLArrays.html": 0.2304,
-    "conformance/more/functions/bindBuffer.html": 0.4035,
-    "conformance/more/functions/bindBufferBadArgs.html": 0.2527,
-    "conformance/more/functions/bindFramebufferLeaveNonZero.html": 0.1885,
-    "conformance/more/functions/bufferData.html": 0.1338,
-    "conformance/more/functions/bufferDataBadArgs.html": 0.2168,
-    "conformance/more/functions/bufferSubData.html": 0.4199,
-    "conformance/more/functions/bufferSubDataBadArgs.html": 0.2891,
-    "conformance/more/functions/copyTexImage2D.html": 0.1762,
-    "conformance/more/functions/copyTexImage2DBadArgs.html": 0.2746,
-    "conformance/more/functions/copyTexSubImage2D.html": 0.5313,
-    "conformance/more/functions/copyTexSubImage2DBadArgs.html": 0.2437,
-    "conformance/more/functions/deleteBufferBadArgs.html": 0.1614,
-    "conformance/more/functions/drawArrays.html": 0.2299,
-    "conformance/more/functions/drawElements.html": 0.5292,
-    "conformance/more/functions/isTests.html": 0.3642,
-    "conformance/more/functions/isTestsBadArgs.html": 0.1044,
-    "conformance/more/functions/readPixels.html": 0.4773,
-    "conformance/more/functions/readPixelsBadArgs.html": 0.249,
-    "conformance/more/functions/texImage2D.html": 0.2797,
-    "conformance/more/functions/texImage2DBadArgs.html": 0.2473,
-    "conformance/more/functions/texImage2DHTML.html": 0.331,
-    "conformance/more/functions/texImage2DHTMLBadArgs.html": 0.1837,
-    "conformance/more/functions/texSubImage2D.html": 0.4245,
-    "conformance/more/functions/texSubImage2DBadArgs.html": 0.1425,
-    "conformance/more/functions/texSubImage2DHTML.html": 0.3317,
-    "conformance/more/functions/texSubImage2DHTMLBadArgs.html": 0.2148,
-    "conformance/more/functions/uniformMatrix.html": 0.2408,
-    "conformance/more/functions/uniformMatrixBadArgs.html": 0.2427,
-    "conformance/more/functions/uniformf.html": 0.2757,
-    "conformance/more/functions/uniformfArrayLen1.html": 0.1742,
-    "conformance/more/functions/uniformfBadArgs.html": 0.2018,
-    "conformance/more/functions/uniformi.html": 0.1787,
-    "conformance/more/functions/uniformiBadArgs.html": 0.3966,
-    "conformance/more/functions/vertexAttrib.html": 0.1872,
-    "conformance/more/functions/vertexAttribBadArgs.html": 0.2519,
-    "conformance/more/functions/vertexAttribPointer.html": 0.2014,
-    "conformance/more/functions/vertexAttribPointerBadArgs.html": 0.4793,
-    "conformance/more/glsl/arrayOutOfBounds.html": 0.3352,
-    "conformance/more/glsl/uniformOutOfBounds.html": 0.2434,
-    "conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html": 0.9041,
-    "conformance/offscreencanvas/context-creation-worker.html": 0.357,
-    "conformance/offscreencanvas/context-creation.html": 0.4214,
-    "conformance/offscreencanvas/context-lost-restored-worker.html": 0.3107,
-    "conformance/offscreencanvas/context-lost-restored.html": 0.217,
-    "conformance/offscreencanvas/context-lost-worker.html": 0.1722,
-    "conformance/offscreencanvas/context-lost.html": 0.1747,
-    "conformance/offscreencanvas/methods-worker.html": 0.3401,
-    "conformance/offscreencanvas/methods.html": 0.2968,
-    "conformance/offscreencanvas/offscreencanvas-resize.html": 0.346,
-    "conformance/offscreencanvas/offscreencanvas-timer-query.html": 0.1885,
-    "conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.4679,
-    "conformance/ogles/GL/abs/abs_001_to_006.html": 2.8082,
-    "conformance/ogles/GL/acos/acos_001_to_006.html": 2.8989,
-    "conformance/ogles/GL/all/all_001_to_004.html": 2.8114,
-    "conformance/ogles/GL/any/any_001_to_004.html": 2.9161,
-    "conformance/ogles/GL/array/array_001_to_006.html": 0.7714,
-    "conformance/ogles/GL/asin/asin_001_to_006.html": 3.0866,
-    "conformance/ogles/GL/atan/atan_001_to_008.html": 3.318,
-    "conformance/ogles/GL/atan/atan_009_to_012.html": 3.1781,
-    "conformance/ogles/GL/biConstants/biConstants_001_to_008.html": 2.8982,
-    "conformance/ogles/GL/biConstants/biConstants_009_to_016.html": 3.0389,
-    "conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html": 2.2809,
-    "conformance/ogles/GL/build/build_001_to_008.html": 0.4116,
-    "conformance/ogles/GL/build/build_009_to_016.html": 0.3277,
-    "conformance/ogles/GL/build/build_017_to_024.html": 0.3927,
-    "conformance/ogles/GL/build/build_025_to_032.html": 0.3831,
-    "conformance/ogles/GL/build/build_033_to_040.html": 0.576,
-    "conformance/ogles/GL/build/build_041_to_048.html": 0.2773,
-    "conformance/ogles/GL/build/build_049_to_056.html": 0.5383,
-    "conformance/ogles/GL/build/build_057_to_064.html": 0.2933,
-    "conformance/ogles/GL/build/build_065_to_072.html": 0.2955,
-    "conformance/ogles/GL/build/build_073_to_080.html": 0.3316,
-    "conformance/ogles/GL/build/build_081_to_088.html": 0.3243,
-    "conformance/ogles/GL/build/build_089_to_096.html": 0.4849,
-    "conformance/ogles/GL/build/build_097_to_104.html": 0.3877,
-    "conformance/ogles/GL/build/build_105_to_112.html": 0.4099,
-    "conformance/ogles/GL/build/build_113_to_120.html": 0.2886,
-    "conformance/ogles/GL/build/build_121_to_128.html": 0.4447,
-    "conformance/ogles/GL/build/build_129_to_136.html": 0.2887,
-    "conformance/ogles/GL/build/build_137_to_144.html": 0.4072,
-    "conformance/ogles/GL/build/build_145_to_152.html": 0.2937,
-    "conformance/ogles/GL/build/build_153_to_160.html": 0.3612,
-    "conformance/ogles/GL/build/build_161_to_168.html": 0.2547,
-    "conformance/ogles/GL/build/build_169_to_176.html": 0.2161,
-    "conformance/ogles/GL/build/build_177_to_178.html": 0.3134,
-    "conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html": 0.1731,
-    "conformance/ogles/GL/ceil/ceil_001_to_006.html": 2.6012,
-    "conformance/ogles/GL/clamp/clamp_001_to_006.html": 2.9544,
-    "conformance/ogles/GL/control_flow/control_flow_001_to_008.html": 0.8169,
-    "conformance/ogles/GL/control_flow/control_flow_009_to_010.html": 0.4405,
-    "conformance/ogles/GL/cos/cos_001_to_006.html": 3.1236,
-    "conformance/ogles/GL/cross/cross_001_to_002.html": 2.4583,
-    "conformance/ogles/GL/default/default_001_to_001.html": 0.6329,
-    "conformance/ogles/GL/degrees/degrees_001_to_006.html": 2.8479,
-    "conformance/ogles/GL/discard/discard_001_to_002.html": 0.6362,
-    "conformance/ogles/GL/distance/distance_001_to_006.html": 2.7963,
-    "conformance/ogles/GL/dot/dot_001_to_006.html": 3.0436,
-    "conformance/ogles/GL/equal/equal_001_to_008.html": 2.8562,
-    "conformance/ogles/GL/equal/equal_009_to_012.html": 2.7881,
-    "conformance/ogles/GL/exp/exp_001_to_008.html": 2.9173,
-    "conformance/ogles/GL/exp/exp_009_to_012.html": 2.577,
-    "conformance/ogles/GL/exp2/exp2_001_to_008.html": 3.3721,
-    "conformance/ogles/GL/exp2/exp2_009_to_012.html": 2.803,
-    "conformance/ogles/GL/faceforward/faceforward_001_to_006.html": 2.9212,
-    "conformance/ogles/GL/floor/floor_001_to_006.html": 2.9441,
-    "conformance/ogles/GL/fract/fract_001_to_006.html": 2.9293,
-    "conformance/ogles/GL/functions/functions_001_to_008.html": 3.0274,
-    "conformance/ogles/GL/functions/functions_009_to_016.html": 0.9209,
-    "conformance/ogles/GL/functions/functions_017_to_024.html": 0.779,
-    "conformance/ogles/GL/functions/functions_025_to_032.html": 0.874,
-    "conformance/ogles/GL/functions/functions_033_to_040.html": 0.8912,
-    "conformance/ogles/GL/functions/functions_041_to_048.html": 0.9953,
-    "conformance/ogles/GL/functions/functions_049_to_056.html": 1.0501,
-    "conformance/ogles/GL/functions/functions_057_to_064.html": 0.9192,
-    "conformance/ogles/GL/functions/functions_065_to_072.html": 1.0992,
-    "conformance/ogles/GL/functions/functions_073_to_080.html": 0.9976,
-    "conformance/ogles/GL/functions/functions_081_to_088.html": 0.7684,
-    "conformance/ogles/GL/functions/functions_089_to_096.html": 0.8455,
-    "conformance/ogles/GL/functions/functions_097_to_104.html": 0.8402,
-    "conformance/ogles/GL/functions/functions_105_to_112.html": 0.8285,
-    "conformance/ogles/GL/functions/functions_113_to_120.html": 0.9833,
-    "conformance/ogles/GL/functions/functions_121_to_126.html": 0.8891,
-    "conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html": 0.7293,
-    "conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html": 0.652,
-    "conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html": 2.9623,
-    "conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html": 3.2424,
-    "conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html": 2.909,
-    "conformance/ogles/GL/length/length_001_to_006.html": 2.8937,
-    "conformance/ogles/GL/lessThan/lessThan_001_to_008.html": 3.0495,
-    "conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html": 3.0615,
-    "conformance/ogles/GL/log/log_001_to_008.html": 3.079,
-    "conformance/ogles/GL/log/log_009_to_012.html": 2.8898,
-    "conformance/ogles/GL/log2/log2_001_to_008.html": 3.008,
-    "conformance/ogles/GL/log2/log2_009_to_012.html": 2.9547,
-    "conformance/ogles/GL/mat/mat_001_to_008.html": 0.8573,
-    "conformance/ogles/GL/mat/mat_009_to_016.html": 0.9535,
-    "conformance/ogles/GL/mat/mat_017_to_024.html": 0.8951,
-    "conformance/ogles/GL/mat/mat_025_to_032.html": 3.0759,
-    "conformance/ogles/GL/mat/mat_033_to_040.html": 3.098,
-    "conformance/ogles/GL/mat/mat_041_to_046.html": 0.6759,
-    "conformance/ogles/GL/mat3/mat3_001_to_006.html": 0.8285,
-    "conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html": 2.67,
-    "conformance/ogles/GL/max/max_001_to_006.html": 2.728,
-    "conformance/ogles/GL/min/min_001_to_006.html": 2.9185,
-    "conformance/ogles/GL/mix/mix_001_to_006.html": 2.8366,
-    "conformance/ogles/GL/mod/mod_001_to_008.html": 2.9838,
-    "conformance/ogles/GL/normalize/normalize_001_to_006.html": 2.921,
-    "conformance/ogles/GL/not/not_001_to_004.html": 2.8664,
-    "conformance/ogles/GL/notEqual/notEqual_001_to_008.html": 3.2451,
-    "conformance/ogles/GL/notEqual/notEqual_009_to_012.html": 2.7443,
-    "conformance/ogles/GL/operators/operators_001_to_008.html": 0.8589,
-    "conformance/ogles/GL/operators/operators_009_to_016.html": 0.9565,
-    "conformance/ogles/GL/operators/operators_017_to_024.html": 0.9056,
-    "conformance/ogles/GL/operators/operators_025_to_026.html": 0.6206,
-    "conformance/ogles/GL/pow/pow_001_to_008.html": 1.1036,
-    "conformance/ogles/GL/pow/pow_009_to_016.html": 3.0634,
-    "conformance/ogles/GL/pow/pow_017_to_024.html": 3.186,
-    "conformance/ogles/GL/radians/radians_001_to_006.html": 2.8656,
-    "conformance/ogles/GL/reflect/reflect_001_to_006.html": 3.4024,
-    "conformance/ogles/GL/refract/refract_001_to_006.html": 2.728,
-    "conformance/ogles/GL/sign/sign_001_to_006.html": 3.0497,
-    "conformance/ogles/GL/sin/sin_001_to_006.html": 3.0811,
-    "conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html": 2.9807,
-    "conformance/ogles/GL/sqrt/sqrt_001_to_006.html": 2.8298,
-    "conformance/ogles/GL/step/step_001_to_006.html": 2.7911,
-    "conformance/ogles/GL/struct/struct_001_to_008.html": 3.2044,
-    "conformance/ogles/GL/struct/struct_009_to_016.html": 2.8258,
-    "conformance/ogles/GL/struct/struct_017_to_024.html": 2.9781,
-    "conformance/ogles/GL/struct/struct_025_to_032.html": 3.1905,
-    "conformance/ogles/GL/struct/struct_033_to_040.html": 3.126,
-    "conformance/ogles/GL/struct/struct_041_to_048.html": 3.0655,
-    "conformance/ogles/GL/struct/struct_049_to_056.html": 3.3849,
-    "conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html": 3.0182,
-    "conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html": 2.9678,
-    "conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html": 3.1438,
-    "conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html": 3.136,
-    "conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html": 3.416,
-    "conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html": 3.0388,
-    "conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html": 3.1373,
-    "conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html": 3.1467,
-    "conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html": 3.187,
-    "conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html": 3.2781,
-    "conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html": 3.1533,
-    "conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html": 3.1221,
-    "conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html": 3.0734,
-    "conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html": 3.0303,
-    "conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html": 3.0807,
-    "conformance/ogles/GL/tan/tan_001_to_006.html": 2.8305,
-    "conformance/ogles/GL/vec/vec_001_to_008.html": 0.8871,
-    "conformance/ogles/GL/vec/vec_009_to_016.html": 0.9646,
-    "conformance/ogles/GL/vec/vec_017_to_018.html": 0.6801,
-    "conformance/ogles/GL/vec3/vec3_001_to_008.html": 0.9221,
-    "conformance/programs/get-active-test.html": 0.7471,
-    "conformance/programs/gl-bind-attrib-location-long-names-test.html": 0.3845,
-    "conformance/programs/gl-bind-attrib-location-test.html": 0.313,
-    "conformance/programs/gl-get-active-attribute.html": 0.3972,
-    "conformance/programs/gl-get-active-uniform.html": 0.4713,
-    "conformance/programs/gl-getshadersource.html": 0.3665,
-    "conformance/programs/gl-shader-test.html": 0.3991,
-    "conformance/programs/invalid-UTF-16.html": 0.1172,
-    "conformance/programs/program-handling.html": 0.9312,
-    "conformance/programs/program-infolog.html": 0.3138,
-    "conformance/programs/program-test.html": 0.4099,
-    "conformance/programs/use-program-crash-with-discard-in-fragment-shader.html": 0.3397,
-    "conformance/reading/fbo-remains-unchanged-after-read-pixels.html": 0.3127,
-    "conformance/reading/read-pixels-pack-alignment.html": 0.6994,
-    "conformance/reading/read-pixels-test.html": 3.376,
-    "conformance/renderbuffers/depth-renderbuffer-initialization.html": 0.7315,
-    "conformance/renderbuffers/feedback-loop.html": 0.4758,
-    "conformance/renderbuffers/framebuffer-state-restoration.html": 0.5003,
-    "conformance/renderbuffers/renderbuffer-initialization.html": 0.5334,
-    "conformance/renderbuffers/stencil-renderbuffer-initialization.html": 0.4215,
-    "conformance/rendering/bind-framebuffer-flush-bug.html": 0.3009,
-    "conformance/rendering/blending.html": 0.5112,
-    "conformance/rendering/canvas-alpha-bug.html": 0.3398,
-    "conformance/rendering/clear-after-copyTexImage2D.html": 0.5182,
-    "conformance/rendering/color-mask-preserved-during-implicit-clears.html": 1.9128,
-    "conformance/rendering/culling.html": 0.4259,
-    "conformance/rendering/default-texture-draw-bug.html": 0.307,
-    "conformance/rendering/draw-arrays-out-of-bounds.html": 0.2992,
-    "conformance/rendering/draw-elements-out-of-bounds.html": 0.2988,
-    "conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html": 0.3927,
-    "conformance/rendering/draw-with-changing-start-vertex-bug.html": 0.4792,
-    "conformance/rendering/framebuffer-switch.html": 0.6096,
-    "conformance/rendering/framebuffer-texture-clear.html": 0.1997,
-    "conformance/rendering/framebuffer-texture-switch.html": 0.5418,
-    "conformance/rendering/gl-clear.html": 12.8384,
-    "conformance/rendering/gl-drawarrays.html": 0.3864,
-    "conformance/rendering/gl-drawelements.html": 0.3714,
-    "conformance/rendering/gl-scissor-canvas-dimensions.html": 0.169,
-    "conformance/rendering/gl-scissor-fbo-test.html": 0.5317,
-    "conformance/rendering/gl-scissor-test.html": 0.7793,
-    "conformance/rendering/gl-viewport-test.html": 0.7521,
-    "conformance/rendering/line-loop-tri-fan.html": 0.1273,
-    "conformance/rendering/line-rendering-quality.html": 0.5506,
-    "conformance/rendering/many-draw-calls.html": 2.0114,
-    "conformance/rendering/more-than-65536-indices.html": 0.9717,
-    "conformance/rendering/multisample-corruption.html": 3.9421,
-    "conformance/rendering/negative-one-index.html": 0.1301,
-    "conformance/rendering/out-of-bounds-array-buffers.html": 0.4088,
-    "conformance/rendering/out-of-bounds-index-buffers.html": 0.2027,
-    "conformance/rendering/point-no-attributes.html": 0.141,
-    "conformance/rendering/point-size.html": 0.1725,
-    "conformance/rendering/point-specific-shader-variables.html": 0.3947,
-    "conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html": 0.3224,
-    "conformance/rendering/polygon-offset.html": 0.1939,
-    "conformance/rendering/preservedrawingbuffer-leak.html": 1.0959,
-    "conformance/rendering/rendering-sampling-feedback-loop.html": 0.311,
-    "conformance/rendering/rendering-stencil-large-viewport.html": 0.5551,
-    "conformance/rendering/scissor-rect-repeated-rendering.html": 0.3991,
-    "conformance/rendering/simple.html": 0.3077,
-    "conformance/rendering/texture-switch-performance.html": 0.0,
-    "conformance/rendering/triangle.html": 0.1666,
-    "conformance/state/fb-attach-implicit-target-assignment.html": 0.1657,
-    "conformance/state/gl-enable-enum-test.html": 0.6183,
-    "conformance/state/gl-get-calls.html": 0.1468,
-    "conformance/state/gl-geterror.html": 0.3911,
-    "conformance/state/gl-initial-state.html": 0.2913,
-    "conformance/state/state-uneffected-after-compositing.html": 0.3369,
-    "conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.0636,
-    "conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.2659,
-    "conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.8792,
-    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html": 4.3671,
-    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.5835,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html": 4.1579,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.2177,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.6446,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html": 1.2265,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html": 1.3077,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.1277,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html": 2.3804,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.1499,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html": 1.2218,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.8558,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.6429,
-    "conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html": 0.5052,
-    "conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html": 0.7716,
-    "conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.7081,
-    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html": 0.561,
-    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4089,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html": 0.5432,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.7802,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4981,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html": 0.7137,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html": 0.6308,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.845,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html": 0.7933,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.7071,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html": 0.8659,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5938,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.6079,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.2433,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.8987,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.0699,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 1.01,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.2122,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 1.0518,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.9415,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.876,
-    "conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.7912,
-    "conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.4553,
-    "conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.6666,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.7378,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5827,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.6331,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.8023,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.6594,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html": 0.472,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html": 0.5334,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.4734,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html": 0.4122,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3514,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html": 0.3492,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5301,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7807,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.5333,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.7805,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5639,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.4064,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4742,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.4776,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5741,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4453,
-    "conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html": 0.7061,
-    "conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html": 0.6327,
-    "conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.497,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html": 0.6112,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5755,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html": 0.6547,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4888,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7575,
-    "conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html": 1.4108,
-    "conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.745,
-    "conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.9405,
-    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.5918,
-    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.7854,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.6035,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.8457,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7936,
-    "conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html": 0.3199,
-    "conformance/textures/misc/copy-tex-image-2d-formats.html": 0.4395,
-    "conformance/textures/misc/copy-tex-image-and-sub-image-2d.html": 0.7348,
-    "conformance/textures/misc/copy-tex-image-crash.html": 0.1905,
-    "conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html": 0.4188,
-    "conformance/textures/misc/copytexsubimage2d-subrects.html": 0.1826,
-    "conformance/textures/misc/cube-incomplete-fbo.html": 0.1486,
-    "conformance/textures/misc/cube-map-uploads-out-of-order.html": 1.1393,
-    "conformance/textures/misc/default-texture.html": 0.1779,
-    "conformance/textures/misc/exif-orientation.html": 0.7674,
-    "conformance/textures/misc/gl-pixelstorei.html": 0.2008,
-    "conformance/textures/misc/gl-teximage.html": 1.1086,
-    "conformance/textures/misc/mipmap-fbo.html": 0.3335,
-    "conformance/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.3235,
-    "conformance/textures/misc/origin-clean-conformance.html": 0.1855,
-    "conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html": 2.0769,
-    "conformance/textures/misc/tex-image-and-uniform-binding-bugs.html": 0.1094,
-    "conformance/textures/misc/tex-image-canvas-corruption.html": 0.5558,
-    "conformance/textures/misc/tex-image-webgl.html": 0.3179,
-    "conformance/textures/misc/tex-image-with-format-and-type.html": 0.9681,
-    "conformance/textures/misc/tex-image-with-invalid-data.html": 0.1058,
-    "conformance/textures/misc/tex-sub-image-2d-bad-args.html": 0.2039,
-    "conformance/textures/misc/tex-sub-image-2d.html": 0.161,
-    "conformance/textures/misc/tex-video-using-tex-unit-non-zero.html": 0.746,
-    "conformance/textures/misc/texparameter-test.html": 0.3683,
-    "conformance/textures/misc/texture-active-bind-2.html": 0.3354,
-    "conformance/textures/misc/texture-active-bind.html": 0.2007,
-    "conformance/textures/misc/texture-attachment-formats.html": 0.4068,
-    "conformance/textures/misc/texture-clear.html": 0.1715,
-    "conformance/textures/misc/texture-complete.html": 0.1533,
-    "conformance/textures/misc/texture-copying-and-deletion.html": 1.2349,
-    "conformance/textures/misc/texture-copying-feedback-loops.html": 0.1142,
-    "conformance/textures/misc/texture-corner-case-videos.html": 0.3093,
-    "conformance/textures/misc/texture-cube-as-fbo-attachment.html": 0.231,
-    "conformance/textures/misc/texture-draw-with-2d-and-cube.html": 0.1019,
-    "conformance/textures/misc/texture-hd-dpi.html": 0.353,
-    "conformance/textures/misc/texture-mips.html": 0.3779,
-    "conformance/textures/misc/texture-size-cube-maps.html": 0.8743,
-    "conformance/textures/misc/texture-size-limit.html": 0.5067,
-    "conformance/textures/misc/texture-size.html": 1.2286,
-    "conformance/textures/misc/texture-sub-image-cube-maps.html": 0.5006,
-    "conformance/textures/misc/texture-transparent-pixels-initialized.html": 0.4271,
-    "conformance/textures/misc/texture-upload-cube-maps.html": 0.4384,
-    "conformance/textures/misc/texture-upload-size.html": 0.5463,
-    "conformance/textures/misc/texture-video-transparent.html": 2.4005,
-    "conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html": 0.1244,
-    "conformance/textures/misc/upload-from-srcset-with-empty-data.html": 0.216,
-    "conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.4354,
-    "conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.1914,
-    "conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3896,
-    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3765,
-    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1852,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.423,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3915,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3032,
-    "conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html": 0.7933,
-    "conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html": 0.9321,
-    "conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5761,
-    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html": 0.8117,
-    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.8596,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html": 0.6039,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.8286,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.866,
-    "conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 2.099,
-    "conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.3863,
-    "conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.5391,
-    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 4.9072,
-    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.5133,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 5.3275,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.7977,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.4056,
-    "conformance/typedarrays/array-buffer-crash.html": 0.0671,
-    "conformance/typedarrays/array-buffer-view-crash.html": 0.0867,
-    "conformance/typedarrays/array-large-array-tests.html": 0.3225,
-    "conformance/typedarrays/array-unit-tests.html": 0.1226,
-    "conformance/typedarrays/data-view-crash.html": 0.1066,
-    "conformance/typedarrays/data-view-test.html": 0.1462,
-    "conformance/typedarrays/typed-arrays-in-workers.html": 0.162,
-    "conformance/uniforms/gl-uniform-arrays.html": 0.4747,
-    "conformance/uniforms/gl-uniform-bool.html": 0.2007,
-    "conformance/uniforms/gl-uniformmatrix4fv.html": 0.2121,
-    "conformance/uniforms/gl-unknown-uniform.html": 0.1349,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-00.html": 1.341,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-01.html": 1.0657,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-02.html": 1.5066,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-03.html": 1.0568,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-04.html": 1.7469,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-05.html": 1.6042,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-06.html": 1.3688,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-07.html": 1.4745,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-08.html": 1.4427,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-09.html": 2.1216,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-10.html": 1.3261,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-11.html": 1.3819,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-12.html": 2.2069,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-13.html": 1.1593,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-14.html": 1.6884,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-15.html": 1.6679,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-16.html": 1.5267,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-17.html": 1.3343,
-    "conformance/uniforms/null-uniform-location.html": 0.3938,
-    "conformance/uniforms/out-of-bounds-uniform-array-access.html": 3.477,
-    "conformance/uniforms/uniform-default-values.html": 1.9935,
-    "conformance/uniforms/uniform-location.html": 0.5463,
-    "conformance/uniforms/uniform-samplers-test.html": 24.516,
-    "conformance/uniforms/uniform-values-per-program.html": 1.0317,
-    "conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html": 0.7929,
-    "conformance2/attribs/gl-vertex-attrib-i-render.html": 0.2106,
-    "conformance2/attribs/gl-vertex-attrib-normalized-int.html": 0.1165,
-    "conformance2/attribs/gl-vertex-attrib.html": 0.9694,
-    "conformance2/attribs/gl-vertexattribipointer-offsets.html": 0.5687,
-    "conformance2/attribs/gl-vertexattribipointer.html": 1.3529,
-    "conformance2/attribs/render-no-enabled-attrib-arrays.html": 0.2172,
-    "conformance2/buffers/bound-buffer-size-change-test.html": 0.2984,
-    "conformance2/buffers/buffer-copying-contents.html": 0.6368,
-    "conformance2/buffers/buffer-copying-restrictions.html": 0.123,
-    "conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html": 0.355,
-    "conformance2/buffers/buffer-overflow-test.html": 0.1775,
-    "conformance2/buffers/buffer-type-restrictions.html": 0.5574,
-    "conformance2/buffers/delete-buffer.html": 0.2169,
-    "conformance2/buffers/get-buffer-sub-data-validity.html": 0.4969,
-    "conformance2/buffers/get-buffer-sub-data.html": 0.1622,
-    "conformance2/buffers/one-large-uniform-buffer.html": 0.4448,
-    "conformance2/buffers/uniform-buffers-second-compile.html": 0.1541,
-    "conformance2/buffers/uniform-buffers-state-restoration.html": 0.6353,
-    "conformance2/buffers/uniform-buffers.html": 0.431,
-    "conformance2/canvas/to-data-url-with-pack-params.html": 0.2331,
-    "conformance2/context/constants-and-properties-2.html": 0.2124,
-    "conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html": 0.2031,
-    "conformance2/context/context-mode.html": 0.2001,
-    "conformance2/context/context-resize-changes-buffer-binding-bug.html": 0.4545,
-    "conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html": 0.9247,
-    "conformance2/context/context-type-test-2.html": 0.1318,
-    "conformance2/context/incorrect-context-object-behaviour.html": 0.4204,
-    "conformance2/context/methods-2.html": 0.0949,
-    "conformance2/context/no-experimental-webgl2.html": 0.0649,
-    "conformance2/extensions/ext-color-buffer-float.html": 0.7638,
-    "conformance2/extensions/ext-color-buffer-half-float.html": 0.8968,
-    "conformance2/extensions/ext-disjoint-timer-query-webgl2.html": 8.168,
-    "conformance2/extensions/ext-texture-filter-anisotropic.html": 0.1492,
-    "conformance2/extensions/ext-texture-norm16.html": 0.3666,
-    "conformance2/extensions/oes-draw-buffers-indexed.html": 0.5775,
-    "conformance2/extensions/ovr_multiview2.html": 1.6216,
-    "conformance2/extensions/ovr_multiview2_depth.html": 0.4598,
-    "conformance2/extensions/ovr_multiview2_draw_buffers.html": 0.5874,
-    "conformance2/extensions/ovr_multiview2_flat_varying.html": 0.5047,
-    "conformance2/extensions/ovr_multiview2_instanced_draw.html": 0.7869,
-    "conformance2/extensions/ovr_multiview2_non_multiview_shaders.html": 1.006,
-    "conformance2/extensions/ovr_multiview2_single_view_operations.html": 0.9591,
-    "conformance2/extensions/ovr_multiview2_timer_query.html": 0.4799,
-    "conformance2/extensions/ovr_multiview2_transform_feedback.html": 0.4464,
-    "conformance2/extensions/promoted-extensions-in-shaders.html": 0.6803,
-    "conformance2/extensions/promoted-extensions.html": 0.1411,
-    "conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html": 1.7593,
-    "conformance2/glsl3/array-as-return-value.html": 0.3873,
-    "conformance2/glsl3/array-assign-constructor.html": 0.16,
-    "conformance2/glsl3/array-assign.html": 0.17,
-    "conformance2/glsl3/array-complex-indexing.html": 0.6304,
-    "conformance2/glsl3/array-element-increment.html": 0.5941,
-    "conformance2/glsl3/array-equality.html": 0.4129,
-    "conformance2/glsl3/array-in-complex-expression.html": 0.3775,
-    "conformance2/glsl3/array-initialize-with-same-name-array.html": 0.3577,
-    "conformance2/glsl3/array-length-side-effects.html": 0.4921,
-    "conformance2/glsl3/attrib-location-length-limits.html": 0.2775,
-    "conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html": 0.3611,
-    "conformance2/glsl3/compare-structs-containing-arrays.html": 0.3623,
-    "conformance2/glsl3/compound-assignment-type-combination.html": 2.675,
-    "conformance2/glsl3/const-array-init.html": 0.3337,
-    "conformance2/glsl3/const-struct-from-array-as-function-parameter.html": 0.1667,
-    "conformance2/glsl3/float-parsing.html": 0.682,
-    "conformance2/glsl3/forbidden-operators.html": 0.4363,
-    "conformance2/glsl3/forward-declaration.html": 0.3527,
-    "conformance2/glsl3/frag-depth.html": 0.1993,
-    "conformance2/glsl3/gradient-in-discontinuous-loop.html": 0.1966,
-    "conformance2/glsl3/input-with-interpotaion-as-lvalue.html": 0.4151,
-    "conformance2/glsl3/invalid-default-precision.html": 0.4497,
-    "conformance2/glsl3/invalid-invariant.html": 0.3589,
-    "conformance2/glsl3/loops-with-side-effects.html": 0.698,
-    "conformance2/glsl3/matrix-row-major-dynamic-indexing.html": 0.4338,
-    "conformance2/glsl3/matrix-row-major.html": 0.4156,
-    "conformance2/glsl3/misplaced-version-directive.html": 0.5199,
-    "conformance2/glsl3/no-attribute-vertex-shader.html": 0.5508,
-    "conformance2/glsl3/sampler-array-indexing.html": 0.4845,
-    "conformance2/glsl3/sampler-no-precision.html": 0.3665,
-    "conformance2/glsl3/sequence-operator-returns-non-constant.html": 0.3764,
-    "conformance2/glsl3/shader-linking.html": 0.2088,
-    "conformance2/glsl3/shader-with-1024-character-define.html": 0.4969,
-    "conformance2/glsl3/shader-with-1024-character-identifier.frag.html": 0.3899,
-    "conformance2/glsl3/shader-with-1025-character-define.html": 0.3832,
-    "conformance2/glsl3/shader-with-1025-character-identifier.frag.html": 0.1559,
-    "conformance2/glsl3/shader-with-invalid-characters.html": 0.1278,
-    "conformance2/glsl3/shader-with-mis-matching-uniform-block.html": 0.2273,
-    "conformance2/glsl3/short-circuiting-in-loop-condition.html": 0.4605,
-    "conformance2/glsl3/switch-case.html": 0.6012,
-    "conformance2/glsl3/texture-offset-non-constant-offset.html": 0.2811,
-    "conformance2/glsl3/texture-offset-out-of-range.html": 0.2314,
-    "conformance2/glsl3/texture-offset-uniform-texture-coordinate.html": 0.2732,
-    "conformance2/glsl3/tricky-loop-conditions.html": 1.0059,
-    "conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html": 0.7658,
-    "conformance2/glsl3/uniform-block-layout-match.html": 0.2462,
-    "conformance2/glsl3/uniform-block-layouts.html": 0.4879,
-    "conformance2/glsl3/uniform-location-length-limits.html": 0.431,
-    "conformance2/glsl3/uniform-struct-with-non-square-matrix.html": 0.4353,
-    "conformance2/glsl3/uninitialized-local-global-variables.html": 0.3166,
-    "conformance2/glsl3/valid-invariant.html": 0.1278,
-    "conformance2/glsl3/varying-struct-inline-definition.html": 0.5139,
-    "conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html": 0.2139,
-    "conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html": 0.5175,
-    "conformance2/glsl3/vector-dynamic-indexing.html": 0.6785,
-    "conformance2/misc/expando-loss-2.html": 0.5043,
-    "conformance2/misc/getextension-while-pbo-bound-stability.html": 0.2805,
-    "conformance2/misc/instanceof-test.html": 0.3835,
-    "conformance2/misc/null-object-behaviour-2.html": 0.2713,
-    "conformance2/misc/object-deletion-behaviour-2.html": 0.3203,
-    "conformance2/misc/uninitialized-test-2.html": 15.5432,
-    "conformance2/misc/views-with-offsets.html": 0.4898,
-    "conformance2/offscreencanvas/context-creation-worker.html": 0.2157,
-    "conformance2/offscreencanvas/context-creation.html": 0.2026,
-    "conformance2/offscreencanvas/methods-2-worker.html": 0.1736,
-    "conformance2/offscreencanvas/methods-2.html": 0.2034,
-    "conformance2/offscreencanvas/offscreencanvas-query.html": 0.2062,
-    "conformance2/offscreencanvas/offscreencanvas-sync.html": 0.1611,
-    "conformance2/offscreencanvas/offscreencanvas-timer-query.html": 0.3943,
-    "conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.2117,
-    "conformance2/programs/active-built-in-attribs.html": 0.2781,
-    "conformance2/programs/gl-get-frag-data-location.html": 0.4567,
-    "conformance2/programs/sampler-uniforms.html": 0.5902,
-    "conformance2/query/occlusion-query.html": 3.4598,
-    "conformance2/query/query.html": 0.1032,
-    "conformance2/reading/format-r11f-g11f-b10f.html": 0.4098,
-    "conformance2/reading/read-pixels-from-fbo-test.html": 0.7119,
-    "conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html": 0.247,
-    "conformance2/reading/read-pixels-into-pixel-pack-buffer.html": 0.1061,
-    "conformance2/reading/read-pixels-pack-parameters.html": 0.4235,
-    "conformance2/renderbuffers/framebuffer-object-attachment.html": 0.2328,
-    "conformance2/renderbuffers/framebuffer-test.html": 0.1204,
-    "conformance2/renderbuffers/framebuffer-texture-layer.html": 0.1181,
-    "conformance2/renderbuffers/invalidate-framebuffer.html": 0.1152,
-    "conformance2/renderbuffers/multisample-with-full-sample-counts.html": 0.2597,
-    "conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html": 0.745,
-    "conformance2/renderbuffers/multisampled-renderbuffer-initialization.html": 0.8211,
-    "conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html": 0.6727,
-    "conformance2/renderbuffers/readbuffer.html": 0.435,
-    "conformance2/rendering/attrib-type-match.html": 0.5153,
-    "conformance2/rendering/blitframebuffer-filter-outofbounds.html": 0.7073,
-    "conformance2/rendering/blitframebuffer-filter-srgb.html": 0.2962,
-    "conformance2/rendering/blitframebuffer-multisampled-readbuffer.html": 0.1846,
-    "conformance2/rendering/blitframebuffer-outside-readbuffer.html": 0.1914,
-    "conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html": 0.2701,
-    "conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html": 0.2987,
-    "conformance2/rendering/blitframebuffer-scissor-enabled.html": 0.2491,
-    "conformance2/rendering/blitframebuffer-size-overflow.html": 0.3128,
-    "conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html": 0.2414,
-    "conformance2/rendering/blitframebuffer-stencil-only.html": 0.4163,
-    "conformance2/rendering/blitframebuffer-test.html": 0.3189,
-    "conformance2/rendering/canvas-resizing-with-pbo-bound.html": 0.3677,
-    "conformance2/rendering/clear-func-buffer-type-match.html": 0.1486,
-    "conformance2/rendering/clear-srgb-color-buffer.html": 0.2518,
-    "conformance2/rendering/clearbuffer-sub-source.html": 0.4455,
-    "conformance2/rendering/clearbufferfv-with-alpha-false.html": 0.1287,
-    "conformance2/rendering/clipping-wide-points.html": 0.1907,
-    "conformance2/rendering/depth-stencil-feedback-loop.html": 0.3786,
-    "conformance2/rendering/draw-buffers-dirty-state-bug.html": 0.3008,
-    "conformance2/rendering/draw-buffers-driver-hang.html": 0.3098,
-    "conformance2/rendering/draw-buffers.html": 0.9372,
-    "conformance2/rendering/draw-with-integer-texture-base-level.html": 0.1583,
-    "conformance2/rendering/element-index-uint.html": 0.7611,
-    "conformance2/rendering/framebuffer-completeness-draw-framebuffer.html": 0.3241,
-    "conformance2/rendering/framebuffer-completeness-unaffected.html": 0.1674,
-    "conformance2/rendering/framebuffer-mismatched-attachment-targets.html": 0.2425,
-    "conformance2/rendering/framebuffer-render-to-layer-angle-issue.html": 0.1436,
-    "conformance2/rendering/framebuffer-render-to-layer.html": 2.3018,
-    "conformance2/rendering/framebuffer-texture-changing-base-level.html": 0.2115,
-    "conformance2/rendering/framebuffer-texture-level1.html": 0.0864,
-    "conformance2/rendering/framebuffer-unsupported.html": 0.1101,
-    "conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html": 0.1375,
-    "conformance2/rendering/instanced-arrays.html": 0.4483,
-    "conformance2/rendering/instanced-rendering-bug.html": 0.5029,
-    "conformance2/rendering/instanced-rendering-large-divisor.html": 0.1833,
-    "conformance2/rendering/line-rendering-quality.html": 0.3471,
-    "conformance2/rendering/multisampling-fragment-evaluation.html": 0.182,
-    "conformance2/rendering/out-of-bounds-index-buffers-after-copying.html": 0.2799,
-    "conformance2/rendering/rasterizer-discard-and-implicit-clear.html": 0.8586,
-    "conformance2/rendering/read-draw-when-missing-image.html": 0.2873,
-    "conformance2/rendering/rgb-format-support.html": 0.3084,
-    "conformance2/rendering/texture-switch-performance.html": 0.0,
-    "conformance2/rendering/uniform-block-buffer-size.html": 0.4152,
-    "conformance2/rendering/vertex-id.html": 0.4436,
-    "conformance2/samplers/multi-context-sampler-test.html": 0.2857,
-    "conformance2/samplers/sampler-drawing-test.html": 0.3815,
-    "conformance2/samplers/samplers.html": 0.4774,
-    "conformance2/state/gl-enum-tests.html": 0.2563,
-    "conformance2/state/gl-get-calls.html": 0.3113,
-    "conformance2/state/gl-getstring.html": 0.2255,
-    "conformance2/state/gl-object-get-calls.html": 16.3843,
-    "conformance2/sync/sync-webgl-specific.html": 23.1643,
-    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.2813,
-    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.5635,
-    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.9323,
-    "conformance2/textures/canvas/tex-2d-r16f-red-float.html": 1.657,
-    "conformance2/textures/canvas/tex-2d-r16f-red-half_float.html": 1.452,
-    "conformance2/textures/canvas/tex-2d-r32f-red-float.html": 1.1352,
-    "conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html": 1.6673,
-    "conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.9966,
-    "conformance2/textures/canvas/tex-2d-rg16f-rg-float.html": 1.4202,
-    "conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html": 1.3841,
-    "conformance2/textures/canvas/tex-2d-rg32f-rg-float.html": 1.0508,
-    "conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html": 1.2845,
-    "conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.4452,
-    "conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.3854,
-    "conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html": 1.4447,
-    "conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html": 1.1358,
-    "conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html": 1.6026,
-    "conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.7655,
-    "conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.1165,
-    "conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 2.1894,
-    "conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.097,
-    "conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 1.4629,
-    "conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.7236,
-    "conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html": 1.5263,
-    "conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.7806,
-    "conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html": 1.5318,
-    "conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html": 1.4868,
-    "conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html": 1.7554,
-    "conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 1.4471,
-    "conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.0097,
-    "conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.5278,
-    "conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.3039,
-    "conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.4522,
-    "conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.5371,
-    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 5.8411,
-    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 5.8969,
-    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 5.6245,
-    "conformance2/textures/canvas/tex-3d-r16f-red-float.html": 5.6296,
-    "conformance2/textures/canvas/tex-3d-r16f-red-half_float.html": 5.737,
-    "conformance2/textures/canvas/tex-3d-r32f-red-float.html": 7.3679,
-    "conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html": 5.4286,
-    "conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 5.9279,
-    "conformance2/textures/canvas/tex-3d-rg16f-rg-float.html": 5.9073,
-    "conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html": 5.4323,
-    "conformance2/textures/canvas/tex-3d-rg32f-rg-float.html": 5.845,
-    "conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html": 5.98,
-    "conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 5.4712,
-    "conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 5.4847,
-    "conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html": 5.6118,
-    "conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html": 6.0393,
-    "conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html": 5.8583,
-    "conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 5.5456,
-    "conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 6.0045,
-    "conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 5.8877,
-    "conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 5.4563,
-    "conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 6.0692,
-    "conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 5.9428,
-    "conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html": 5.905,
-    "conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html": 5.9819,
-    "conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html": 5.4939,
-    "conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html": 5.3238,
-    "conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html": 5.7412,
-    "conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 5.579,
-    "conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 5.5909,
-    "conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 5.5784,
-    "conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 5.7007,
-    "conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 5.7369,
-    "conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 5.611,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.5115,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.5505,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.0607,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html": 2.3934,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html": 1.2673,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html": 1.1373,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html": 1.5795,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html": 2.676,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html": 1.9324,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html": 1.8467,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html": 1.5616,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html": 1.4224,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.3379,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.2912,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html": 1.4586,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html": 1.4236,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html": 1.3043,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html": 2.101,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.857,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 2.2486,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 2.1424,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html": 2.0904,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.6081,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html": 1.5442,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html": 2.2974,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html": 1.9912,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html": 2.1919,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html": 2.043,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html": 1.4822,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.4564,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html": 1.0509,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.8427,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html": 1.2084,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.3454,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html": 2.0239,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 1.9917,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 2.3111,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html": 1.8697,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html": 1.9271,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html": 1.8967,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html": 2.0967,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html": 2.3902,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html": 2.4559,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html": 1.9061,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html": 2.5055,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html": 3.0251,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 1.5665,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 2.3068,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html": 3.5728,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html": 3.0682,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html": 3.2446,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html": 1.8298,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 1.8083,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 1.9769,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.7183,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html": 1.661,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 2.1955,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html": 2.4035,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html": 2.2879,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html": 2.6312,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html": 2.9764,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html": 2.289,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html": 2.1396,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 2.1046,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html": 2.0423,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 2.3977,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html": 1.934,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 1.5079,
-    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.566,
-    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.6032,
-    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4327,
-    "conformance2/textures/image/tex-2d-r16f-red-float.html": 0.553,
-    "conformance2/textures/image/tex-2d-r16f-red-half_float.html": 0.632,
-    "conformance2/textures/image/tex-2d-r32f-red-float.html": 0.5485,
-    "conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html": 0.8017,
-    "conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.5089,
-    "conformance2/textures/image/tex-2d-rg16f-rg-float.html": 0.6456,
-    "conformance2/textures/image/tex-2d-rg16f-rg-half_float.html": 0.394,
-    "conformance2/textures/image/tex-2d-rg32f-rg-float.html": 0.626,
-    "conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html": 0.5885,
-    "conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7348,
-    "conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6304,
-    "conformance2/textures/image/tex-2d-rgb16f-rgb-float.html": 0.5143,
-    "conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html": 0.5109,
-    "conformance2/textures/image/tex-2d-rgb32f-rgb-float.html": 0.7487,
-    "conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.6263,
-    "conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4634,
-    "conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.5739,
-    "conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.6388,
-    "conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.4393,
-    "conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5452,
-    "conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html": 0.5496,
-    "conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html": 0.6205,
-    "conformance2/textures/image/tex-2d-rgba16f-rgba-float.html": 0.5647,
-    "conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html": 0.5975,
-    "conformance2/textures/image/tex-2d-rgba32f-rgba-float.html": 0.6035,
-    "conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7384,
-    "conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5344,
-    "conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.3661,
-    "conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6451,
-    "conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.5573,
-    "conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.7768,
-    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.5002,
-    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.5536,
-    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5632,
-    "conformance2/textures/image/tex-3d-r16f-red-float.html": 0.7404,
-    "conformance2/textures/image/tex-3d-r16f-red-half_float.html": 0.5447,
-    "conformance2/textures/image/tex-3d-r32f-red-float.html": 0.5512,
-    "conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html": 0.5286,
-    "conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.5707,
-    "conformance2/textures/image/tex-3d-rg16f-rg-float.html": 0.48,
-    "conformance2/textures/image/tex-3d-rg16f-rg-half_float.html": 0.4719,
-    "conformance2/textures/image/tex-3d-rg32f-rg-float.html": 0.5104,
-    "conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html": 0.4954,
-    "conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.5055,
-    "conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.7105,
-    "conformance2/textures/image/tex-3d-rgb16f-rgb-float.html": 0.5572,
-    "conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html": 0.562,
-    "conformance2/textures/image/tex-3d-rgb32f-rgb-float.html": 0.6128,
-    "conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.4908,
-    "conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.6384,
-    "conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.5225,
-    "conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.7209,
-    "conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.4627,
-    "conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.7603,
-    "conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html": 0.4391,
-    "conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html": 0.494,
-    "conformance2/textures/image/tex-3d-rgba16f-rgba-float.html": 0.5092,
-    "conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html": 0.5203,
-    "conformance2/textures/image/tex-3d-rgba32f-rgba-float.html": 0.4949,
-    "conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.5565,
-    "conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.6024,
-    "conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.4708,
-    "conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.5119,
-    "conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.5124,
-    "conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.6944,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.6608,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.721,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.71,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html": 0.6693,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html": 0.7495,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html": 0.6843,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html": 0.6605,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.698,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html": 0.7012,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html": 0.6485,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html": 0.6936,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html": 0.6852,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.6646,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.7427,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html": 1.0919,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html": 0.6752,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html": 0.678,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html": 0.7818,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.6959,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.7426,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.6888,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html": 0.734,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6742,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html": 0.6757,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html": 0.6818,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html": 0.6934,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html": 0.5877,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html": 0.6998,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7057,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5334,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html": 0.7138,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6147,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7013,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.7149,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3839,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3499,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.3529,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html": 0.3436,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html": 0.3784,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html": 0.3682,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html": 0.3447,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.3543,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html": 0.3552,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html": 0.3253,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html": 0.339,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html": 0.3734,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.3377,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3177,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html": 0.3584,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html": 0.3462,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html": 0.3283,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html": 0.201,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3254,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.3179,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3435,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html": 0.3384,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4484,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html": 0.3301,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html": 0.3313,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html": 0.3324,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html": 0.3616,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html": 0.2423,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3437,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3733,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2267,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4342,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html": 0.3216,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.3147,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.0671,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.6581,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.3091,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html": 1.659,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html": 1.1743,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html": 1.44,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html": 1.0208,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.9613,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html": 1.288,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html": 1.4098,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html": 0.9305,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html": 0.9395,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.3978,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.1049,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html": 1.25,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html": 0.9793,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html": 1.0622,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.0592,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7963,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.952,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.9633,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 0.903,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.9765,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html": 1.1893,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.4362,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html": 0.8779,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html": 1.1633,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html": 1.1474,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 1.0294,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.8651,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.375,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.9552,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.2549,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.9349,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.5725,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.5774,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6307,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html": 0.5892,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html": 0.4724,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html": 0.61,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html": 0.7879,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4496,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html": 0.6403,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html": 0.5537,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html": 0.5353,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html": 0.7654,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.6295,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6385,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html": 0.6168,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html": 1.0349,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html": 0.6248,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 0.8637,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4872,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.5334,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5002,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 0.6175,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6024,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html": 0.5766,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html": 0.6215,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html": 0.66,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html": 0.5925,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html": 0.7305,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 0.6921,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.6071,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 0.5106,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.5476,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 0.558,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5728,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.7548,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.6228,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5886,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html": 0.7281,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html": 0.5425,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html": 0.6451,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html": 0.6208,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.6233,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html": 0.4823,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html": 0.5628,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html": 0.8121,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html": 0.5367,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7387,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4613,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html": 0.7591,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html": 0.8379,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html": 0.5003,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.5787,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.8097,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.6473,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5775,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.7478,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5518,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html": 0.4934,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html": 0.4767,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html": 0.5465,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html": 0.5559,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html": 0.5446,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.585,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.9892,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.4329,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.5083,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7907,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5227,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3534,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.6151,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.3377,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html": 0.5949,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html": 0.4298,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html": 0.4418,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html": 0.5005,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4104,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html": 0.3424,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html": 0.4383,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html": 0.3772,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html": 0.4693,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.4004,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4281,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html": 0.466,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html": 0.4759,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html": 0.5218,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.5622,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4294,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.3772,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3965,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.4076,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.479,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html": 0.4389,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html": 0.4252,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html": 0.4326,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html": 0.4071,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html": 0.4149,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.395,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3706,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.3773,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3945,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.4478,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4046,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.608,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.5388,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.7605,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html": 0.5832,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html": 0.5446,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html": 0.5918,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html": 0.7085,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.5227,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html": 0.7693,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html": 0.4915,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html": 0.6253,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html": 0.5781,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.5246,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.528,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html": 0.5491,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html": 0.5785,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html": 0.3536,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html": 0.4886,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.5224,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.73,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.4476,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html": 0.7688,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3935,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html": 0.7573,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html": 0.5379,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html": 0.5322,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html": 0.4868,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html": 0.5992,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html": 0.5347,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3583,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html": 0.5206,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.494,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html": 0.518,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5268,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3301,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3994,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.339,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html": 0.4015,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html": 0.3681,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html": 0.3092,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html": 0.3701,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4489,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html": 0.3129,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html": 0.2255,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html": 0.1916,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html": 0.385,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.4107,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4886,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html": 0.3799,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html": 0.3722,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html": 0.3106,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html": 0.4995,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.2152,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.2241,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.4966,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html": 0.3352,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3334,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html": 0.3713,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html": 0.4161,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html": 0.2662,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html": 0.3625,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html": 0.3699,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html": 0.4329,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4074,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html": 0.202,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4234,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html": 0.2295,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.3995,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.5033,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.5418,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.7653,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html": 0.533,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html": 0.5222,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html": 0.6477,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html": 0.4228,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.7526,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html": 0.5536,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html": 0.5488,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html": 0.4974,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html": 0.4776,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.5608,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6825,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html": 0.5352,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html": 0.7434,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html": 0.5905,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html": 0.5782,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.5034,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.5936,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5469,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html": 0.6149,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4942,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html": 0.562,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html": 0.6529,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html": 0.478,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html": 0.5724,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html": 0.4659,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html": 0.6601,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3942,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html": 0.4433,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6057,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7864,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5056,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3093,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3376,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6389,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html": 0.3342,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html": 0.3763,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html": 0.3673,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html": 0.3728,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4077,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html": 0.3069,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html": 0.4054,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html": 0.2396,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html": 0.3904,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.3987,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4081,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html": 0.4193,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html": 0.4126,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html": 0.3164,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html": 0.3606,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.5014,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.3406,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2697,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html": 0.5428,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4221,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html": 0.3639,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html": 0.2557,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html": 0.4655,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html": 0.2847,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html": 0.4168,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3639,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7402,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html": 0.3685,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4856,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html": 0.4601,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4833,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.6066,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.6981,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6309,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html": 0.602,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html": 0.6454,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html": 0.5375,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html": 0.5893,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.5087,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html": 0.7772,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html": 0.5706,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html": 0.7644,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html": 0.6013,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.5559,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5659,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html": 0.6808,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html": 0.7664,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html": 0.5502,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html": 0.7845,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.522,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.4674,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5623,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html": 0.5326,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5468,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html": 0.5942,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html": 0.5724,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html": 0.701,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html": 0.5899,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html": 0.5469,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html": 0.5446,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.513,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html": 0.5527,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6155,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html": 0.544,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.6719,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.5625,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.5617,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4874,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html": 0.5907,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html": 0.6838,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html": 0.543,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html": 0.5967,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.7182,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html": 0.5569,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html": 0.6873,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html": 0.7784,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html": 0.669,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.6877,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.9584,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html": 0.5884,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html": 0.5425,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html": 0.5775,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html": 0.5666,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.5407,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.4975,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5218,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html": 0.443,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5418,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html": 0.5928,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html": 0.5188,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html": 0.5822,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html": 0.5612,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html": 0.542,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html": 0.5597,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5034,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html": 0.6512,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.566,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html": 0.6401,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5852,
-    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.024,
-    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.1333,
-    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.9425,
-    "conformance2/textures/image_data/tex-2d-r16f-red-float.html": 1.4094,
-    "conformance2/textures/image_data/tex-2d-r16f-red-half_float.html": 0.8945,
-    "conformance2/textures/image_data/tex-2d-r32f-red-float.html": 0.8862,
-    "conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html": 0.8822,
-    "conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.3839,
-    "conformance2/textures/image_data/tex-2d-rg16f-rg-float.html": 1.1229,
-    "conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html": 1.0591,
-    "conformance2/textures/image_data/tex-2d-rg32f-rg-float.html": 1.0879,
-    "conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html": 0.8172,
-    "conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.9097,
-    "conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.9594,
-    "conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html": 0.8031,
-    "conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html": 0.9324,
-    "conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html": 0.7619,
-    "conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html": 0.9643,
-    "conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.8854,
-    "conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.3531,
-    "conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.8347,
-    "conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html": 1.0343,
-    "conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.8097,
-    "conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html": 0.8727,
-    "conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html": 0.7303,
-    "conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html": 0.8745,
-    "conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html": 1.1883,
-    "conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html": 0.9422,
-    "conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html": 0.9718,
-    "conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.2357,
-    "conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html": 0.9307,
-    "conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.8057,
-    "conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html": 0.8949,
-    "conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.8817,
-    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.8564,
-    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.7863,
-    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.0044,
-    "conformance2/textures/image_data/tex-3d-r16f-red-float.html": 0.8081,
-    "conformance2/textures/image_data/tex-3d-r16f-red-half_float.html": 0.9375,
-    "conformance2/textures/image_data/tex-3d-r32f-red-float.html": 1.1863,
-    "conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html": 0.775,
-    "conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.802,
-    "conformance2/textures/image_data/tex-3d-rg16f-rg-float.html": 1.1784,
-    "conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html": 1.0668,
-    "conformance2/textures/image_data/tex-3d-rg32f-rg-float.html": 1.0747,
-    "conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html": 1.1015,
-    "conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 1.2657,
-    "conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.9207,
-    "conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html": 0.7078,
-    "conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html": 0.736,
-    "conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html": 0.8162,
-    "conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html": 0.8444,
-    "conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.8859,
-    "conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.9869,
-    "conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.655,
-    "conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html": 0.9324,
-    "conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6492,
-    "conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html": 0.7506,
-    "conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html": 0.6679,
-    "conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html": 0.8879,
-    "conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html": 0.7438,
-    "conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html": 0.7939,
-    "conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html": 1.3664,
-    "conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.6492,
-    "conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html": 0.9925,
-    "conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 1.2631,
-    "conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html": 1.1432,
-    "conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.8995,
-    "conformance2/textures/misc/active-3d-texture-bug.html": 0.3479,
-    "conformance2/textures/misc/angle-stuck-depth-textures.html": 0.2961,
-    "conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html": 0.2153,
-    "conformance2/textures/misc/compressed-tex-from-pbo-crash.html": 0.1728,
-    "conformance2/textures/misc/compressed-tex-image.html": 0.2087,
-    "conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html": 0.2676,
-    "conformance2/textures/misc/copy-texture-cube-map-bug.html": 0.1238,
-    "conformance2/textures/misc/copy-texture-image-luma-format.html": 5.2303,
-    "conformance2/textures/misc/copy-texture-image-same-texture.html": 0.4701,
-    "conformance2/textures/misc/copy-texture-image-webgl-specific.html": 0.174,
-    "conformance2/textures/misc/copy-texture-image.html": 0.3414,
-    "conformance2/textures/misc/generate-mipmap-with-large-base-level.html": 0.1679,
-    "conformance2/textures/misc/gl-get-tex-parameter.html": 0.3247,
-    "conformance2/textures/misc/integer-cubemap-specification-order-bug.html": 0.8789,
-    "conformance2/textures/misc/integer-cubemap-texture-sampling.html": 1.8262,
-    "conformance2/textures/misc/mipmap-fbo.html": 0.1463,
-    "conformance2/textures/misc/npot-video-sizing.html": 0.2012,
-    "conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.2176,
-    "conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html": 0.1354,
-    "conformance2/textures/misc/tex-3d-size-limit.html": 0.1497,
-    "conformance2/textures/misc/tex-base-level-bug.html": 0.3366,
-    "conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html": 0.7423,
-    "conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html": 0.2021,
-    "conformance2/textures/misc/tex-image-with-bad-args.html": 0.307,
-    "conformance2/textures/misc/tex-image-with-different-data-source.html": 0.302,
-    "conformance2/textures/misc/tex-input-validation.html": 0.2467,
-    "conformance2/textures/misc/tex-mipmap-levels.html": 0.3703,
-    "conformance2/textures/misc/tex-new-formats.html": 0.7535,
-    "conformance2/textures/misc/tex-srgb-mipmap.html": 0.4628,
-    "conformance2/textures/misc/tex-storage-2d.html": 0.7276,
-    "conformance2/textures/misc/tex-storage-and-subimage-3d.html": 0.1825,
-    "conformance2/textures/misc/tex-storage-compressed-formats.html": 0.1996,
-    "conformance2/textures/misc/tex-subimage3d-canvas-bug.html": 0.3285,
-    "conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html": 0.2199,
-    "conformance2/textures/misc/tex-unpack-params-imagedata.html": 0.1119,
-    "conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html": 1.2721,
-    "conformance2/textures/misc/tex-unpack-params.html": 1.9597,
-    "conformance2/textures/misc/texel-fetch-undefined.html": 0.5037,
-    "conformance2/textures/misc/texture-npot.html": 0.3489,
-    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.2853,
-    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.388,
-    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5467,
-    "conformance2/textures/svg_image/tex-2d-r16f-red-float.html": 0.4303,
-    "conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html": 0.3198,
-    "conformance2/textures/svg_image/tex-2d-r32f-red-float.html": 0.5594,
-    "conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html": 0.419,
-    "conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.4232,
-    "conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html": 0.5069,
-    "conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html": 0.3671,
-    "conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html": 0.3987,
-    "conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html": 0.4087,
-    "conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.4392,
-    "conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3853,
-    "conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html": 0.3364,
-    "conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html": 0.3581,
-    "conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html": 0.4824,
-    "conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.4513,
-    "conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4428,
-    "conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.2223,
-    "conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3862,
-    "conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.3748,
-    "conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.425,
-    "conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html": 0.3541,
-    "conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html": 0.3219,
-    "conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html": 0.3951,
-    "conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html": 0.5686,
-    "conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html": 0.3974,
-    "conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.5008,
-    "conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3356,
-    "conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.3005,
-    "conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3863,
-    "conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.3886,
-    "conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4215,
-    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3386,
-    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3401,
-    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.2773,
-    "conformance2/textures/svg_image/tex-3d-r16f-red-float.html": 0.366,
-    "conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html": 0.1652,
-    "conformance2/textures/svg_image/tex-3d-r32f-red-float.html": 0.1912,
-    "conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html": 0.3238,
-    "conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.3219,
-    "conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html": 0.2118,
-    "conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html": 0.335,
-    "conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html": 0.2532,
-    "conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html": 0.3177,
-    "conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.3256,
-    "conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.1729,
-    "conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html": 0.3186,
-    "conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html": 0.3046,
-    "conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html": 0.1654,
-    "conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.3754,
-    "conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.2096,
-    "conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.2024,
-    "conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2793,
-    "conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.2972,
-    "conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.2463,
-    "conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html": 0.4776,
-    "conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html": 0.2977,
-    "conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html": 0.2081,
-    "conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html": 0.2512,
-    "conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html": 0.2719,
-    "conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3055,
-    "conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.2041,
-    "conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2378,
-    "conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4453,
-    "conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.3243,
-    "conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.1832,
-    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.5468,
-    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.6192,
-    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.7602,
-    "conformance2/textures/video/tex-2d-r16f-red-float.html": 0.7329,
-    "conformance2/textures/video/tex-2d-r16f-red-half_float.html": 0.9183,
-    "conformance2/textures/video/tex-2d-r32f-red-float.html": 0.7575,
-    "conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html": 0.695,
-    "conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.7561,
-    "conformance2/textures/video/tex-2d-rg16f-rg-float.html": 0.7418,
-    "conformance2/textures/video/tex-2d-rg16f-rg-half_float.html": 0.6759,
-    "conformance2/textures/video/tex-2d-rg32f-rg-float.html": 0.7666,
-    "conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html": 0.6911,
-    "conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7132,
-    "conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5436,
-    "conformance2/textures/video/tex-2d-rgb16f-rgb-float.html": 0.8752,
-    "conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html": 0.5339,
-    "conformance2/textures/video/tex-2d-rgb32f-rgb-float.html": 0.7535,
-    "conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html": 0.8516,
-    "conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7313,
-    "conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.0432,
-    "conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.8432,
-    "conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html": 1.0175,
-    "conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5916,
-    "conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html": 0.734,
-    "conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html": 0.4868,
-    "conformance2/textures/video/tex-2d-rgba16f-rgba-float.html": 0.8134,
-    "conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html": 0.5861,
-    "conformance2/textures/video/tex-2d-rgba32f-rgba-float.html": 0.9958,
-    "conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7184,
-    "conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.731,
-    "conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html": 0.7293,
-    "conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6152,
-    "conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html": 0.5606,
-    "conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.6635,
-    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.8797,
-    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 1.152,
-    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.0132,
-    "conformance2/textures/video/tex-3d-r16f-red-float.html": 1.2302,
-    "conformance2/textures/video/tex-3d-r16f-red-half_float.html": 1.059,
-    "conformance2/textures/video/tex-3d-r32f-red-float.html": 0.94,
-    "conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html": 0.9438,
-    "conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.8502,
-    "conformance2/textures/video/tex-3d-rg16f-rg-float.html": 0.9116,
-    "conformance2/textures/video/tex-3d-rg16f-rg-half_float.html": 1.0499,
-    "conformance2/textures/video/tex-3d-rg32f-rg-float.html": 0.9176,
-    "conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html": 0.8577,
-    "conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.9489,
-    "conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.7154,
-    "conformance2/textures/video/tex-3d-rgb16f-rgb-float.html": 0.9042,
-    "conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html": 0.7134,
-    "conformance2/textures/video/tex-3d-rgb32f-rgb-float.html": 0.9176,
-    "conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html": 0.8013,
-    "conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 1.0297,
-    "conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 1.1738,
-    "conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.9288,
-    "conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html": 0.8691,
-    "conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.9278,
-    "conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html": 0.9033,
-    "conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html": 1.2131,
-    "conformance2/textures/video/tex-3d-rgba16f-rgba-float.html": 0.8637,
-    "conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html": 1.1175,
-    "conformance2/textures/video/tex-3d-rgba32f-rgba-float.html": 0.903,
-    "conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html": 0.9912,
-    "conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7335,
-    "conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html": 0.7262,
-    "conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 1.0748,
-    "conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html": 1.032,
-    "conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.9275,
-    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.9371,
-    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 2.0092,
-    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.887,
-    "conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html": 1.5584,
-    "conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html": 1.6418,
-    "conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html": 1.8789,
-    "conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html": 1.3247,
-    "conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.4249,
-    "conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html": 1.7632,
-    "conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html": 1.6324,
-    "conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html": 1.9121,
-    "conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html": 1.9035,
-    "conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.9031,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.6477,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html": 1.8634,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html": 1.7342,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html": 1.8971,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.4328,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.3983,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.7364,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.5786,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 1.847,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.6319,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html": 1.7326,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.8312,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html": 1.8505,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html": 1.6606,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html": 1.6933,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 1.6648,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.6907,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.8493,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.4914,
-    "conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.3173,
-    "conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.8785,
-    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 5.8507,
-    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 5.8079,
-    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 5.5266,
-    "conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html": 5.5222,
-    "conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html": 5.5788,
-    "conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html": 5.5206,
-    "conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html": 5.4929,
-    "conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 5.5198,
-    "conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html": 5.9102,
-    "conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html": 5.5407,
-    "conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html": 5.7505,
-    "conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html": 5.6491,
-    "conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 5.4964,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 5.5039,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html": 5.5007,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html": 5.6694,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html": 5.9995,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 5.7181,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 5.8418,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 5.4312,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 5.4962,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 5.5367,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 5.7875,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html": 5.5009,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html": 5.7735,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html": 6.1147,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html": 5.4097,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html": 5.5841,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 5.4089,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 5.4493,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 5.791,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 5.6329,
-    "conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 5.8329,
-    "conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 5.7867,
-    "conformance2/transform_feedback/default_transform_feedback.html": 0.1927,
-    "conformance2/transform_feedback/non-existent-varying.html": 0.2208,
-    "conformance2/transform_feedback/same-buffer-two-binding-points.html": 0.195,
-    "conformance2/transform_feedback/simultaneous_binding.html": 0.2963,
-    "conformance2/transform_feedback/switching-objects.html": 0.4884,
-    "conformance2/transform_feedback/too-small-buffers.html": 0.3821,
-    "conformance2/transform_feedback/transform_feedback.html": 1.7058,
-    "conformance2/transform_feedback/two-unreferenced-varyings.html": 0.1291,
-    "conformance2/transform_feedback/unwritten-output-defaults-to-zero.html": 0.2266,
-    "conformance2/uniforms/dependent-buffer-change.html": 0.3887,
-    "conformance2/uniforms/draw-with-uniform-blocks.html": 0.2287,
-    "conformance2/uniforms/gl-uniform-arrays-sub-source.html": 1.1589,
-    "conformance2/uniforms/incompatible-texture-type-for-sampler.html": 6.2317,
-    "conformance2/uniforms/large-uniform-buffers.html": 0.4367,
-    "conformance2/uniforms/query-uniform-blocks-after-shader-detach.html": 0.4111,
-    "conformance2/uniforms/simple-buffer-change.html": 0.2327,
-    "conformance2/uniforms/uniform-blocks-with-arrays.html": 0.3635,
-    "conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html": 0.5086,
-    "conformance2/vertex_arrays/vertex-array-object.html": 0.5197,
-    "deqp/data/gles3/shaders/arrays.html": 5.4927,
-    "deqp/data/gles3/shaders/conditionals.html": 1.9135,
-    "deqp/data/gles3/shaders/constant_expressions.html": 2.2888,
-    "deqp/data/gles3/shaders/constants.html": 4.5781,
-    "deqp/data/gles3/shaders/conversions.html": 76.9115,
-    "deqp/data/gles3/shaders/declarations.html": 1.2863,
-    "deqp/data/gles3/shaders/fragdata.html": 0.4611,
-    "deqp/data/gles3/shaders/functions.html": 13.0018,
-    "deqp/data/gles3/shaders/invalid_texture_functions.html": 2.4362,
-    "deqp/data/gles3/shaders/keywords.html": 5.0786,
-    "deqp/data/gles3/shaders/linkage.html": 5.3696,
-    "deqp/data/gles3/shaders/negative.html": 0.7784,
-    "deqp/data/gles3/shaders/preprocessor.html": 16.3259,
-    "deqp/data/gles3/shaders/qualification_order.html": 2.1285,
-    "deqp/data/gles3/shaders/scoping.html": 2.4766,
-    "deqp/data/gles3/shaders/switch.html": 1.4503,
-    "deqp/data/gles3/shaders/swizzles.html": 38.9969,
-    "deqp/framework/opengl/simplereference/referencecontext.html": 4.5305,
-    "deqp/functional/gles3/attriblocation.html": 6.795,
-    "deqp/functional/gles3/booleanstatequery.html": 0.6217,
-    "deqp/functional/gles3/buffercopy.html": 8.0987,
-    "deqp/functional/gles3/bufferobjectquery.html": 0.4522,
-    "deqp/functional/gles3/clipping.html": 28.5123,
-    "deqp/functional/gles3/defaultvertexattribute.html": 11.0768,
-    "deqp/functional/gles3/draw/draw_arrays.html": 17.9266,
-    "deqp/functional/gles3/draw/draw_arrays_instanced.html": 21.656,
-    "deqp/functional/gles3/draw/draw_elements.html": 15.7873,
-    "deqp/functional/gles3/draw/draw_elements_instanced.html": 19.2682,
-    "deqp/functional/gles3/draw/draw_range_elements.html": 10.8046,
-    "deqp/functional/gles3/draw/instancing.html": 1.4597,
-    "deqp/functional/gles3/draw/random.html": 16.6638,
-    "deqp/functional/gles3/fbocolorbuffer/blend.html": 17.9141,
-    "deqp/functional/gles3/fbocolorbuffer/clear.html": 10.8813,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_00.html": 19.0756,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_01.html": 17.4809,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_02.html": 19.5968,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_03.html": 15.915,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_04.html": 18.5513,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_05.html": 16.1648,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html": 18.0498,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html": 15.6474,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html": 16.7224,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html": 16.0242,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html": 16.4917,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html": 14.0216,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_00.html": 15.8808,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_01.html": 16.4243,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_02.html": 15.4028,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_03.html": 15.7178,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_04.html": 17.011,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_05.html": 13.7105,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_00.html": 24.1638,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_01.html": 22.5316,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_02.html": 25.5942,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_03.html": 20.566,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_04.html": 24.7419,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_05.html": 20.6543,
-    "deqp/functional/gles3/fbocompleteness.html": 4.9495,
-    "deqp/functional/gles3/fbodepthbuffer.html": 25.2687,
-    "deqp/functional/gles3/fboinvalidate/default.html": 50.388,
-    "deqp/functional/gles3/fboinvalidate/format_00.html": 19.0347,
-    "deqp/functional/gles3/fboinvalidate/format_01.html": 18.8165,
-    "deqp/functional/gles3/fboinvalidate/format_02.html": 17.7652,
-    "deqp/functional/gles3/fboinvalidate/sub.html": 37.4744,
-    "deqp/functional/gles3/fboinvalidate/target.html": 44.0602,
-    "deqp/functional/gles3/fboinvalidate/whole.html": 40.1843,
-    "deqp/functional/gles3/fbomultisample.2_samples.html": 35.658,
-    "deqp/functional/gles3/fbomultisample.4_samples.html": 35.0021,
-    "deqp/functional/gles3/fbomultisample.8_samples.html": 37.8935,
-    "deqp/functional/gles3/fborender/recreate_color_00.html": 18.6776,
-    "deqp/functional/gles3/fborender/recreate_color_01.html": 17.5506,
-    "deqp/functional/gles3/fborender/recreate_color_02.html": 19.7001,
-    "deqp/functional/gles3/fborender/recreate_color_03.html": 18.7946,
-    "deqp/functional/gles3/fborender/recreate_color_04.html": 18.7604,
-    "deqp/functional/gles3/fborender/recreate_color_05.html": 17.2652,
-    "deqp/functional/gles3/fborender/recreate_color_06.html": 19.1802,
-    "deqp/functional/gles3/fborender/recreate_depth_stencil.html": 16.4255,
-    "deqp/functional/gles3/fborender/resize_00.html": 17.6163,
-    "deqp/functional/gles3/fborender/resize_01.html": 18.2086,
-    "deqp/functional/gles3/fborender/resize_02.html": 15.2165,
-    "deqp/functional/gles3/fborender/resize_03.html": 24.5897,
-    "deqp/functional/gles3/fborender/shared_colorbuffer_00.html": 27.6068,
-    "deqp/functional/gles3/fborender/shared_colorbuffer_01.html": 27.6173,
-    "deqp/functional/gles3/fborender/shared_colorbuffer_02.html": 31.9987,
-    "deqp/functional/gles3/fborender/shared_colorbuffer_clear.html": 9.7986,
-    "deqp/functional/gles3/fborender/shared_depth_stencil.html": 17.2185,
-    "deqp/functional/gles3/fborender/stencil_clear.html": 7.4134,
-    "deqp/functional/gles3/fbostatequery.html": 0.6883,
-    "deqp/functional/gles3/fbostencilbuffer.html": 19.7051,
-    "deqp/functional/gles3/floatstatequery.html": 0.9683,
-    "deqp/functional/gles3/fragdepth.html": 11.5636,
-    "deqp/functional/gles3/fragmentoutput/array.fixed.html": 8.2541,
-    "deqp/functional/gles3/fragmentoutput/array.float.html": 11.161,
-    "deqp/functional/gles3/fragmentoutput/array.int.html": 9.8795,
-    "deqp/functional/gles3/fragmentoutput/array.uint.html": 11.9009,
-    "deqp/functional/gles3/fragmentoutput/basic.fixed.html": 5.5374,
-    "deqp/functional/gles3/fragmentoutput/basic.float.html": 7.3116,
-    "deqp/functional/gles3/fragmentoutput/basic.int.html": 5.9783,
-    "deqp/functional/gles3/fragmentoutput/basic.uint.html": 6.5468,
-    "deqp/functional/gles3/fragmentoutput/random_00.html": 14.4779,
-    "deqp/functional/gles3/fragmentoutput/random_01.html": 14.8818,
-    "deqp/functional/gles3/fragmentoutput/random_02.html": 14.4162,
-    "deqp/functional/gles3/framebufferblit/conversion_00.html": 8.7919,
-    "deqp/functional/gles3/framebufferblit/conversion_01.html": 8.4789,
-    "deqp/functional/gles3/framebufferblit/conversion_02.html": 8.8428,
-    "deqp/functional/gles3/framebufferblit/conversion_03.html": 9.2038,
-    "deqp/functional/gles3/framebufferblit/conversion_04.html": 14.3149,
-    "deqp/functional/gles3/framebufferblit/conversion_05.html": 7.4194,
-    "deqp/functional/gles3/framebufferblit/conversion_06.html": 9.0632,
-    "deqp/functional/gles3/framebufferblit/conversion_07.html": 13.6706,
-    "deqp/functional/gles3/framebufferblit/conversion_08.html": 12.9684,
-    "deqp/functional/gles3/framebufferblit/conversion_09.html": 8.9008,
-    "deqp/functional/gles3/framebufferblit/conversion_10.html": 15.1128,
-    "deqp/functional/gles3/framebufferblit/conversion_11.html": 13.675,
-    "deqp/functional/gles3/framebufferblit/conversion_12.html": 13.2814,
-    "deqp/functional/gles3/framebufferblit/conversion_13.html": 12.9482,
-    "deqp/functional/gles3/framebufferblit/conversion_14.html": 9.1919,
-    "deqp/functional/gles3/framebufferblit/conversion_15.html": 9.7015,
-    "deqp/functional/gles3/framebufferblit/conversion_16.html": 7.9373,
-    "deqp/functional/gles3/framebufferblit/conversion_17.html": 8.7763,
-    "deqp/functional/gles3/framebufferblit/conversion_18.html": 14.1758,
-    "deqp/functional/gles3/framebufferblit/conversion_19.html": 8.492,
-    "deqp/functional/gles3/framebufferblit/conversion_20.html": 8.759,
-    "deqp/functional/gles3/framebufferblit/conversion_21.html": 8.0001,
-    "deqp/functional/gles3/framebufferblit/conversion_22.html": 8.6829,
-    "deqp/functional/gles3/framebufferblit/conversion_23.html": 8.0737,
-    "deqp/functional/gles3/framebufferblit/conversion_24.html": 8.5056,
-    "deqp/functional/gles3/framebufferblit/conversion_25.html": 14.5723,
-    "deqp/functional/gles3/framebufferblit/conversion_26.html": 8.6924,
-    "deqp/functional/gles3/framebufferblit/conversion_27.html": 9.6397,
-    "deqp/functional/gles3/framebufferblit/conversion_28.html": 14.798,
-    "deqp/functional/gles3/framebufferblit/conversion_29.html": 13.6466,
-    "deqp/functional/gles3/framebufferblit/conversion_30.html": 13.2891,
-    "deqp/functional/gles3/framebufferblit/conversion_31.html": 13.7105,
-    "deqp/functional/gles3/framebufferblit/conversion_32.html": 13.2879,
-    "deqp/functional/gles3/framebufferblit/conversion_33.html": 12.8226,
-    "deqp/functional/gles3/framebufferblit/conversion_34.html": 13.5944,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_00.html": 17.5814,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_01.html": 17.847,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_02.html": 13.8203,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_03.html": 19.0266,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_04.html": 31.903,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_05.html": 16.622,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_06.html": 20.7838,
-    "deqp/functional/gles3/framebufferblit/depth_stencil.html": 33.8569,
-    "deqp/functional/gles3/framebufferblit/rect_00.html": 9.9852,
-    "deqp/functional/gles3/framebufferblit/rect_01.html": 10.5017,
-    "deqp/functional/gles3/framebufferblit/rect_02.html": 8.0013,
-    "deqp/functional/gles3/framebufferblit/rect_03.html": 5.6803,
-    "deqp/functional/gles3/framebufferblit/rect_04.html": 5.3912,
-    "deqp/functional/gles3/framebufferblit/rect_05.html": 0.6351,
-    "deqp/functional/gles3/framebufferblit/rect_06.html": 0.6364,
-    "deqp/functional/gles3/indexedstatequery.html": 0.314,
-    "deqp/functional/gles3/instancedrendering.html": 33.277,
-    "deqp/functional/gles3/integerstatequery.html": 1.8028,
-    "deqp/functional/gles3/internalformatquery.html": 0.5024,
-    "deqp/functional/gles3/lifetime.html": 1.5059,
-    "deqp/functional/gles3/multisample.html": 124.583,
-    "deqp/functional/gles3/negativebufferapi.html": 0.6649,
-    "deqp/functional/gles3/negativefragmentapi.html": 0.4248,
-    "deqp/functional/gles3/negativeshaderapi.html": 0.8676,
-    "deqp/functional/gles3/negativestateapi.html": 0.6304,
-    "deqp/functional/gles3/negativetextureapi.html": 1.0559,
-    "deqp/functional/gles3/negativevertexarrayapi.html": 0.9471,
-    "deqp/functional/gles3/occlusionquery_conservative.html": 19.5033,
-    "deqp/functional/gles3/occlusionquery_strict.html": 18.5944,
-    "deqp/functional/gles3/pixelbufferobject.html": 7.0603,
-    "deqp/functional/gles3/primitiverestart/00.html": 6.0853,
-    "deqp/functional/gles3/primitiverestart/01.html": 6.7324,
-    "deqp/functional/gles3/primitiverestart/02.html": 6.7785,
-    "deqp/functional/gles3/primitiverestart/03.html": 6.7211,
-    "deqp/functional/gles3/primitiverestart/04.html": 6.2866,
-    "deqp/functional/gles3/primitiverestart/05.html": 6.8685,
-    "deqp/functional/gles3/primitiverestart/06.html": 5.8894,
-    "deqp/functional/gles3/primitiverestart/07.html": 6.3586,
-    "deqp/functional/gles3/rasterizerdiscard.html": 8.5007,
-    "deqp/functional/gles3/rbostatequery.html": 0.3948,
-    "deqp/functional/gles3/readpixel.html": 2.2063,
-    "deqp/functional/gles3/samplerobject.html": 5.1514,
-    "deqp/functional/gles3/samplerstatequery.html": 0.6203,
-    "deqp/functional/gles3/shaderapi.html": 0.8315,
-    "deqp/functional/gles3/shaderbuiltinvar.html": 9.6097,
-    "deqp/functional/gles3/shadercommonfunction.html": 14.0613,
-    "deqp/functional/gles3/shaderderivate_dfdx.html": 12.4368,
-    "deqp/functional/gles3/shaderderivate_dfdy.html": 13.0936,
-    "deqp/functional/gles3/shaderderivate_fwidth.html": 12.8459,
-    "deqp/functional/gles3/shaderindexing/mat_00.html": 49.4006,
-    "deqp/functional/gles3/shaderindexing/mat_01.html": 49.196,
-    "deqp/functional/gles3/shaderindexing/mat_02.html": 64.6569,
-    "deqp/functional/gles3/shaderindexing/tmp.html": 61.8934,
-    "deqp/functional/gles3/shaderindexing/uniform.html": 17.0099,
-    "deqp/functional/gles3/shaderindexing/varying.html": 31.7124,
-    "deqp/functional/gles3/shaderindexing/vec2.html": 38.0852,
-    "deqp/functional/gles3/shaderindexing/vec3.html": 34.9643,
-    "deqp/functional/gles3/shaderindexing/vec4.html": 35.7014,
-    "deqp/functional/gles3/shaderloop_do_while.html": 85.9848,
-    "deqp/functional/gles3/shaderloop_for.html": 84.5642,
-    "deqp/functional/gles3/shaderloop_while.html": 89.8627,
-    "deqp/functional/gles3/shadermatrix/add_assign.html": 49.7048,
-    "deqp/functional/gles3/shadermatrix/add_const.html": 78.6233,
-    "deqp/functional/gles3/shadermatrix/add_dynamic.html": 79.9774,
-    "deqp/functional/gles3/shadermatrix/add_uniform.html": 77.2481,
-    "deqp/functional/gles3/shadermatrix/determinant.html": 14.73,
-    "deqp/functional/gles3/shadermatrix/div_assign.html": 44.0458,
-    "deqp/functional/gles3/shadermatrix/div_const.html": 79.1737,
-    "deqp/functional/gles3/shadermatrix/div_dynamic.html": 103.3187,
-    "deqp/functional/gles3/shadermatrix/div_uniform.html": 79.5751,
-    "deqp/functional/gles3/shadermatrix/inverse.html": 31.2532,
-    "deqp/functional/gles3/shadermatrix/matrixcompmult.html": 41.4608,
-    "deqp/functional/gles3/shadermatrix/mul_assign.html": 18.7602,
-    "deqp/functional/gles3/shadermatrix/mul_const_highp.html": 74.5858,
-    "deqp/functional/gles3/shadermatrix/mul_const_lowp.html": 77.8448,
-    "deqp/functional/gles3/shadermatrix/mul_const_mediump.html": 75.1778,
-    "deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html": 79.1787,
-    "deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html": 76.6234,
-    "deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html": 79.1611,
-    "deqp/functional/gles3/shadermatrix/mul_uniform_highp.html": 76.3603,
-    "deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html": 79.7511,
-    "deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html": 83.8969,
-    "deqp/functional/gles3/shadermatrix/negation.html": 43.5772,
-    "deqp/functional/gles3/shadermatrix/outerproduct.html": 46.6459,
-    "deqp/functional/gles3/shadermatrix/post_decrement.html": 41.9801,
-    "deqp/functional/gles3/shadermatrix/post_increment.html": 40.4847,
-    "deqp/functional/gles3/shadermatrix/pre_decrement.html": 51.4306,
-    "deqp/functional/gles3/shadermatrix/pre_increment.html": 50.498,
-    "deqp/functional/gles3/shadermatrix/sub_assign.html": 45.8503,
-    "deqp/functional/gles3/shadermatrix/sub_const.html": 79.7309,
-    "deqp/functional/gles3/shadermatrix/sub_dynamic.html": 80.5905,
-    "deqp/functional/gles3/shadermatrix/sub_uniform.html": 81.0267,
-    "deqp/functional/gles3/shadermatrix/transpose.html": 52.799,
-    "deqp/functional/gles3/shadermatrix/unary_addition.html": 36.4138,
-    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html": 59.3128,
-    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html": 34.0124,
-    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html": 36.9459,
-    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html": 28.6354,
-    "deqp/functional/gles3/shaderoperator/binary_operator_00.html": 136.6353,
-    "deqp/functional/gles3/shaderoperator/binary_operator_01.html": 135.2298,
-    "deqp/functional/gles3/shaderoperator/binary_operator_02.html": 83.5236,
-    "deqp/functional/gles3/shaderoperator/binary_operator_03.html": 88.5133,
-    "deqp/functional/gles3/shaderoperator/binary_operator_04.html": 113.9627,
-    "deqp/functional/gles3/shaderoperator/binary_operator_05.html": 97.1943,
-    "deqp/functional/gles3/shaderoperator/binary_operator_06.html": 96.2103,
-    "deqp/functional/gles3/shaderoperator/binary_operator_07.html": 65.625,
-    "deqp/functional/gles3/shaderoperator/binary_operator_08.html": 62.5231,
-    "deqp/functional/gles3/shaderoperator/binary_operator_09.html": 108.295,
-    "deqp/functional/gles3/shaderoperator/binary_operator_10.html": 95.5139,
-    "deqp/functional/gles3/shaderoperator/binary_operator_11.html": 96.7594,
-    "deqp/functional/gles3/shaderoperator/binary_operator_12.html": 65.0465,
-    "deqp/functional/gles3/shaderoperator/binary_operator_13.html": 63.3077,
-    "deqp/functional/gles3/shaderoperator/binary_operator_14.html": 106.8526,
-    "deqp/functional/gles3/shaderoperator/binary_operator_15.html": 110.7028,
-    "deqp/functional/gles3/shaderoperator/bool_compare.html": 20.2399,
-    "deqp/functional/gles3/shaderoperator/common_functions_00.html": 61.3537,
-    "deqp/functional/gles3/shaderoperator/common_functions_01.html": 64.3813,
-    "deqp/functional/gles3/shaderoperator/common_functions_02.html": 60.0378,
-    "deqp/functional/gles3/shaderoperator/common_functions_03.html": 72.9309,
-    "deqp/functional/gles3/shaderoperator/common_functions_04.html": 59.2245,
-    "deqp/functional/gles3/shaderoperator/common_functions_05.html": 57.8672,
-    "deqp/functional/gles3/shaderoperator/common_functions_06.html": 47.6832,
-    "deqp/functional/gles3/shaderoperator/exponential.html": 55.5937,
-    "deqp/functional/gles3/shaderoperator/float_compare.html": 74.2315,
-    "deqp/functional/gles3/shaderoperator/geometric.html": 58.638,
-    "deqp/functional/gles3/shaderoperator/int_compare.html": 56.4135,
-    "deqp/functional/gles3/shaderoperator/selection.html": 45.3551,
-    "deqp/functional/gles3/shaderoperator/sequence.html": 32.8332,
-    "deqp/functional/gles3/shaderoperator/unary_operator_00.html": 79.4715,
-    "deqp/functional/gles3/shaderoperator/unary_operator_01.html": 135.5306,
-    "deqp/functional/gles3/shaderoperator/unary_operator_02.html": 146.889,
-    "deqp/functional/gles3/shaderpackingfunction.html": 1.6265,
-    "deqp/functional/gles3/shaderprecision_float.html": 18.4849,
-    "deqp/functional/gles3/shaderprecision_int.html": 16.3971,
-    "deqp/functional/gles3/shaderprecision_uint.html": 17.625,
-    "deqp/functional/gles3/shaderstatequery.html": 1.2495,
-    "deqp/functional/gles3/shaderstruct.html": 47.5794,
-    "deqp/functional/gles3/shaderswitch.html": 53.5557,
-    "deqp/functional/gles3/shadertexturefunction/texelfetch.html": 22.0863,
-    "deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html": 18.6804,
-    "deqp/functional/gles3/shadertexturefunction/texture.html": 36.3278,
-    "deqp/functional/gles3/shadertexturefunction/texturegrad.html": 24.878,
-    "deqp/functional/gles3/shadertexturefunction/texturegradoffset.html": 18.2487,
-    "deqp/functional/gles3/shadertexturefunction/texturelod.html": 24.4717,
-    "deqp/functional/gles3/shadertexturefunction/texturelodoffset.html": 17.7382,
-    "deqp/functional/gles3/shadertexturefunction/textureoffset.html": 23.4754,
-    "deqp/functional/gles3/shadertexturefunction/textureproj.html": 28.0846,
-    "deqp/functional/gles3/shadertexturefunction/textureprojgrad.html": 18.1498,
-    "deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html": 17.9773,
-    "deqp/functional/gles3/shadertexturefunction/textureprojlod.html": 17.7233,
-    "deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html": 17.3851,
-    "deqp/functional/gles3/shadertexturefunction/textureprojoffset.html": 24.0382,
-    "deqp/functional/gles3/shadertexturefunction/texturesize.html": 26.6967,
-    "deqp/functional/gles3/stringquery.html": 0.3897,
-    "deqp/functional/gles3/sync.html": 4.1107,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html": 8.5834,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html": 9.1263,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html": 8.9467,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html": 8.6149,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html": 9.1643,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html": 10.0702,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_00.html": 6.4877,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_01.html": 5.8089,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_02.html": 5.4398,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_03.html": 5.322,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_04.html": 5.0164,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_05.html": 5.4166,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_06.html": 4.8317,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_07.html": 4.7443,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_08.html": 5.3703,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_09.html": 5.009,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html": 4.5537,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html": 4.394,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html": 5.4652,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html": 4.702,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html": 11.6098,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_00.html": 5.0141,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_01.html": 4.5311,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_02.html": 5.3016,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_03.html": 4.7318,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_04.html": 4.6039,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_05.html": 4.8183,
-    "deqp/functional/gles3/texturefiltering/2d_formats_00.html": 3.6842,
-    "deqp/functional/gles3/texturefiltering/2d_formats_01.html": 3.6888,
-    "deqp/functional/gles3/texturefiltering/2d_formats_02.html": 3.3238,
-    "deqp/functional/gles3/texturefiltering/2d_formats_03.html": 3.1258,
-    "deqp/functional/gles3/texturefiltering/2d_formats_04.html": 3.3602,
-    "deqp/functional/gles3/texturefiltering/2d_formats_05.html": 3.0803,
-    "deqp/functional/gles3/texturefiltering/2d_formats_06.html": 3.5269,
-    "deqp/functional/gles3/texturefiltering/2d_formats_07.html": 2.7984,
-    "deqp/functional/gles3/texturefiltering/2d_formats_08.html": 3.0363,
-    "deqp/functional/gles3/texturefiltering/2d_formats_09.html": 3.3043,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_00.html": 2.7906,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_01.html": 2.7475,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_02.html": 3.1445,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_03.html": 2.8623,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_04.html": 3.4561,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_05.html": 2.9431,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_00.html": 5.2043,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_01.html": 5.1744,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_02.html": 4.3593,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_03.html": 5.8217,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_04.html": 5.6526,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_05.html": 5.1207,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_06.html": 5.107,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_07.html": 5.2652,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_08.html": 5.1948,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_09.html": 5.1084,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_10.html": 5.3732,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_11.html": 5.0923,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_12.html": 5.424,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_13.html": 4.6909,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_14.html": 4.6595,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_15.html": 5.5386,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_16.html": 5.185,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_17.html": 5.3338,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_18.html": 5.4961,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_19.html": 5.2288,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_20.html": 5.5089,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_21.html": 5.031,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_22.html": 5.0257,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_23.html": 5.1342,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_24.html": 17.8891,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_25.html": 17.8943,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_26.html": 17.8644,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_27.html": 19.0879,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_28.html": 16.5173,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_29.html": 17.9685,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_30.html": 17.6767,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_31.html": 18.2394,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_32.html": 19.3553,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_33.html": 17.8837,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_34.html": 17.6733,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_35.html": 21.0721,
-    "deqp/functional/gles3/texturefiltering/3d_formats_00.html": 11.8232,
-    "deqp/functional/gles3/texturefiltering/3d_formats_01.html": 11.207,
-    "deqp/functional/gles3/texturefiltering/3d_formats_02.html": 10.3023,
-    "deqp/functional/gles3/texturefiltering/3d_formats_03.html": 10.3933,
-    "deqp/functional/gles3/texturefiltering/3d_formats_04.html": 11.2353,
-    "deqp/functional/gles3/texturefiltering/3d_formats_05.html": 9.7258,
-    "deqp/functional/gles3/texturefiltering/3d_formats_06.html": 10.1946,
-    "deqp/functional/gles3/texturefiltering/3d_formats_07.html": 10.3245,
-    "deqp/functional/gles3/texturefiltering/3d_formats_08.html": 10.2871,
-    "deqp/functional/gles3/texturefiltering/3d_formats_09.html": 10.7378,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_00.html": 11.2046,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_01.html": 9.9377,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_02.html": 10.9346,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_03.html": 8.7039,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_04.html": 10.5352,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_00.html": 12.5676,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_01.html": 14.5286,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_02.html": 18.0429,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_03.html": 17.9496,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_04.html": 21.2414,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_05.html": 30.1802,
-    "deqp/functional/gles3/texturefiltering/cube_formats_00.html": 11.5897,
-    "deqp/functional/gles3/texturefiltering/cube_formats_01.html": 11.3714,
-    "deqp/functional/gles3/texturefiltering/cube_formats_02.html": 10.8074,
-    "deqp/functional/gles3/texturefiltering/cube_formats_03.html": 10.2115,
-    "deqp/functional/gles3/texturefiltering/cube_formats_04.html": 10.3566,
-    "deqp/functional/gles3/texturefiltering/cube_formats_05.html": 10.5751,
-    "deqp/functional/gles3/texturefiltering/cube_formats_06.html": 10.1203,
-    "deqp/functional/gles3/texturefiltering/cube_formats_07.html": 9.6884,
-    "deqp/functional/gles3/texturefiltering/cube_formats_08.html": 10.4015,
-    "deqp/functional/gles3/texturefiltering/cube_formats_09.html": 10.545,
-    "deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html": 5.0039,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_00.html": 6.2294,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_01.html": 10.6372,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_02.html": 10.714,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_03.html": 6.4021,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_04.html": 9.5121,
-    "deqp/functional/gles3/textureformat/compressed_2d.html": 0.2955,
-    "deqp/functional/gles3/textureformat/compressed_cube.html": 0.4107,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html": 7.0192,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html": 7.1213,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html": 7.2762,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html": 7.1596,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html": 7.7528,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html": 7.9818,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html": 8.0483,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html": 8.1379,
-    "deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html": 3.9409,
-    "deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html": 4.0437,
-    "deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html": 3.7625,
-    "deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html": 3.9912,
-    "deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html": 4.4982,
-    "deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html": 4.7777,
-    "deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html": 4.3043,
-    "deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html": 4.4934,
-    "deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html": 5.4088,
-    "deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html": 5.2636,
-    "deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html": 5.3548,
-    "deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html": 5.0417,
-    "deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html": 8.5549,
-    "deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html": 9.0955,
-    "deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html": 8.578,
-    "deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html": 7.7276,
-    "deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html": 7.481,
-    "deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html": 7.0738,
-    "deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html": 6.6389,
-    "deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html": 6.9461,
-    "deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html": 7.8896,
-    "deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html": 7.1927,
-    "deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html": 6.887,
-    "deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html": 7.1318,
-    "deqp/functional/gles3/textureformat/sized_depth_stencil.html": 8.2313,
-    "deqp/functional/gles3/textureformat/unsized_2d.html": 8.3554,
-    "deqp/functional/gles3/textureformat/unsized_2d_array.html": 7.4249,
-    "deqp/functional/gles3/textureformat/unsized_3d.html": 8.348,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_always.html": 3.9449,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_equal.html": 6.091,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_greater.html": 5.8138,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html": 5.9025,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_less.html": 6.2214,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html": 5.6489,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html": 3.9133,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html": 6.2243,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html": 7.6809,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html": 7.8445,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html": 7.6333,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html": 7.9095,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html": 3.9598,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html": 6.5712,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html": 3.6855,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html": 6.0514,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html": 5.9761,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html": 5.9189,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html": 6.0687,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html": 6.2073,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html": 3.6778,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html": 5.8374,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_never.html": 3.8011,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html": 6.1843,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_always.html": 3.8806,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html": 3.6448,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html": 3.8739,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html": 3.5777,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_less.html": 3.7137,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html": 3.762,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html": 3.7378,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html": 5.5599,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html": 5.4236,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html": 5.0052,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html": 5.1198,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html": 5.1839,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html": 3.7029,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html": 5.699,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html": 3.9615,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html": 5.5891,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html": 5.4922,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html": 5.2629,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html": 5.3344,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html": 5.6799,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html": 4.0206,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html": 5.6047,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_never.html": 3.6358,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html": 3.6196,
-    "deqp/functional/gles3/textureshadow/2d_linear_always.html": 3.7865,
-    "deqp/functional/gles3/textureshadow/2d_linear_equal.html": 5.7318,
-    "deqp/functional/gles3/textureshadow/2d_linear_greater.html": 5.4551,
-    "deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html": 5.3471,
-    "deqp/functional/gles3/textureshadow/2d_linear_less.html": 5.7111,
-    "deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html": 5.5004,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html": 3.5964,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html": 6.9353,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html": 6.9942,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html": 7.7348,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html": 7.3648,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html": 7.1089,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html": 3.481,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html": 7.2594,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html": 3.1999,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html": 5.7794,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html": 5.5348,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html": 5.1075,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html": 5.595,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html": 5.6685,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html": 3.4772,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html": 5.4298,
-    "deqp/functional/gles3/textureshadow/2d_linear_never.html": 3.259,
-    "deqp/functional/gles3/textureshadow/2d_linear_not_equal.html": 5.778,
-    "deqp/functional/gles3/textureshadow/2d_nearest_always.html": 3.3017,
-    "deqp/functional/gles3/textureshadow/2d_nearest_equal.html": 3.6071,
-    "deqp/functional/gles3/textureshadow/2d_nearest_greater.html": 3.236,
-    "deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html": 3.2892,
-    "deqp/functional/gles3/textureshadow/2d_nearest_less.html": 3.5107,
-    "deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html": 3.3408,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html": 3.6836,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html": 6.0373,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html": 4.9147,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html": 5.7789,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html": 5.9373,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html": 5.1398,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html": 3.4318,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html": 5.9988,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html": 3.547,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html": 5.2248,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html": 5.1707,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html": 4.5961,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html": 4.7484,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html": 5.2838,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html": 3.5632,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html": 5.1316,
-    "deqp/functional/gles3/textureshadow/2d_nearest_never.html": 3.1541,
-    "deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html": 3.3208,
-    "deqp/functional/gles3/textureshadow/cube_linear_always.html": 6.1478,
-    "deqp/functional/gles3/textureshadow/cube_linear_equal.html": 8.2039,
-    "deqp/functional/gles3/textureshadow/cube_linear_greater.html": 7.9345,
-    "deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html": 9.4329,
-    "deqp/functional/gles3/textureshadow/cube_linear_less.html": 9.1556,
-    "deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html": 8.1812,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html": 6.4151,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html": 10.9826,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html": 10.6756,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html": 10.73,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html": 10.8095,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html": 10.8706,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html": 6.3635,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html": 10.872,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html": 6.1382,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html": 8.7132,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html": 8.7623,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html": 9.6489,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html": 9.1515,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html": 9.5091,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html": 6.0431,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html": 8.8329,
-    "deqp/functional/gles3/textureshadow/cube_linear_never.html": 6.2148,
-    "deqp/functional/gles3/textureshadow/cube_linear_not_equal.html": 8.8146,
-    "deqp/functional/gles3/textureshadow/cube_nearest_always.html": 6.1353,
-    "deqp/functional/gles3/textureshadow/cube_nearest_equal.html": 6.8405,
-    "deqp/functional/gles3/textureshadow/cube_nearest_greater.html": 6.5643,
-    "deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html": 7.1791,
-    "deqp/functional/gles3/textureshadow/cube_nearest_less.html": 7.7329,
-    "deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html": 7.1486,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html": 7.0025,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html": 11.555,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html": 9.5731,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html": 10.0319,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html": 9.955,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html": 9.9701,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html": 6.8861,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html": 10.786,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html": 6.5262,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html": 8.7924,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html": 8.8138,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html": 9.3621,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html": 8.7568,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html": 8.5149,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html": 6.7117,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html": 8.8778,
-    "deqp/functional/gles3/textureshadow/cube_nearest_never.html": 6.2355,
-    "deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html": 7.4378,
-    "deqp/functional/gles3/texturespecification/basic_copyteximage2d.html": 30.372,
-    "deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html": 31.2791,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html": 11.2391,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html": 11.968,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html": 21.9158,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html": 20.903,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html": 21.9492,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html": 22.2901,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html": 19.0708,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html": 11.9435,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html": 9.7265,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html": 9.4667,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html": 8.5368,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html": 8.2829,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html": 7.7255,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html": 7.5678,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html": 7.2318,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html": 11.9923,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html": 10.272,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html": 9.7785,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html": 21.9277,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html": 21.0692,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html": 21.917,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html": 22.5583,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html": 18.266,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html": 10.2702,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html": 8.9075,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html": 9.7994,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html": 8.549,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html": 8.2435,
-    "deqp/functional/gles3/texturespecification/random_teximage2d_2d.html": 7.744,
-    "deqp/functional/gles3/texturespecification/random_teximage2d_cube.html": 29.9238,
-    "deqp/functional/gles3/texturespecification/teximage2d_align.html": 24.1882,
-    "deqp/functional/gles3/texturespecification/teximage2d_depth.html": 4.5094,
-    "deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html": 5.4586,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html": 6.5144,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html": 7.2888,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html": 15.4128,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html": 17.7247,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html": 15.6067,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html": 15.8486,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html": 16.7187,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html": 6.1065,
-    "deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html": 3.8678,
-    "deqp/functional/gles3/texturespecification/teximage3d_depth.html": 5.3977,
-    "deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html": 4.7055,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html": 6.5899,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html": 7.4512,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html": 6.2602,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html": 7.2646,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html": 4.2194,
-    "deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html": 4.6177,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html": 10.5246,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html": 9.0155,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html": 9.8367,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html": 18.3651,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html": 19.3377,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html": 17.3963,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html": 18.3248,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html": 17.0192,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html": 15.1049,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_size.html": 14.8131,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html": 8.7266,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html": 6.9242,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html": 6.651,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html": 10.1953,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html": 9.8527,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html": 10.9833,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html": 10.6222,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html": 3.8225,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_size.html": 6.3556,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_align.html": 40.4617,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_depth.html": 3.7857,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html": 11.2365,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html": 8.2379,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html": 7.9177,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html": 17.1927,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html": 17.251,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html": 19.0907,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html": 17.4239,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html": 17.0116,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html": 10.8445,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html": 5.5711,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_depth.html": 5.6469,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html": 9.146,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html": 9.6661,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html": 10.6188,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html": 11.5742,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html": 4.215,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html": 5.4319,
-    "deqp/functional/gles3/texturestatequery.html": 2.0966,
-    "deqp/functional/gles3/texturewrap/eac_r11_npot.html": 0.3073,
-    "deqp/functional/gles3/texturewrap/eac_r11_pot.html": 0.3193,
-    "deqp/functional/gles3/texturewrap/eac_rg11_npot.html": 0.2999,
-    "deqp/functional/gles3/texturewrap/eac_rg11_pot.html": 0.3101,
-    "deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html": 0.2643,
-    "deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html": 0.341,
-    "deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html": 0.282,
-    "deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html": 0.3605,
-    "deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html": 0.4081,
-    "deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html": 0.2934,
-    "deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html": 0.2731,
-    "deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html": 0.2536,
-    "deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html": 0.3028,
-    "deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html": 0.3057,
-    "deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html": 0.3136,
-    "deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html": 0.5252,
-    "deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html": 0.2592,
-    "deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html": 0.2931,
-    "deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html": 0.2835,
-    "deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html": 0.2692,
-    "deqp/functional/gles3/texturewrap/rgba8_npot.html": 9.9138,
-    "deqp/functional/gles3/texturewrap/rgba8_pot.html": 9.7601,
-    "deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html": 2.0453,
-    "deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html": 2.1438,
-    "deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html": 2.7311,
-    "deqp/functional/gles3/transformfeedback/array_element_separate_lines.html": 2.0179,
-    "deqp/functional/gles3/transformfeedback/array_element_separate_points.html": 2.5684,
-    "deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html": 2.1849,
-    "deqp/functional/gles3/transformfeedback/array_interleaved_lines.html": 2.2803,
-    "deqp/functional/gles3/transformfeedback/array_interleaved_points.html": 2.9673,
-    "deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html": 2.5862,
-    "deqp/functional/gles3/transformfeedback/array_separate_lines.html": 2.0994,
-    "deqp/functional/gles3/transformfeedback/array_separate_points.html": 2.3726,
-    "deqp/functional/gles3/transformfeedback/array_separate_triangles.html": 2.6257,
-    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html": 35.3355,
-    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html": 33.2702,
-    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html": 34.3474,
-    "deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html": 21.4536,
-    "deqp/functional/gles3/transformfeedback/basic_types_separate_points.html": 22.8867,
-    "deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html": 22.3308,
-    "deqp/functional/gles3/transformfeedback/interpolation_centroid.html": 10.6019,
-    "deqp/functional/gles3/transformfeedback/interpolation_flat.html": 11.6008,
-    "deqp/functional/gles3/transformfeedback/interpolation_smooth.html": 10.9689,
-    "deqp/functional/gles3/transformfeedback/point_size.html": 4.1158,
-    "deqp/functional/gles3/transformfeedback/position.html": 4.2093,
-    "deqp/functional/gles3/transformfeedback/random_interleaved_lines.html": 6.5097,
-    "deqp/functional/gles3/transformfeedback/random_interleaved_points.html": 6.3677,
-    "deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html": 5.4392,
-    "deqp/functional/gles3/transformfeedback/random_separate_lines.html": 6.3537,
-    "deqp/functional/gles3/transformfeedback/random_separate_points.html": 6.7831,
-    "deqp/functional/gles3/transformfeedback/random_separate_triangles.html": 6.3406,
-    "deqp/functional/gles3/uniformapi/info_query.html": 15.116,
-    "deqp/functional/gles3/uniformapi/random.html": 6.9361,
-    "deqp/functional/gles3/uniformapi/value_assigned.html": 38.1869,
-    "deqp/functional/gles3/uniformapi/value_initial.html": 16.0341,
-    "deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html": 6.4611,
-    "deqp/functional/gles3/uniformbuffers/multi_basic_types.html": 1.4128,
-    "deqp/functional/gles3/uniformbuffers/multi_nested_struct.html": 2.0127,
-    "deqp/functional/gles3/uniformbuffers/random.html": 20.022,
-    "deqp/functional/gles3/uniformbuffers/single_basic_array.html": 6.9601,
-    "deqp/functional/gles3/uniformbuffers/single_basic_type.html": 15.4633,
-    "deqp/functional/gles3/uniformbuffers/single_nested_struct.html": 1.9016,
-    "deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html": 1.9859,
-    "deqp/functional/gles3/uniformbuffers/single_struct.html": 1.3369,
-    "deqp/functional/gles3/uniformbuffers/single_struct_array.html": 3.2203,
-    "deqp/functional/gles3/vertexarrayobject.html": 2.4155,
-    "deqp/functional/gles3/vertexarrays/multiple_attributes.count.html": 20.3589,
-    "deqp/functional/gles3/vertexarrays/multiple_attributes.output.html": 57.9566,
-    "deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html": 5.0709,
-    "deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html": 46.0135,
-    "deqp/functional/gles3/vertexarrays/single_attribute.first.html": 54.381,
-    "deqp/functional/gles3/vertexarrays/single_attribute.normalize.html": 36.0473,
-    "deqp/functional/gles3/vertexarrays/single_attribute.offset.html": 40.3913,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html": 27.5109,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html": 18.266,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html": 20.1996,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html": 25.683,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html": 11.3981,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html": 25.7891,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html": 25.8998,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html": 25.4544,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html": 8.2816,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html": 27.3873,
-    "deqp/functional/gles3/vertexarrays/single_attribute.stride.html": 30.5422,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html": 18.9174,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html": 19.8194,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html": 19.6885,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html": 19.6368,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html": 20.4549,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html": 22.1891,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html": 20.9253,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html": 20.0795,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html": 19.8545
+    "WebglExtension_EXT_color_buffer_float": 0.3506,
+    "WebglExtension_EXT_color_buffer_half_float": 0.4301,
+    "WebglExtension_EXT_disjoint_timer_query_webgl2": 0.2434,
+    "WebglExtension_EXT_float_blend": 0.3705,
+    "WebglExtension_EXT_texture_compression_bptc": 0.3507,
+    "WebglExtension_EXT_texture_compression_rgtc": 0.39,
+    "WebglExtension_EXT_texture_filter_anisotropic": 0.4496,
+    "WebglExtension_EXT_texture_norm16": 0.2246,
+    "WebglExtension_KHR_parallel_shader_compile": 0.2398,
+    "WebglExtension_OES_draw_buffers_indexed": 0.4721,
+    "WebglExtension_OES_texture_float_linear": 0.4541,
+    "WebglExtension_OVR_multiview2": 0.3915,
+    "WebglExtension_TestCoverage": 0.2344,
+    "WebglExtension_WEBGL_clip_cull_distance": 0.4539,
+    "WebglExtension_WEBGL_compressed_texture_astc": 0,
+    "WebglExtension_WEBGL_compressed_texture_etc": 0,
+    "WebglExtension_WEBGL_compressed_texture_etc1": 0,
+    "WebglExtension_WEBGL_compressed_texture_pvrtc": 0,
+    "WebglExtension_WEBGL_compressed_texture_s3tc": 0.4521,
+    "WebglExtension_WEBGL_compressed_texture_s3tc_srgb": 0,
+    "WebglExtension_WEBGL_debug_renderer_info": 0.2034,
+    "WebglExtension_WEBGL_debug_shaders": 0.2142,
+    "WebglExtension_WEBGL_draw_instanced_base_vertex_base_instance": 0.4884,
+    "WebglExtension_WEBGL_lose_context": 0.2885,
+    "WebglExtension_WEBGL_multi_draw": 0.4667,
+    "WebglExtension_WEBGL_multi_draw_instanced_base_vertex_base_instance": 0.3995,
+    "WebglExtension_WEBGL_provoking_vertex": 0.3753,
+    "WebglExtension_WEBGL_video_texture": 0.4354,
+    "WebglExtension_WEBGL_webcodecs_video_frame": 0,
+    "conformance/attribs/gl-bindAttribLocation-aliasing.html": 0.697,
+    "conformance/attribs/gl-bindAttribLocation-matrix.html": 0.6593,
+    "conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html": 0.5465,
+    "conformance/attribs/gl-bindAttribLocation-repeated.html": 0.494,
+    "conformance/attribs/gl-disabled-vertex-attrib-update.html": 0.2877,
+    "conformance/attribs/gl-disabled-vertex-attrib.html": 0.9816,
+    "conformance/attribs/gl-enable-vertex-attrib.html": 0.3063,
+    "conformance/attribs/gl-matrix-attributes.html": 0.7804,
+    "conformance/attribs/gl-vertex-attrib-context-switch.html": 0.6309,
+    "conformance/attribs/gl-vertex-attrib-render.html": 0.5328,
+    "conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html": 0.6088,
+    "conformance/attribs/gl-vertex-attrib-zero-issues.html": 0.3476,
+    "conformance/attribs/gl-vertexattribpointer-offsets.html": 0.5969,
+    "conformance/attribs/gl-vertexattribpointer.html": 1.0182,
+    "conformance/buffers/buffer-bind-test.html": 0.5039,
+    "conformance/buffers/buffer-data-and-buffer-sub-data.html": 0.4613,
+    "conformance/buffers/buffer-data-array-buffer-delete.html": 2.4641,
+    "conformance/buffers/buffer-data-dynamic-delay.html": 0.5879,
+    "conformance/buffers/buffer-uninitialized.html": 0.5662,
+    "conformance/buffers/element-array-buffer-delete-recreate.html": 0.5182,
+    "conformance/buffers/index-validation-copies-indices.html": 0.5454,
+    "conformance/buffers/index-validation-crash-with-buffer-sub-data.html": 0.2717,
+    "conformance/buffers/index-validation-large-buffer.html": 0.4679,
+    "conformance/buffers/index-validation-verifies-too-many-indices.html": 0.4745,
+    "conformance/buffers/index-validation-with-resized-buffer.html": 0.4903,
+    "conformance/buffers/index-validation.html": 0.5413,
+    "conformance/buffers/vertex-buffer-updated-after-draw.html": 0.6156,
+    "conformance/canvas/buffer-offscreen-test.html": 0.709,
+    "conformance/canvas/buffer-preserve-test.html": 1.3639,
+    "conformance/canvas/canvas-test.html": 0.4399,
+    "conformance/canvas/canvas-zero-size.html": 0.2125,
+    "conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html": 0.8347,
+    "conformance/canvas/draw-webgl-to-canvas-test.html": 0.54,
+    "conformance/canvas/drawingbuffer-hd-dpi-test.html": 0.5826,
+    "conformance/canvas/drawingbuffer-static-canvas-test.html": 0.5161,
+    "conformance/canvas/drawingbuffer-test.html": 0.5119,
+    "conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html": 0.5176,
+    "conformance/canvas/framebuffer-bindings-unaffected-on-resize.html": 0.3008,
+    "conformance/canvas/rapid-resizing.html": 2.4449,
+    "conformance/canvas/render-after-resize-test.html": 0.6531,
+    "conformance/canvas/texture-bindings-unaffected-on-resize.html": 0.6293,
+    "conformance/canvas/to-data-url-after-composite.html": 0.5405,
+    "conformance/canvas/to-data-url-test.html": 0.7818,
+    "conformance/canvas/viewport-unchanged-upon-resize.html": 0.5371,
+    "conformance/canvas/webgl-to-2d-canvas.html": 1.1584,
+    "conformance/context/context-attribute-preserve-drawing-buffer-antialias.html": 0.7281,
+    "conformance/context/context-attribute-preserve-drawing-buffer.html": 0.9849,
+    "conformance/context/context-attributes-alpha-depth-stencil-antialias.html": 0.8028,
+    "conformance/context/context-creation-and-destruction.html": 0.7817,
+    "conformance/context/context-creation.html": 0.8082,
+    "conformance/context/context-eviction-with-garbage-collection.html": 1.4078,
+    "conformance/context/context-hidden-alpha.html": 0.5026,
+    "conformance/context/context-lost-restored.html": 0.7437,
+    "conformance/context/context-lost.html": 0.476,
+    "conformance/context/context-no-alpha-fbo-with-alpha.html": 0.1613,
+    "conformance/context/context-release-upon-reload.html": 1.4991,
+    "conformance/context/context-release-with-workers.html": 1.8,
+    "conformance/context/context-size-change.html": 0.5114,
+    "conformance/context/deleted-object-behavior.html": 0.4703,
+    "conformance/context/incorrect-context-object-behaviour.html": 0.5107,
+    "conformance/context/premultiplyalpha-test.html": 1.3049,
+    "conformance/context/user-defined-properties-on-context.html": 0.2393,
+    "conformance/context/zero-sized-canvas.html": 0.299,
+    "conformance/extensions/ext-color-buffer-half-float.html": 0.4662,
+    "conformance/extensions/ext-disjoint-timer-query.html": 0.0514,
+    "conformance/extensions/ext-float-blend.html": 0.296,
+    "conformance/extensions/ext-texture-compression-bptc.html": 0.5652,
+    "conformance/extensions/ext-texture-compression-rgtc.html": 0.5561,
+    "conformance/extensions/ext-texture-filter-anisotropic.html": 0.2548,
+    "conformance/extensions/get-extension.html": 0.3155,
+    "conformance/extensions/khr-parallel-shader-compile.html": 10.2361,
+    "conformance/extensions/oes-texture-float-linear.html": 0.3691,
+    "conformance/extensions/s3tc-and-rgtc.html": 1.6042,
+    "conformance/extensions/webgl-compressed-texture-astc.html": 0.2463,
+    "conformance/extensions/webgl-compressed-texture-etc.html": 0.2624,
+    "conformance/extensions/webgl-compressed-texture-etc1.html": 0.2441,
+    "conformance/extensions/webgl-compressed-texture-pvrtc.html": 0.1331,
+    "conformance/extensions/webgl-compressed-texture-s3tc-srgb.html": 1.3209,
+    "conformance/extensions/webgl-compressed-texture-size-limit.html": 3.0427,
+    "conformance/extensions/webgl-debug-renderer-info.html": 0.4708,
+    "conformance/extensions/webgl-debug-shaders.html": 0.4823,
+    "conformance/extensions/webgl-multi-draw.html": 2.9712,
+    "conformance/glsl/bugs/angle-ambiguous-function-call.html": 0.3104,
+    "conformance/glsl/bugs/angle-constructor-invalid-parameters.html": 0.2338,
+    "conformance/glsl/bugs/angle-d3d11-compiler-error.html": 0.2361,
+    "conformance/glsl/bugs/angle-dx-variable-bug.html": 0.0668,
+    "conformance/glsl/bugs/array-of-struct-with-int-first-position.html": 0.1974,
+    "conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html": 0.3503,
+    "conformance/glsl/bugs/bool-type-cast-bug-int-float.html": 0.1355,
+    "conformance/glsl/bugs/character-set.html": 0.1609,
+    "conformance/glsl/bugs/compare-loop-index-to-uniform.html": 0.3645,
+    "conformance/glsl/bugs/complex-glsl-does-not-crash.html": 1.1319,
+    "conformance/glsl/bugs/compound-assignment-type-combination.html": 1.4538,
+    "conformance/glsl/bugs/conditional-discard-in-loop.html": 0.2297,
+    "conformance/glsl/bugs/conditional-discard-optimization.html": 0.5336,
+    "conformance/glsl/bugs/conditional-texture-fetch.html": 0.0978,
+    "conformance/glsl/bugs/constant-precision-qualifier.html": 0.5398,
+    "conformance/glsl/bugs/floor-div-cos-should-not-truncate.html": 0.2294,
+    "conformance/glsl/bugs/floored-division-accuracy.html": 0.2256,
+    "conformance/glsl/bugs/fragcoord-linking-bug.html": 0.2752,
+    "conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html": 0.3956,
+    "conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html": 0.2211,
+    "conformance/glsl/bugs/if-return-and-elseif.html": 0.2172,
+    "conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html": 0.2715,
+    "conformance/glsl/bugs/init-array-with-loop.html": 0.35,
+    "conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html": 0.0842,
+    "conformance/glsl/bugs/logic-inside-block-without-braces.html": 0.3021,
+    "conformance/glsl/bugs/long-expressions-should-not-crash.html": 0.6303,
+    "conformance/glsl/bugs/loop-if-loop-gradient.html": 0.3007,
+    "conformance/glsl/bugs/modulo-arithmetic-accuracy.html": 0.0796,
+    "conformance/glsl/bugs/multiplication-assignment.html": 0.0769,
+    "conformance/glsl/bugs/nested-functions-should-not-crash.html": 0.571,
+    "conformance/glsl/bugs/nested-loops-with-break-and-continue.html": 0.536,
+    "conformance/glsl/bugs/nested-sequence-operator.html": 0.1289,
+    "conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html": 0.4379,
+    "conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html": 0.1226,
+    "conformance/glsl/bugs/qualcomm-crash.html": 0.2976,
+    "conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html": 0.1106,
+    "conformance/glsl/bugs/sampler-array-struct-function-arg.html": 0.4369,
+    "conformance/glsl/bugs/sampler-array-using-loop-index.html": 0.1287,
+    "conformance/glsl/bugs/sampler-struct-function-arg.html": 0.2894,
+    "conformance/glsl/bugs/sequence-operator-evaluation-order.html": 0.2416,
+    "conformance/glsl/bugs/sketchfab-lighting-shader-crash.html": 0.1192,
+    "conformance/glsl/bugs/struct-constructor-highp-bug.html": 0.1006,
+    "conformance/glsl/bugs/struct-with-single-member-constructor.html": 0.1862,
+    "conformance/glsl/bugs/temp-expressions-should-not-crash.html": 0.9189,
+    "conformance/glsl/bugs/unary-minus-operator-float-bug.html": 0.2662,
+    "conformance/glsl/bugs/undefined-index-should-not-crash.html": 0.1154,
+    "conformance/glsl/bugs/uniforms-should-not-lose-values.html": 0.1007,
+    "conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html": 0.2366,
+    "conformance/glsl/bugs/vector-matrix-constructor-scalarization.html": 0.1193,
+    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html": 0.3458,
+    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html": 0.3219,
+    "conformance/glsl/constructors/glsl-construct-bvec2.html": 0.3936,
+    "conformance/glsl/constructors/glsl-construct-bvec3.html": 0.5907,
+    "conformance/glsl/constructors/glsl-construct-bvec4.html": 0.7384,
+    "conformance/glsl/constructors/glsl-construct-ivec2.html": 0.365,
+    "conformance/glsl/constructors/glsl-construct-ivec3.html": 0.4326,
+    "conformance/glsl/constructors/glsl-construct-ivec4.html": 0.6415,
+    "conformance/glsl/constructors/glsl-construct-mat2.html": 0.5644,
+    "conformance/glsl/constructors/glsl-construct-mat3.html": 0.3385,
+    "conformance/glsl/constructors/glsl-construct-mat4.html": 0.3558,
+    "conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html": 0.2948,
+    "conformance/glsl/constructors/glsl-construct-vec-mat-index.html": 0.3429,
+    "conformance/glsl/constructors/glsl-construct-vec2.html": 0.4837,
+    "conformance/glsl/constructors/glsl-construct-vec3.html": 0.5625,
+    "conformance/glsl/constructors/glsl-construct-vec4.html": 0.6575,
+    "conformance/glsl/functions/glsl-function-abs.html": 0.4388,
+    "conformance/glsl/functions/glsl-function-acos.html": 0.43,
+    "conformance/glsl/functions/glsl-function-asin.html": 0.2359,
+    "conformance/glsl/functions/glsl-function-atan-xy.html": 0.5807,
+    "conformance/glsl/functions/glsl-function-atan.html": 0.4722,
+    "conformance/glsl/functions/glsl-function-ceil.html": 0.7793,
+    "conformance/glsl/functions/glsl-function-clamp-float.html": 0.4888,
+    "conformance/glsl/functions/glsl-function-clamp-gentype.html": 0.5562,
+    "conformance/glsl/functions/glsl-function-cos.html": 0.6571,
+    "conformance/glsl/functions/glsl-function-cross.html": 0.421,
+    "conformance/glsl/functions/glsl-function-distance.html": 0.5187,
+    "conformance/glsl/functions/glsl-function-dot.html": 0.4787,
+    "conformance/glsl/functions/glsl-function-faceforward.html": 0.5054,
+    "conformance/glsl/functions/glsl-function-floor.html": 0.6147,
+    "conformance/glsl/functions/glsl-function-fract.html": 0.6327,
+    "conformance/glsl/functions/glsl-function-length.html": 0.4694,
+    "conformance/glsl/functions/glsl-function-max-float.html": 0.4938,
+    "conformance/glsl/functions/glsl-function-max-gentype.html": 0.4848,
+    "conformance/glsl/functions/glsl-function-min-float.html": 0.5028,
+    "conformance/glsl/functions/glsl-function-min-gentype.html": 0.6033,
+    "conformance/glsl/functions/glsl-function-mix-float.html": 0.4939,
+    "conformance/glsl/functions/glsl-function-mix-gentype.html": 0.4876,
+    "conformance/glsl/functions/glsl-function-mod-float.html": 0.4824,
+    "conformance/glsl/functions/glsl-function-mod-gentype.html": 0.4546,
+    "conformance/glsl/functions/glsl-function-normalize.html": 0.4712,
+    "conformance/glsl/functions/glsl-function-reflect.html": 0.3264,
+    "conformance/glsl/functions/glsl-function-sign.html": 0.3,
+    "conformance/glsl/functions/glsl-function-sin.html": 0.4459,
+    "conformance/glsl/functions/glsl-function-smoothstep-float.html": 0.4917,
+    "conformance/glsl/functions/glsl-function-smoothstep-gentype.html": 0.7743,
+    "conformance/glsl/functions/glsl-function-step-float.html": 0.6089,
+    "conformance/glsl/functions/glsl-function-step-gentype.html": 0.4758,
+    "conformance/glsl/functions/glsl-function.html": 0.4783,
+    "conformance/glsl/implicit/add_int_float.vert.html": 0.2669,
+    "conformance/glsl/implicit/add_int_mat2.vert.html": 0.2605,
+    "conformance/glsl/implicit/add_int_mat3.vert.html": 0.2652,
+    "conformance/glsl/implicit/add_int_mat4.vert.html": 0.263,
+    "conformance/glsl/implicit/add_int_vec2.vert.html": 0.2478,
+    "conformance/glsl/implicit/add_int_vec3.vert.html": 0.2655,
+    "conformance/glsl/implicit/add_int_vec4.vert.html": 0.2883,
+    "conformance/glsl/implicit/add_ivec2_vec2.vert.html": 0.0615,
+    "conformance/glsl/implicit/add_ivec3_vec3.vert.html": 0.1119,
+    "conformance/glsl/implicit/add_ivec4_vec4.vert.html": 0.2163,
+    "conformance/glsl/implicit/assign_int_to_float.vert.html": 0.291,
+    "conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html": 0.2615,
+    "conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html": 0.2078,
+    "conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html": 0.1217,
+    "conformance/glsl/implicit/construct_struct.vert.html": 0.2259,
+    "conformance/glsl/implicit/divide_int_float.vert.html": 0.1622,
+    "conformance/glsl/implicit/divide_int_mat2.vert.html": 0.1615,
+    "conformance/glsl/implicit/divide_int_mat3.vert.html": 0.2294,
+    "conformance/glsl/implicit/divide_int_mat4.vert.html": 0.1649,
+    "conformance/glsl/implicit/divide_int_vec2.vert.html": 0.2589,
+    "conformance/glsl/implicit/divide_int_vec3.vert.html": 0.1635,
+    "conformance/glsl/implicit/divide_int_vec4.vert.html": 0.3054,
+    "conformance/glsl/implicit/divide_ivec2_vec2.vert.html": 0.1165,
+    "conformance/glsl/implicit/divide_ivec3_vec3.vert.html": 0.2023,
+    "conformance/glsl/implicit/divide_ivec4_vec4.vert.html": 0.0683,
+    "conformance/glsl/implicit/equal_int_float.vert.html": 0.1721,
+    "conformance/glsl/implicit/equal_ivec2_vec2.vert.html": 0.1592,
+    "conformance/glsl/implicit/equal_ivec3_vec3.vert.html": 0.2772,
+    "conformance/glsl/implicit/equal_ivec4_vec4.vert.html": 0.273,
+    "conformance/glsl/implicit/function_int_float.vert.html": 0.2785,
+    "conformance/glsl/implicit/function_ivec2_vec2.vert.html": 0.1552,
+    "conformance/glsl/implicit/function_ivec3_vec3.vert.html": 0.4606,
+    "conformance/glsl/implicit/function_ivec4_vec4.vert.html": 0.0665,
+    "conformance/glsl/implicit/greater_than.vert.html": 0.1966,
+    "conformance/glsl/implicit/greater_than_equal.vert.html": 0.2251,
+    "conformance/glsl/implicit/less_than.vert.html": 0.2081,
+    "conformance/glsl/implicit/less_than_equal.vert.html": 0.081,
+    "conformance/glsl/implicit/multiply_int_float.vert.html": 0.2356,
+    "conformance/glsl/implicit/multiply_int_mat2.vert.html": 0.122,
+    "conformance/glsl/implicit/multiply_int_mat3.vert.html": 0.0544,
+    "conformance/glsl/implicit/multiply_int_mat4.vert.html": 0.0526,
+    "conformance/glsl/implicit/multiply_int_vec2.vert.html": 0.1193,
+    "conformance/glsl/implicit/multiply_int_vec3.vert.html": 0.059,
+    "conformance/glsl/implicit/multiply_int_vec4.vert.html": 0.2752,
+    "conformance/glsl/implicit/multiply_ivec2_vec2.vert.html": 0.1202,
+    "conformance/glsl/implicit/multiply_ivec3_vec3.vert.html": 0.0559,
+    "conformance/glsl/implicit/multiply_ivec4_vec4.vert.html": 0.3125,
+    "conformance/glsl/implicit/not_equal_int_float.vert.html": 0.1128,
+    "conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html": 0.2567,
+    "conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html": 0.1284,
+    "conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html": 0.2954,
+    "conformance/glsl/implicit/subtract_int_float.vert.html": 0.0581,
+    "conformance/glsl/implicit/subtract_int_mat2.vert.html": 0.1556,
+    "conformance/glsl/implicit/subtract_int_mat3.vert.html": 0.3234,
+    "conformance/glsl/implicit/subtract_int_mat4.vert.html": 0.0597,
+    "conformance/glsl/implicit/subtract_int_vec2.vert.html": 0.2806,
+    "conformance/glsl/implicit/subtract_int_vec3.vert.html": 0.073,
+    "conformance/glsl/implicit/subtract_int_vec4.vert.html": 0.2632,
+    "conformance/glsl/implicit/subtract_ivec2_vec2.vert.html": 0.2174,
+    "conformance/glsl/implicit/subtract_ivec3_vec3.vert.html": 0.0541,
+    "conformance/glsl/implicit/subtract_ivec4_vec4.vert.html": 0.1102,
+    "conformance/glsl/implicit/ternary_int_float.vert.html": 0.2593,
+    "conformance/glsl/implicit/ternary_ivec2_vec2.vert.html": 0.29,
+    "conformance/glsl/implicit/ternary_ivec3_vec3.vert.html": 0.0671,
+    "conformance/glsl/implicit/ternary_ivec4_vec4.vert.html": 0.0646,
+    "conformance/glsl/literals/float_literal.vert.html": 0.0661,
+    "conformance/glsl/literals/literal_precision.html": 0.3058,
+    "conformance/glsl/literals/overflow_leak.vert.html": 0.3187,
+    "conformance/glsl/matrices/glsl-mat3-construction.html": 0.4076,
+    "conformance/glsl/matrices/glsl-mat4-to-mat3.html": 0.3172,
+    "conformance/glsl/matrices/matrix-compound-multiply.html": 0.4242,
+    "conformance/glsl/misc/boolean_precision.html": 0.1065,
+    "conformance/glsl/misc/const-variable-initialization.html": 1.0281,
+    "conformance/glsl/misc/embedded-struct-definitions-forbidden.html": 0.211,
+    "conformance/glsl/misc/empty-declaration.html": 0.3278,
+    "conformance/glsl/misc/empty_main.vert.html": 0.0862,
+    "conformance/glsl/misc/expression-list-in-declarator-initializer.html": 0.6064,
+    "conformance/glsl/misc/fragcolor-fragdata-invariant.html": 0.0573,
+    "conformance/glsl/misc/gl_position_unset.vert.html": 0.2746,
+    "conformance/glsl/misc/global-variable-init.html": 0.1131,
+    "conformance/glsl/misc/glsl-function-nodes.html": 0.5484,
+    "conformance/glsl/misc/glsl-long-variable-names.html": 0.1102,
+    "conformance/glsl/misc/glsl-vertex-branch.html": 0.5249,
+    "conformance/glsl/misc/large-loop-compile.html": 0.63,
+    "conformance/glsl/misc/local-variable-shadowing-outer-function.html": 0.2166,
+    "conformance/glsl/misc/non-ascii-comments.vert.html": 0.0588,
+    "conformance/glsl/misc/non-ascii.vert.html": 0.3047,
+    "conformance/glsl/misc/re-compile-re-link.html": 0.1227,
+    "conformance/glsl/misc/sampler-operand.html": 0.287,
+    "conformance/glsl/misc/sequence-operator-returns-constant.html": 0.2841,
+    "conformance/glsl/misc/shader-precision-format-obeyed.html": 0.0854,
+    "conformance/glsl/misc/shader-struct-scope.html": 0.3028,
+    "conformance/glsl/misc/shader-uniform-packing-restrictions.html": 1.7473,
+    "conformance/glsl/misc/shader-varying-packing-restrictions.html": 0.2874,
+    "conformance/glsl/misc/shader-with-256-character-define.html": 0.1693,
+    "conformance/glsl/misc/shader-with-256-character-identifier.frag.html": 0.0848,
+    "conformance/glsl/misc/shader-with-_webgl-identifier.vert.html": 0.0523,
+    "conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html": 0.156,
+    "conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html": 0.0721,
+    "conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html": 0.234,
+    "conformance/glsl/misc/shader-with-array-of-structs-uniform.html": 0.1009,
+    "conformance/glsl/misc/shader-with-attrib-array.vert.html": 0.2748,
+    "conformance/glsl/misc/shader-with-attrib-struct.vert.html": 0.0709,
+    "conformance/glsl/misc/shader-with-clipvertex.vert.html": 0.0711,
+    "conformance/glsl/misc/shader-with-comma-assignment.html": 0.1118,
+    "conformance/glsl/misc/shader-with-comma-conditional-assignment.html": 0.1728,
+    "conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html": 0.0598,
+    "conformance/glsl/misc/shader-with-conditional-scoping-negative.html": 0.2339,
+    "conformance/glsl/misc/shader-with-conditional-scoping.html": 0.2653,
+    "conformance/glsl/misc/shader-with-default-precision.frag.html": 0.0938,
+    "conformance/glsl/misc/shader-with-default-precision.vert.html": 0.2107,
+    "conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html": 0.1019,
+    "conformance/glsl/misc/shader-with-dfdx.frag.html": 0.253,
+    "conformance/glsl/misc/shader-with-do-loop.html": 0.2236,
+    "conformance/glsl/misc/shader-with-error-directive.html": 0.0667,
+    "conformance/glsl/misc/shader-with-explicit-int-cast.vert.html": 0.053,
+    "conformance/glsl/misc/shader-with-float-return-value.frag.html": 0.0812,
+    "conformance/glsl/misc/shader-with-for-loop.html": 0.0729,
+    "conformance/glsl/misc/shader-with-for-scoping.html": 0.2071,
+    "conformance/glsl/misc/shader-with-frag-depth.frag.html": 0.0593,
+    "conformance/glsl/misc/shader-with-function-recursion.frag.html": 0.22,
+    "conformance/glsl/misc/shader-with-function-scoped-struct.html": 0.0563,
+    "conformance/glsl/misc/shader-with-functional-scoping.html": 0.0563,
+    "conformance/glsl/misc/shader-with-glcolor.vert.html": 0.0498,
+    "conformance/glsl/misc/shader-with-gles-1.frag.html": 0.2834,
+    "conformance/glsl/misc/shader-with-gles-symbol.frag.html": 0.1104,
+    "conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html": 0.0823,
+    "conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html": 0.0572,
+    "conformance/glsl/misc/shader-with-hex-int-constant-macro.html": 0.2155,
+    "conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html": 0.265,
+    "conformance/glsl/misc/shader-with-include.vert.html": 0.0625,
+    "conformance/glsl/misc/shader-with-int-return-value.frag.html": 0.0642,
+    "conformance/glsl/misc/shader-with-invalid-identifier.frag.html": 0.2132,
+    "conformance/glsl/misc/shader-with-ivec2-return-value.frag.html": 0.0968,
+    "conformance/glsl/misc/shader-with-ivec3-return-value.frag.html": 0.0642,
+    "conformance/glsl/misc/shader-with-ivec4-return-value.frag.html": 0.0694,
+    "conformance/glsl/misc/shader-with-limited-indexing.frag.html": 0.1598,
+    "conformance/glsl/misc/shader-with-long-line.html": 0.2956,
+    "conformance/glsl/misc/shader-with-non-ascii-error.frag.html": 0.2092,
+    "conformance/glsl/misc/shader-with-non-reserved-words-1-of-8.html": 2.6158,
+    "conformance/glsl/misc/shader-with-non-reserved-words-2-of-8.html": 2.5113,
+    "conformance/glsl/misc/shader-with-non-reserved-words-3-of-8.html": 2.4598,
+    "conformance/glsl/misc/shader-with-non-reserved-words-4-of-8.html": 2.1899,
+    "conformance/glsl/misc/shader-with-non-reserved-words-5-of-8.html": 0.9989,
+    "conformance/glsl/misc/shader-with-non-reserved-words-6-of-8.html": 1.542,
+    "conformance/glsl/misc/shader-with-non-reserved-words-7-of-8.html": 2.4016,
+    "conformance/glsl/misc/shader-with-non-reserved-words-8-of-8.html": 1.0081,
+    "conformance/glsl/misc/shader-with-precision.frag.html": 0.2208,
+    "conformance/glsl/misc/shader-with-preprocessor-whitespace.html": 0.1645,
+    "conformance/glsl/misc/shader-with-quoted-error.frag.html": 0.0561,
+    "conformance/glsl/misc/shader-with-reserved-words.html": 2.5819,
+    "conformance/glsl/misc/shader-with-short-circuiting-operators.html": 0.3757,
+    "conformance/glsl/misc/shader-with-similar-uniform-array-names.html": 0.332,
+    "conformance/glsl/misc/shader-with-too-many-uniforms.html": 0.4238,
+    "conformance/glsl/misc/shader-with-two-initializer-types.html": 0.1016,
+    "conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html": 0.0548,
+    "conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html": 0.2492,
+    "conformance/glsl/misc/shader-with-vec2-return-value.frag.html": 0.2827,
+    "conformance/glsl/misc/shader-with-vec3-return-value.frag.html": 0.3131,
+    "conformance/glsl/misc/shader-with-vec4-return-value.frag.html": 0.2753,
+    "conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html": 0.1274,
+    "conformance/glsl/misc/shader-with-version-100.frag.html": 0.2125,
+    "conformance/glsl/misc/shader-with-version-100.vert.html": 0.1238,
+    "conformance/glsl/misc/shader-with-version-120.vert.html": 0.1456,
+    "conformance/glsl/misc/shader-with-version-130.vert.html": 0.0511,
+    "conformance/glsl/misc/shader-with-webgl-identifier.vert.html": 0.06,
+    "conformance/glsl/misc/shader-with-while-loop.html": 0.0669,
+    "conformance/glsl/misc/shader-without-precision.frag.html": 0.0577,
+    "conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html": 0.0711,
+    "conformance/glsl/misc/shaders-with-invariance.html": 0.2578,
+    "conformance/glsl/misc/shaders-with-mis-matching-uniforms.html": 0.3216,
+    "conformance/glsl/misc/shaders-with-mis-matching-varyings.html": 0.0838,
+    "conformance/glsl/misc/shaders-with-missing-varyings.html": 0.0989,
+    "conformance/glsl/misc/shaders-with-name-conflicts.html": 0.0994,
+    "conformance/glsl/misc/shaders-with-uniform-structs.html": 0.3104,
+    "conformance/glsl/misc/shaders-with-varyings.html": 0.2246,
+    "conformance/glsl/misc/shared.html": 0.1033,
+    "conformance/glsl/misc/struct-as-inout-parameter.html": 0.119,
+    "conformance/glsl/misc/struct-as-out-parameter.html": 0.1164,
+    "conformance/glsl/misc/struct-assign.html": 0.124,
+    "conformance/glsl/misc/struct-equals.html": 0.1304,
+    "conformance/glsl/misc/struct-mixed-array-declarators.html": 0.3804,
+    "conformance/glsl/misc/struct-nesting-exceeds-maximum.html": 0.0577,
+    "conformance/glsl/misc/struct-nesting-of-variable-names.html": 1.375,
+    "conformance/glsl/misc/struct-nesting-under-maximum.html": 0.1708,
+    "conformance/glsl/misc/struct-specifiers-in-uniforms.html": 0.3493,
+    "conformance/glsl/misc/struct-unary-operators.html": 0.2479,
+    "conformance/glsl/misc/ternary-operator-on-arrays.html": 0.1736,
+    "conformance/glsl/misc/ternary-operators-in-global-initializers.html": 0.1515,
+    "conformance/glsl/misc/ternary-operators-in-initializers.html": 0.1852,
+    "conformance/glsl/misc/uninitialized-local-global-variables.html": 0.3417,
+    "conformance/glsl/preprocessor/comments.html": 0.2819,
+    "conformance/glsl/preprocessor/macro-expansion-tricky.html": 0.0681,
+    "conformance/glsl/reserved/_webgl_field.vert.html": 0.2074,
+    "conformance/glsl/reserved/_webgl_function.vert.html": 0.0682,
+    "conformance/glsl/reserved/_webgl_struct.vert.html": 0.2893,
+    "conformance/glsl/reserved/_webgl_variable.vert.html": 0.0638,
+    "conformance/glsl/reserved/webgl_field.vert.html": 0.1136,
+    "conformance/glsl/reserved/webgl_function.vert.html": 0.2054,
+    "conformance/glsl/reserved/webgl_struct.vert.html": 0.0568,
+    "conformance/glsl/reserved/webgl_variable.vert.html": 0.2325,
+    "conformance/glsl/samplers/glsl-function-texture2d-bias.html": 0.0959,
+    "conformance/glsl/samplers/glsl-function-texture2dlod.html": 0.0893,
+    "conformance/glsl/samplers/glsl-function-texture2dproj.html": 0.3849,
+    "conformance/glsl/samplers/glsl-function-texture2dprojlod.html": 0.9176,
+    "conformance/glsl/variables/gl-fragcoord-xy-values.html": 0.0702,
+    "conformance/glsl/variables/gl-fragcoord.html": 0.0959,
+    "conformance/glsl/variables/gl-fragdata-and-fragcolor.html": 0.0619,
+    "conformance/glsl/variables/gl-frontfacing.html": 0.2134,
+    "conformance/glsl/variables/gl-pointcoord.html": 0.2554,
+    "conformance/glsl/variables/glsl-built-ins.html": 0.3537,
+    "conformance/limits/gl-line-width.html": 0.2217,
+    "conformance/limits/gl-max-texture-dimensions.html": 0.0768,
+    "conformance/limits/gl-min-attribs.html": 0.1726,
+    "conformance/limits/gl-min-textures.html": 0.2389,
+    "conformance/limits/gl-min-uniforms.html": 0.0953,
+    "conformance/misc/bad-arguments-test.html": 0.2456,
+    "conformance/misc/boolean-argument-conversion.html": 0.0761,
+    "conformance/misc/delayed-drawing.html": 1.2315,
+    "conformance/misc/error-reporting.html": 0.1813,
+    "conformance/misc/expando-loss.html": 0.2639,
+    "conformance/misc/functions-returning-strings.html": 0.071,
+    "conformance/misc/hint.html": 0.2961,
+    "conformance/misc/invalid-passed-params.html": 0.1222,
+    "conformance/misc/is-object.html": 0.1647,
+    "conformance/misc/null-object-behaviour.html": 0.1965,
+    "conformance/misc/object-deletion-behaviour.html": 0.2085,
+    "conformance/misc/shader-precision-format.html": 0.1582,
+    "conformance/misc/type-conversion-test.html": 0.2839,
+    "conformance/misc/uninitialized-test.html": 0.2427,
+    "conformance/misc/webgl-specific-stencil-settings.html": 0.4886,
+    "conformance/misc/webgl-specific.html": 0.3153,
+    "conformance/more/conformance/constants.html": 0.0763,
+    "conformance/more/conformance/getContext.html": 0.0713,
+    "conformance/more/conformance/methods.html": 0.069,
+    "conformance/more/conformance/quickCheckAPI-A.html": 0.0841,
+    "conformance/more/conformance/quickCheckAPI-B1.html": 0.1289,
+    "conformance/more/conformance/quickCheckAPI-B2.html": 0.134,
+    "conformance/more/conformance/quickCheckAPI-B3.html": 0.0739,
+    "conformance/more/conformance/quickCheckAPI-B4.html": 0.0729,
+    "conformance/more/conformance/quickCheckAPI-C.html": 0.2093,
+    "conformance/more/conformance/quickCheckAPI-D_G.html": 0.2482,
+    "conformance/more/conformance/quickCheckAPI-G_I.html": 0.1288,
+    "conformance/more/conformance/quickCheckAPI-L_S.html": 0.2794,
+    "conformance/more/conformance/quickCheckAPI-S_V.html": 0.1797,
+    "conformance/more/conformance/webGLArrays.html": 0.3343,
+    "conformance/more/functions/bindBuffer.html": 0.2109,
+    "conformance/more/functions/bindBufferBadArgs.html": 0.2265,
+    "conformance/more/functions/bindFramebufferLeaveNonZero.html": 0.0765,
+    "conformance/more/functions/bufferData.html": 0.2374,
+    "conformance/more/functions/bufferDataBadArgs.html": 0.0766,
+    "conformance/more/functions/bufferSubData.html": 0.1773,
+    "conformance/more/functions/bufferSubDataBadArgs.html": 0.2812,
+    "conformance/more/functions/copyTexImage2D.html": 0.256,
+    "conformance/more/functions/copyTexImage2DBadArgs.html": 0.0725,
+    "conformance/more/functions/copyTexSubImage2D.html": 0.1101,
+    "conformance/more/functions/copyTexSubImage2DBadArgs.html": 0.1726,
+    "conformance/more/functions/deleteBufferBadArgs.html": 0.09,
+    "conformance/more/functions/drawArrays.html": 0.1058,
+    "conformance/more/functions/drawElements.html": 0.2998,
+    "conformance/more/functions/isTests.html": 0.2682,
+    "conformance/more/functions/isTestsBadArgs.html": 0.0617,
+    "conformance/more/functions/readPixels.html": 0.1654,
+    "conformance/more/functions/readPixelsBadArgs.html": 0.2238,
+    "conformance/more/functions/texImage2D.html": 0.2502,
+    "conformance/more/functions/texImage2DBadArgs.html": 0.0954,
+    "conformance/more/functions/texImage2DHTML.html": 0.3196,
+    "conformance/more/functions/texImage2DHTMLBadArgs.html": 0.2804,
+    "conformance/more/functions/texSubImage2D.html": 0.0688,
+    "conformance/more/functions/texSubImage2DBadArgs.html": 0.0953,
+    "conformance/more/functions/texSubImage2DHTML.html": 0.398,
+    "conformance/more/functions/texSubImage2DHTMLBadArgs.html": 0.1848,
+    "conformance/more/functions/uniformMatrix.html": 0.2917,
+    "conformance/more/functions/uniformMatrixBadArgs.html": 0.3248,
+    "conformance/more/functions/uniformf.html": 0.0806,
+    "conformance/more/functions/uniformfArrayLen1.html": 0.1678,
+    "conformance/more/functions/uniformfBadArgs.html": 0.5132,
+    "conformance/more/functions/uniformi.html": 0.3301,
+    "conformance/more/functions/uniformiBadArgs.html": 0.2706,
+    "conformance/more/functions/vertexAttrib.html": 0.2329,
+    "conformance/more/functions/vertexAttribBadArgs.html": 0.1742,
+    "conformance/more/functions/vertexAttribPointer.html": 0.0735,
+    "conformance/more/functions/vertexAttribPointerBadArgs.html": 0.2278,
+    "conformance/more/glsl/arrayOutOfBounds.html": 0.1212,
+    "conformance/more/glsl/uniformOutOfBounds.html": 0.0957,
+    "conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html": 0.599,
+    "conformance/offscreencanvas/context-creation-worker.html": 0.0785,
+    "conformance/offscreencanvas/context-creation.html": 0.0823,
+    "conformance/offscreencanvas/context-lost-restored-worker.html": 0.1032,
+    "conformance/offscreencanvas/context-lost-restored.html": 0.1191,
+    "conformance/offscreencanvas/context-lost-worker.html": 0.0859,
+    "conformance/offscreencanvas/context-lost.html": 0.078,
+    "conformance/offscreencanvas/methods-worker.html": 0.2744,
+    "conformance/offscreencanvas/methods.html": 0.2153,
+    "conformance/offscreencanvas/offscreencanvas-resize.html": 0.0562,
+    "conformance/offscreencanvas/offscreencanvas-timer-query.html": 0.0796,
+    "conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.2191,
+    "conformance/ogles/GL/abs/abs_001_to_006.html": 0.744,
+    "conformance/ogles/GL/acos/acos_001_to_006.html": 0.8088,
+    "conformance/ogles/GL/all/all_001_to_004.html": 0.5131,
+    "conformance/ogles/GL/any/any_001_to_004.html": 0.3787,
+    "conformance/ogles/GL/array/array_001_to_006.html": 0.6154,
+    "conformance/ogles/GL/asin/asin_001_to_006.html": 0.8566,
+    "conformance/ogles/GL/atan/atan_001_to_008.html": 0.8614,
+    "conformance/ogles/GL/atan/atan_009_to_012.html": 0.6163,
+    "conformance/ogles/GL/biConstants/biConstants_001_to_008.html": 0.6309,
+    "conformance/ogles/GL/biConstants/biConstants_009_to_016.html": 0.6438,
+    "conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html": 0.5014,
+    "conformance/ogles/GL/build/build_001_to_008.html": 0.2043,
+    "conformance/ogles/GL/build/build_009_to_016.html": 0.3839,
+    "conformance/ogles/GL/build/build_017_to_024.html": 0.3352,
+    "conformance/ogles/GL/build/build_025_to_032.html": 0.1476,
+    "conformance/ogles/GL/build/build_033_to_040.html": 0.3464,
+    "conformance/ogles/GL/build/build_041_to_048.html": 0.2695,
+    "conformance/ogles/GL/build/build_049_to_056.html": 0.2266,
+    "conformance/ogles/GL/build/build_057_to_064.html": 0.1209,
+    "conformance/ogles/GL/build/build_065_to_072.html": 0.1961,
+    "conformance/ogles/GL/build/build_073_to_080.html": 0.1199,
+    "conformance/ogles/GL/build/build_081_to_088.html": 0.1405,
+    "conformance/ogles/GL/build/build_089_to_096.html": 0.3703,
+    "conformance/ogles/GL/build/build_097_to_104.html": 0.1736,
+    "conformance/ogles/GL/build/build_105_to_112.html": 0.1719,
+    "conformance/ogles/GL/build/build_113_to_120.html": 0.3351,
+    "conformance/ogles/GL/build/build_121_to_128.html": 0.3394,
+    "conformance/ogles/GL/build/build_129_to_136.html": 0.2175,
+    "conformance/ogles/GL/build/build_137_to_144.html": 0.1318,
+    "conformance/ogles/GL/build/build_145_to_152.html": 0.3525,
+    "conformance/ogles/GL/build/build_153_to_160.html": 0.1569,
+    "conformance/ogles/GL/build/build_161_to_168.html": 0.3025,
+    "conformance/ogles/GL/build/build_169_to_176.html": 0.2283,
+    "conformance/ogles/GL/build/build_177_to_178.html": 0.1957,
+    "conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html": 0.2866,
+    "conformance/ogles/GL/ceil/ceil_001_to_006.html": 0.6252,
+    "conformance/ogles/GL/clamp/clamp_001_to_006.html": 0.6713,
+    "conformance/ogles/GL/control_flow/control_flow_001_to_008.html": 0.874,
+    "conformance/ogles/GL/control_flow/control_flow_009_to_010.html": 0.3785,
+    "conformance/ogles/GL/cos/cos_001_to_006.html": 0.6078,
+    "conformance/ogles/GL/cross/cross_001_to_002.html": 0.3286,
+    "conformance/ogles/GL/default/default_001_to_001.html": 0.285,
+    "conformance/ogles/GL/degrees/degrees_001_to_006.html": 0.6389,
+    "conformance/ogles/GL/discard/discard_001_to_002.html": 0.2142,
+    "conformance/ogles/GL/distance/distance_001_to_006.html": 0.598,
+    "conformance/ogles/GL/dot/dot_001_to_006.html": 0.6757,
+    "conformance/ogles/GL/equal/equal_001_to_008.html": 1.0095,
+    "conformance/ogles/GL/equal/equal_009_to_012.html": 0.7518,
+    "conformance/ogles/GL/exp/exp_001_to_008.html": 0.8697,
+    "conformance/ogles/GL/exp/exp_009_to_012.html": 0.8673,
+    "conformance/ogles/GL/exp2/exp2_001_to_008.html": 0.7988,
+    "conformance/ogles/GL/exp2/exp2_009_to_012.html": 0.5319,
+    "conformance/ogles/GL/faceforward/faceforward_001_to_006.html": 0.7029,
+    "conformance/ogles/GL/floor/floor_001_to_006.html": 0.68,
+    "conformance/ogles/GL/fract/fract_001_to_006.html": 0.7545,
+    "conformance/ogles/GL/functions/functions_001_to_008.html": 0.69,
+    "conformance/ogles/GL/functions/functions_009_to_016.html": 0.7241,
+    "conformance/ogles/GL/functions/functions_017_to_024.html": 0.5923,
+    "conformance/ogles/GL/functions/functions_025_to_032.html": 0.6556,
+    "conformance/ogles/GL/functions/functions_033_to_040.html": 0.6118,
+    "conformance/ogles/GL/functions/functions_041_to_048.html": 0.4741,
+    "conformance/ogles/GL/functions/functions_049_to_056.html": 0.7514,
+    "conformance/ogles/GL/functions/functions_057_to_064.html": 0.6158,
+    "conformance/ogles/GL/functions/functions_065_to_072.html": 0.538,
+    "conformance/ogles/GL/functions/functions_073_to_080.html": 0.7216,
+    "conformance/ogles/GL/functions/functions_081_to_088.html": 0.6579,
+    "conformance/ogles/GL/functions/functions_089_to_096.html": 0.5535,
+    "conformance/ogles/GL/functions/functions_097_to_104.html": 0.7151,
+    "conformance/ogles/GL/functions/functions_105_to_112.html": 0.6058,
+    "conformance/ogles/GL/functions/functions_113_to_120.html": 0.5718,
+    "conformance/ogles/GL/functions/functions_121_to_126.html": 0.5629,
+    "conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html": 0.4388,
+    "conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html": 0.2327,
+    "conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html": 0.5967,
+    "conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html": 0.8013,
+    "conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html": 0.6011,
+    "conformance/ogles/GL/length/length_001_to_006.html": 0.7276,
+    "conformance/ogles/GL/lessThan/lessThan_001_to_008.html": 0.8739,
+    "conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html": 0.8484,
+    "conformance/ogles/GL/log/log_001_to_008.html": 0.8763,
+    "conformance/ogles/GL/log/log_009_to_012.html": 0.6907,
+    "conformance/ogles/GL/log2/log2_001_to_008.html": 0.7846,
+    "conformance/ogles/GL/log2/log2_009_to_012.html": 0.5907,
+    "conformance/ogles/GL/mat/mat_001_to_008.html": 0.5341,
+    "conformance/ogles/GL/mat/mat_009_to_016.html": 0.5038,
+    "conformance/ogles/GL/mat/mat_017_to_024.html": 0.6009,
+    "conformance/ogles/GL/mat/mat_025_to_032.html": 0.6909,
+    "conformance/ogles/GL/mat/mat_033_to_040.html": 0.5156,
+    "conformance/ogles/GL/mat/mat_041_to_046.html": 0.5459,
+    "conformance/ogles/GL/mat3/mat3_001_to_006.html": 0.4243,
+    "conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html": 0.5975,
+    "conformance/ogles/GL/max/max_001_to_006.html": 0.8072,
+    "conformance/ogles/GL/min/min_001_to_006.html": 0.5574,
+    "conformance/ogles/GL/mix/mix_001_to_006.html": 0.682,
+    "conformance/ogles/GL/mod/mod_001_to_008.html": 0.8513,
+    "conformance/ogles/GL/normalize/normalize_001_to_006.html": 0.8798,
+    "conformance/ogles/GL/not/not_001_to_004.html": 0.4524,
+    "conformance/ogles/GL/notEqual/notEqual_001_to_008.html": 0.8316,
+    "conformance/ogles/GL/notEqual/notEqual_009_to_012.html": 0.7007,
+    "conformance/ogles/GL/operators/operators_001_to_008.html": 0.5697,
+    "conformance/ogles/GL/operators/operators_009_to_016.html": 0.5158,
+    "conformance/ogles/GL/operators/operators_017_to_024.html": 0.6063,
+    "conformance/ogles/GL/operators/operators_025_to_026.html": 0.3227,
+    "conformance/ogles/GL/pow/pow_001_to_008.html": 0.6718,
+    "conformance/ogles/GL/pow/pow_009_to_016.html": 0.8688,
+    "conformance/ogles/GL/pow/pow_017_to_024.html": 0.8874,
+    "conformance/ogles/GL/radians/radians_001_to_006.html": 0.6815,
+    "conformance/ogles/GL/reflect/reflect_001_to_006.html": 0.9216,
+    "conformance/ogles/GL/refract/refract_001_to_006.html": 0.6994,
+    "conformance/ogles/GL/sign/sign_001_to_006.html": 0.643,
+    "conformance/ogles/GL/sin/sin_001_to_006.html": 0.8602,
+    "conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html": 0.8276,
+    "conformance/ogles/GL/sqrt/sqrt_001_to_006.html": 0.754,
+    "conformance/ogles/GL/step/step_001_to_006.html": 0.6508,
+    "conformance/ogles/GL/struct/struct_001_to_008.html": 0.815,
+    "conformance/ogles/GL/struct/struct_009_to_016.html": 0.8107,
+    "conformance/ogles/GL/struct/struct_017_to_024.html": 0.8997,
+    "conformance/ogles/GL/struct/struct_025_to_032.html": 0.8482,
+    "conformance/ogles/GL/struct/struct_033_to_040.html": 0.7677,
+    "conformance/ogles/GL/struct/struct_041_to_048.html": 0.7686,
+    "conformance/ogles/GL/struct/struct_049_to_056.html": 0.7432,
+    "conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html": 0.8695,
+    "conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html": 0.8019,
+    "conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html": 0.8005,
+    "conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html": 0.7842,
+    "conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html": 0.8513,
+    "conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html": 0.8828,
+    "conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html": 0.7659,
+    "conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html": 0.7943,
+    "conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html": 0.9047,
+    "conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html": 0.7759,
+    "conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html": 0.65,
+    "conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html": 0.7302,
+    "conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html": 0.9772,
+    "conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html": 0.7679,
+    "conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html": 0.8888,
+    "conformance/ogles/GL/tan/tan_001_to_006.html": 0.6468,
+    "conformance/ogles/GL/vec/vec_001_to_008.html": 0.6121,
+    "conformance/ogles/GL/vec/vec_009_to_016.html": 0.7437,
+    "conformance/ogles/GL/vec/vec_017_to_018.html": 0.366,
+    "conformance/ogles/GL/vec3/vec3_001_to_008.html": 0.5939,
+    "conformance/programs/get-active-test.html": 0.3697,
+    "conformance/programs/gl-bind-attrib-location-long-names-test.html": 0.3087,
+    "conformance/programs/gl-bind-attrib-location-test.html": 0.19,
+    "conformance/programs/gl-get-active-attribute.html": 0.3287,
+    "conformance/programs/gl-get-active-uniform.html": 0.2342,
+    "conformance/programs/gl-getshadersource.html": 0.2288,
+    "conformance/programs/gl-shader-test.html": 0.3237,
+    "conformance/programs/invalid-UTF-16.html": 0.0994,
+    "conformance/programs/program-handling.html": 0.1865,
+    "conformance/programs/program-infolog.html": 0.1695,
+    "conformance/programs/program-test.html": 0.2877,
+    "conformance/programs/use-program-crash-with-discard-in-fragment-shader.html": 0.2887,
+    "conformance/reading/fbo-remains-unchanged-after-read-pixels.html": 0.3404,
+    "conformance/reading/read-pixels-pack-alignment.html": 0.4604,
+    "conformance/reading/read-pixels-test.html": 0.4458,
+    "conformance/renderbuffers/depth-renderbuffer-initialization.html": 0.268,
+    "conformance/renderbuffers/feedback-loop.html": 0.1934,
+    "conformance/renderbuffers/framebuffer-state-restoration.html": 0.3511,
+    "conformance/renderbuffers/renderbuffer-initialization.html": 0.2391,
+    "conformance/renderbuffers/stencil-renderbuffer-initialization.html": 0.2571,
+    "conformance/rendering/bind-framebuffer-flush-bug.html": 0.3804,
+    "conformance/rendering/blending.html": 0.3839,
+    "conformance/rendering/canvas-alpha-bug.html": 0.2393,
+    "conformance/rendering/clear-after-copyTexImage2D.html": 0.1411,
+    "conformance/rendering/clear-default-framebuffer-with-scissor-test.html": 0.2088,
+    "conformance/rendering/color-mask-preserved-during-implicit-clears.html": 1.5767,
+    "conformance/rendering/color-mask-should-not-affect-antialiased-framebuffer-resolution.html": 0.2382,
+    "conformance/rendering/culling.html": 0.2179,
+    "conformance/rendering/default-texture-draw-bug.html": 0.2021,
+    "conformance/rendering/draw-arrays-out-of-bounds.html": 0.287,
+    "conformance/rendering/draw-elements-out-of-bounds.html": 0.2414,
+    "conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html": 0.2435,
+    "conformance/rendering/draw-with-changing-start-vertex-bug.html": 0.1803,
+    "conformance/rendering/framebuffer-switch.html": 0.2245,
+    "conformance/rendering/framebuffer-texture-clear.html": 0.2626,
+    "conformance/rendering/framebuffer-texture-switch.html": 0.2943,
+    "conformance/rendering/gl-clear.html": 0.2188,
+    "conformance/rendering/gl-drawarrays.html": 0.2175,
+    "conformance/rendering/gl-drawelements.html": 0.2297,
+    "conformance/rendering/gl-scissor-canvas-dimensions.html": 0.2007,
+    "conformance/rendering/gl-scissor-fbo-test.html": 0.3579,
+    "conformance/rendering/gl-scissor-test.html": 0.4812,
+    "conformance/rendering/gl-viewport-test.html": 0.5765,
+    "conformance/rendering/line-loop-tri-fan.html": 0.1943,
+    "conformance/rendering/line-rendering-quality.html": 0.4098,
+    "conformance/rendering/many-draw-calls.html": 1.9164,
+    "conformance/rendering/more-than-65536-indices.html": 0.2268,
+    "conformance/rendering/multisample-corruption.html": 3.0193,
+    "conformance/rendering/negative-one-index.html": 0.1229,
+    "conformance/rendering/out-of-bounds-array-buffers.html": 0.2023,
+    "conformance/rendering/out-of-bounds-index-buffers.html": 0.1384,
+    "conformance/rendering/point-no-attributes.html": 0.1877,
+    "conformance/rendering/point-size.html": 0.158,
+    "conformance/rendering/point-specific-shader-variables.html": 0.267,
+    "conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html": 0.1723,
+    "conformance/rendering/polygon-offset.html": 0.0649,
+    "conformance/rendering/preservedrawingbuffer-leak.html": 0.5886,
+    "conformance/rendering/rendering-sampling-feedback-loop.html": 0.2436,
+    "conformance/rendering/rendering-stencil-large-viewport.html": 0.229,
+    "conformance/rendering/scissor-rect-repeated-rendering.html": 0.3854,
+    "conformance/rendering/simple.html": 0.1936,
+    "conformance/rendering/texture-switch-performance.html": 0,
+    "conformance/rendering/triangle.html": 0.2726,
+    "conformance/state/fb-attach-implicit-target-assignment.html": 0.1219,
+    "conformance/state/gl-enable-enum-test.html": 0.4199,
+    "conformance/state/gl-get-calls.html": 0.1657,
+    "conformance/state/gl-geterror.html": 0.3129,
+    "conformance/state/gl-initial-state.html": 0.1747,
+    "conformance/state/state-uneffected-after-compositing.html": 0.4109,
+    "conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.8865,
+    "conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.2001,
+    "conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.8343,
+    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html": 2.8895,
+    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.3182,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html": 3.7429,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.9825,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.1827,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html": 0.8653,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html": 0.8858,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.7487,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html": 0.9367,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.9202,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html": 0.8649,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.9729,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.9538,
+    "conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html": 0.506,
+    "conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html": 0.4501,
+    "conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5552,
+    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3363,
+    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4044,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html": 0.3376,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4001,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3457,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html": 0.3763,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html": 0.3198,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3197,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html": 0.5104,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4276,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html": 0.3431,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.2739,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3784,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.5624,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.6284,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.4987,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 0.7941,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5638,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 0.4729,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.7085,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5813,
+    "conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.2821,
+    "conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.2686,
+    "conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.2721,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.4209,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.2025,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.3739,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.199,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3356,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html": 0.2107,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html": 0.1576,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3113,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html": 0.3011,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3236,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html": 0.2551,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4235,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3395,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.3666,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.3654,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3573,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.2085,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3431,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.1755,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1439,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.2298,
+    "conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html": 1.0937,
+    "conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html": 0.8647,
+    "conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.8602,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html": 0.8977,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.9255,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html": 0.7299,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.8391,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.8573,
+    "conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.4222,
+    "conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.5354,
+    "conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3354,
+    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.2377,
+    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.2764,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.3745,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4508,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5089,
+    "conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html": 0.3654,
+    "conformance/textures/misc/copy-tex-image-2d-formats.html": 0.4371,
+    "conformance/textures/misc/copy-tex-image-and-sub-image-2d.html": 0.3777,
+    "conformance/textures/misc/copy-tex-image-crash.html": 0.1961,
+    "conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html": 0.2426,
+    "conformance/textures/misc/copytexsubimage2d-subrects.html": 0.2401,
+    "conformance/textures/misc/cube-incomplete-fbo.html": 0.0842,
+    "conformance/textures/misc/cube-map-uploads-out-of-order.html": 1.1168,
+    "conformance/textures/misc/default-texture.html": 0.2366,
+    "conformance/textures/misc/exif-orientation.html": 0.7637,
+    "conformance/textures/misc/format-filterable-renderable.html": 0.2114,
+    "conformance/textures/misc/gl-pixelstorei.html": 0.2461,
+    "conformance/textures/misc/gl-teximage.html": 0.4384,
+    "conformance/textures/misc/mipmap-fbo.html": 0.2103,
+    "conformance/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.1442,
+    "conformance/textures/misc/origin-clean-conformance.html": 0.2437,
+    "conformance/textures/misc/png-image-types.html": 0.5885,
+    "conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html": 0.9013,
+    "conformance/textures/misc/tex-image-and-uniform-binding-bugs.html": 0.0889,
+    "conformance/textures/misc/tex-image-canvas-corruption.html": 0.2293,
+    "conformance/textures/misc/tex-image-webgl.html": 0.3622,
+    "conformance/textures/misc/tex-image-with-format-and-type.html": 0.2793,
+    "conformance/textures/misc/tex-image-with-invalid-data.html": 0.0681,
+    "conformance/textures/misc/tex-sub-image-2d-bad-args.html": 0.1107,
+    "conformance/textures/misc/tex-sub-image-2d.html": 0.2481,
+    "conformance/textures/misc/tex-video-using-tex-unit-non-zero.html": 0.6575,
+    "conformance/textures/misc/texparameter-test.html": 0.2624,
+    "conformance/textures/misc/texture-active-bind-2.html": 0.1292,
+    "conformance/textures/misc/texture-active-bind.html": 0.2988,
+    "conformance/textures/misc/texture-attachment-formats.html": 0.2553,
+    "conformance/textures/misc/texture-clear.html": 0.2387,
+    "conformance/textures/misc/texture-complete.html": 0.1943,
+    "conformance/textures/misc/texture-copying-and-deletion.html": 1.0931,
+    "conformance/textures/misc/texture-copying-feedback-loops.html": 0.0739,
+    "conformance/textures/misc/texture-corner-case-videos.html": 0.2334,
+    "conformance/textures/misc/texture-cube-as-fbo-attachment.html": 0.2263,
+    "conformance/textures/misc/texture-draw-with-2d-and-cube.html": 0.0847,
+    "conformance/textures/misc/texture-hd-dpi.html": 0.4111,
+    "conformance/textures/misc/texture-mips.html": 0.1081,
+    "conformance/textures/misc/texture-size-cube-maps.html": 0.5315,
+    "conformance/textures/misc/texture-size-limit.html": 0.3086,
+    "conformance/textures/misc/texture-size.html": 0.6049,
+    "conformance/textures/misc/texture-sub-image-cube-maps.html": 0.2303,
+    "conformance/textures/misc/texture-transparent-pixels-initialized.html": 0.1042,
+    "conformance/textures/misc/texture-upload-cube-maps.html": 0.1802,
+    "conformance/textures/misc/texture-upload-size.html": 0.5114,
+    "conformance/textures/misc/texture-video-transparent.html": 2.5662,
+    "conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html": 0.0889,
+    "conformance/textures/misc/upload-from-srcset-with-empty-data.html": 0.0805,
+    "conformance/textures/misc/video-rotation.html": 0.6579,
+    "conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.1641,
+    "conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.2655,
+    "conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.2539,
+    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.1143,
+    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1318,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.329,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3075,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.2707,
+    "conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html": 1.2977,
+    "conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html": 1.435,
+    "conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.4188,
+    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html": 1.2495,
+    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.4997,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html": 1.176,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.2472,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.4897,
+    "conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.8672,
+    "conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.331,
+    "conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.1628,
+    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 3.9648,
+    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.549,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 3.3336,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.6667,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.4271,
+    "conformance/typedarrays/array-buffer-crash.html": 0.0559,
+    "conformance/typedarrays/array-buffer-view-crash.html": 0.0595,
+    "conformance/typedarrays/array-large-array-tests.html": 0.1586,
+    "conformance/typedarrays/array-unit-tests.html": 0.0681,
+    "conformance/typedarrays/data-view-crash.html": 0.0414,
+    "conformance/typedarrays/data-view-test.html": 0.0806,
+    "conformance/typedarrays/typed-arrays-in-workers.html": 0.0875,
+    "conformance/uniforms/gl-uniform-arrays.html": 0.2564,
+    "conformance/uniforms/gl-uniform-bool.html": 0.0807,
+    "conformance/uniforms/gl-uniformmatrix4fv.html": 0.1466,
+    "conformance/uniforms/gl-unknown-uniform.html": 0.2836,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-00.html": 0.693,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-01.html": 0.6129,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-02.html": 0.68,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-03.html": 0.539,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-04.html": 0.5665,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-05.html": 0.7156,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-06.html": 0.6877,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-07.html": 0.6765,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-08.html": 0.7806,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-09.html": 0.7373,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-10.html": 0.8139,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-11.html": 0.8255,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-12.html": 0.7872,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-13.html": 0.7469,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-14.html": 0.6858,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-15.html": 0.7651,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-16.html": 0.7791,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-17.html": 0.6142,
+    "conformance/uniforms/null-uniform-location.html": 0.0816,
+    "conformance/uniforms/out-of-bounds-uniform-array-access.html": 2.1073,
+    "conformance/uniforms/uniform-default-values.html": 1.3224,
+    "conformance/uniforms/uniform-location.html": 0.4985,
+    "conformance/uniforms/uniform-samplers-test.html": 12.055,
+    "conformance/uniforms/uniform-values-per-program.html": 0.7976,
+    "conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html": 0.2017,
+    "conformance2/attribs/gl-vertex-attrib-i-render.html": 0.1073,
+    "conformance2/attribs/gl-vertex-attrib-normalized-int.html": 0.0884,
+    "conformance2/attribs/gl-vertex-attrib.html": 0.3258,
+    "conformance2/attribs/gl-vertexattribipointer-offsets.html": 0.1819,
+    "conformance2/attribs/gl-vertexattribipointer.html": 0.2556,
+    "conformance2/attribs/invalid-vertex-attribs.html": 0.1319,
+    "conformance2/attribs/render-no-enabled-attrib-arrays.html": 0.2895,
+    "conformance2/buffers/bound-buffer-size-change-test.html": 0.1321,
+    "conformance2/buffers/buffer-copying-contents.html": 0.2314,
+    "conformance2/buffers/buffer-copying-restrictions.html": 0.2362,
+    "conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html": 0.2081,
+    "conformance2/buffers/buffer-overflow-test.html": 0.0726,
+    "conformance2/buffers/buffer-type-restrictions.html": 0.1167,
+    "conformance2/buffers/delete-buffer.html": 0.0586,
+    "conformance2/buffers/get-buffer-sub-data-validity.html": 0.1633,
+    "conformance2/buffers/get-buffer-sub-data.html": 0.1055,
+    "conformance2/buffers/one-large-uniform-buffer.html": 0.2478,
+    "conformance2/buffers/uniform-buffers-second-compile.html": 0.0991,
+    "conformance2/buffers/uniform-buffers-state-restoration.html": 0.1311,
+    "conformance2/buffers/uniform-buffers.html": 0.3819,
+    "conformance2/canvas/to-data-url-with-pack-params.html": 0.1318,
+    "conformance2/context/constants-and-properties-2.html": 0.1075,
+    "conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html": 0.1274,
+    "conformance2/context/context-mode.html": 0.0819,
+    "conformance2/context/context-resize-changes-buffer-binding-bug.html": 0.0806,
+    "conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html": 0.4716,
+    "conformance2/context/context-type-test-2.html": 0.1311,
+    "conformance2/context/incorrect-context-object-behaviour.html": 0.3206,
+    "conformance2/context/methods-2.html": 0.0748,
+    "conformance2/context/no-experimental-webgl2.html": 0.0664,
+    "conformance2/extensions/ext-color-buffer-float.html": 0.4086,
+    "conformance2/extensions/ext-color-buffer-half-float.html": 0.4131,
+    "conformance2/extensions/ext-disjoint-timer-query-webgl2.html": 4.7325,
+    "conformance2/extensions/ext-texture-filter-anisotropic.html": 0.0907,
+    "conformance2/extensions/ext-texture-norm16.html": 0.129,
+    "conformance2/extensions/oes-draw-buffers-indexed.html": 0.5866,
+    "conformance2/extensions/ovr_multiview2.html": 0.8262,
+    "conformance2/extensions/ovr_multiview2_depth.html": 0.0912,
+    "conformance2/extensions/ovr_multiview2_draw_buffers.html": 0.3509,
+    "conformance2/extensions/ovr_multiview2_flat_varying.html": 0.1045,
+    "conformance2/extensions/ovr_multiview2_instanced_draw.html": 0.3168,
+    "conformance2/extensions/ovr_multiview2_non_multiview_shaders.html": 0.2398,
+    "conformance2/extensions/ovr_multiview2_single_view_operations.html": 0.3385,
+    "conformance2/extensions/ovr_multiview2_timer_query.html": 0.1793,
+    "conformance2/extensions/ovr_multiview2_transform_feedback.html": 0.1036,
+    "conformance2/extensions/promoted-extensions-in-shaders.html": 0.1991,
+    "conformance2/extensions/promoted-extensions.html": 0.0895,
+    "conformance2/extensions/required-extensions.html": 0.0849,
+    "conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html": 4.0251,
+    "conformance2/glsl3/array-as-return-value.html": 0.2192,
+    "conformance2/glsl3/array-assign-constructor.html": 0.1913,
+    "conformance2/glsl3/array-assign.html": 0.0831,
+    "conformance2/glsl3/array-complex-indexing.html": 0.2075,
+    "conformance2/glsl3/array-element-increment.html": 0.3434,
+    "conformance2/glsl3/array-equality.html": 0.3391,
+    "conformance2/glsl3/array-in-complex-expression.html": 0.2398,
+    "conformance2/glsl3/array-initialize-with-same-name-array.html": 0.2431,
+    "conformance2/glsl3/array-length-side-effects.html": 0.1034,
+    "conformance2/glsl3/attrib-location-length-limits.html": 0.2574,
+    "conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html": 0.2045,
+    "conformance2/glsl3/compare-structs-containing-arrays.html": 0.2353,
+    "conformance2/glsl3/compound-assignment-type-combination.html": 1.3825,
+    "conformance2/glsl3/const-array-init.html": 0.1796,
+    "conformance2/glsl3/const-struct-from-array-as-function-parameter.html": 0.2221,
+    "conformance2/glsl3/float-parsing.html": 0.2651,
+    "conformance2/glsl3/forbidden-operators.html": 0.0835,
+    "conformance2/glsl3/forward-declaration.html": 0.1402,
+    "conformance2/glsl3/frag-depth.html": 0.2469,
+    "conformance2/glsl3/fragment-shader-loop-crash.html": 0.1992,
+    "conformance2/glsl3/gradient-in-discontinuous-loop.html": 0.2371,
+    "conformance2/glsl3/input-with-interpotaion-as-lvalue.html": 0.2885,
+    "conformance2/glsl3/invalid-default-precision.html": 0.2316,
+    "conformance2/glsl3/invalid-invariant.html": 0.2609,
+    "conformance2/glsl3/loops-with-side-effects.html": 0.2659,
+    "conformance2/glsl3/matrix-row-major-dynamic-indexing.html": 0.1989,
+    "conformance2/glsl3/matrix-row-major.html": 0.3042,
+    "conformance2/glsl3/misplaced-version-directive.html": 0.1377,
+    "conformance2/glsl3/no-attribute-vertex-shader.html": 0.0802,
+    "conformance2/glsl3/precision-side-effects-bug.html": 0.1141,
+    "conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html": 0,
+    "conformance2/glsl3/sampler-array-indexing.html": 0.0928,
+    "conformance2/glsl3/sampler-no-precision.html": 0.2372,
+    "conformance2/glsl3/sequence-operator-returns-non-constant.html": 0.1815,
+    "conformance2/glsl3/shader-linking.html": 0.106,
+    "conformance2/glsl3/shader-with-1024-character-define.html": 0.1955,
+    "conformance2/glsl3/shader-with-1024-character-identifier.frag.html": 0.2052,
+    "conformance2/glsl3/shader-with-1025-character-define.html": 0.2253,
+    "conformance2/glsl3/shader-with-1025-character-identifier.frag.html": 0.144,
+    "conformance2/glsl3/shader-with-invalid-characters.html": 0.1235,
+    "conformance2/glsl3/shader-with-mis-matching-uniform-block.html": 0.0901,
+    "conformance2/glsl3/short-circuiting-in-loop-condition.html": 0.3136,
+    "conformance2/glsl3/switch-case.html": 0.1571,
+    "conformance2/glsl3/texture-offset-non-constant-offset.html": 0.2405,
+    "conformance2/glsl3/texture-offset-out-of-range.html": 0.1177,
+    "conformance2/glsl3/texture-offset-uniform-texture-coordinate.html": 0.1275,
+    "conformance2/glsl3/tricky-loop-conditions.html": 0.4934,
+    "conformance2/glsl3/uint-int-shift-bug.html": 0.2501,
+    "conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html": 0.3269,
+    "conformance2/glsl3/uniform-block-layout-match.html": 0.081,
+    "conformance2/glsl3/uniform-block-layouts.html": 0.0724,
+    "conformance2/glsl3/uniform-location-length-limits.html": 0.2372,
+    "conformance2/glsl3/uniform-struct-with-non-square-matrix.html": 0.3147,
+    "conformance2/glsl3/uninitialized-local-global-variables.html": 0.3408,
+    "conformance2/glsl3/valid-invariant.html": 0.3967,
+    "conformance2/glsl3/varying-struct-inline-definition.html": 0.1864,
+    "conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html": 0.1928,
+    "conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html": 0.2318,
+    "conformance2/glsl3/vector-dynamic-indexing.html": 0.3826,
+    "conformance2/misc/blend-integer.html": 0.2214,
+    "conformance2/misc/expando-loss-2.html": 0.2608,
+    "conformance2/misc/getextension-while-pbo-bound-stability.html": 0.2788,
+    "conformance2/misc/instanceof-test.html": 0.2528,
+    "conformance2/misc/null-object-behaviour-2.html": 0.2286,
+    "conformance2/misc/object-deletion-behaviour-2.html": 0.3153,
+    "conformance2/misc/uninitialized-test-2.html": 5.9665,
+    "conformance2/misc/views-with-offsets.html": 0.3598,
+    "conformance2/offscreencanvas/context-creation-worker.html": 0.1138,
+    "conformance2/offscreencanvas/context-creation.html": 0.0688,
+    "conformance2/offscreencanvas/methods-2-worker.html": 0.1141,
+    "conformance2/offscreencanvas/methods-2.html": 0.0855,
+    "conformance2/offscreencanvas/offscreencanvas-query.html": 0.1402,
+    "conformance2/offscreencanvas/offscreencanvas-sync.html": 0.2304,
+    "conformance2/offscreencanvas/offscreencanvas-timer-query.html": 0.0858,
+    "conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.2754,
+    "conformance2/programs/active-built-in-attribs.html": 0.129,
+    "conformance2/programs/gl-get-frag-data-location.html": 0.1298,
+    "conformance2/programs/sampler-uniforms.html": 0.1701,
+    "conformance2/query/occlusion-query.html": 2.5123,
+    "conformance2/query/query.html": 0.1317,
+    "conformance2/reading/format-r11f-g11f-b10f.html": 0.1213,
+    "conformance2/reading/read-pixels-from-fbo-test.html": 0.233,
+    "conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html": 0.2051,
+    "conformance2/reading/read-pixels-into-pixel-pack-buffer.html": 0.0995,
+    "conformance2/reading/read-pixels-pack-parameters.html": 0.2677,
+    "conformance2/renderbuffers/framebuffer-object-attachment.html": 0.1144,
+    "conformance2/renderbuffers/framebuffer-test.html": 0.2785,
+    "conformance2/renderbuffers/framebuffer-texture-layer.html": 0.1779,
+    "conformance2/renderbuffers/invalidate-framebuffer.html": 0.208,
+    "conformance2/renderbuffers/multisample-draws-between-blits.html": 0.1696,
+    "conformance2/renderbuffers/multisample-with-full-sample-counts.html": 0.3058,
+    "conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html": 0.3564,
+    "conformance2/renderbuffers/multisampled-renderbuffer-initialization.html": 0.257,
+    "conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html": 0.2095,
+    "conformance2/renderbuffers/readbuffer.html": 0.0884,
+    "conformance2/rendering/attrib-type-match.html": 0.1978,
+    "conformance2/rendering/blitframebuffer-filter-outofbounds.html": 0.1077,
+    "conformance2/rendering/blitframebuffer-filter-srgb.html": 0.2709,
+    "conformance2/rendering/blitframebuffer-multisampled-readbuffer.html": 0.2421,
+    "conformance2/rendering/blitframebuffer-outside-readbuffer.html": 0.2534,
+    "conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html": 0.2414,
+    "conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html": 0.2613,
+    "conformance2/rendering/blitframebuffer-scissor-enabled.html": 0.1608,
+    "conformance2/rendering/blitframebuffer-size-overflow.html": 0.2406,
+    "conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html": 0.3146,
+    "conformance2/rendering/blitframebuffer-stencil-only.html": 0.1123,
+    "conformance2/rendering/blitframebuffer-test.html": 0.2412,
+    "conformance2/rendering/blitframebuffer-unaffected-by-colormask.html": 0.0851,
+    "conformance2/rendering/canvas-resizing-with-pbo-bound.html": 0.295,
+    "conformance2/rendering/clear-func-buffer-type-match.html": 0.2631,
+    "conformance2/rendering/clear-srgb-color-buffer.html": 0.074,
+    "conformance2/rendering/clearbuffer-sub-source.html": 0.299,
+    "conformance2/rendering/clearbufferfv-with-alpha-false.html": 0.1812,
+    "conformance2/rendering/clipping-wide-points.html": 0.2878,
+    "conformance2/rendering/depth-stencil-feedback-loop.html": 0.2177,
+    "conformance2/rendering/draw-buffers-dirty-state-bug.html": 0.2744,
+    "conformance2/rendering/draw-buffers-driver-hang.html": 0.3108,
+    "conformance2/rendering/draw-buffers-sparse-output-locations.html": 0.0872,
+    "conformance2/rendering/draw-buffers.html": 0.2336,
+    "conformance2/rendering/draw-with-integer-texture-base-level.html": 0.3086,
+    "conformance2/rendering/element-index-uint.html": 0.365,
+    "conformance2/rendering/framebuffer-completeness-draw-framebuffer.html": 0.2737,
+    "conformance2/rendering/framebuffer-completeness-unaffected.html": 0.0859,
+    "conformance2/rendering/framebuffer-mismatched-attachment-targets.html": 0.3534,
+    "conformance2/rendering/framebuffer-render-to-layer-angle-issue.html": 0.1064,
+    "conformance2/rendering/framebuffer-render-to-layer.html": 0.3432,
+    "conformance2/rendering/framebuffer-texture-changing-base-level.html": 0.105,
+    "conformance2/rendering/framebuffer-texture-level1.html": 0.1705,
+    "conformance2/rendering/framebuffer-to-texture.html": 0.2161,
+    "conformance2/rendering/framebuffer-unsupported.html": 0.2451,
+    "conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html": 0.1064,
+    "conformance2/rendering/instanced-arrays.html": 0.1366,
+    "conformance2/rendering/instanced-rendering-bug.html": 0.5019,
+    "conformance2/rendering/instanced-rendering-large-divisor.html": 0.1641,
+    "conformance2/rendering/line-rendering-quality.html": 0.3623,
+    "conformance2/rendering/multisampling-depth-resolve.html": 0.0904,
+    "conformance2/rendering/multisampling-fragment-evaluation.html": 0.193,
+    "conformance2/rendering/out-of-bounds-index-buffers-after-copying.html": 0.2327,
+    "conformance2/rendering/rasterizer-discard-and-implicit-clear.html": 0.5876,
+    "conformance2/rendering/read-draw-when-missing-image.html": 0.2868,
+    "conformance2/rendering/rgb-format-support.html": 0.2283,
+    "conformance2/rendering/texture-switch-performance.html": 0,
+    "conformance2/rendering/uniform-block-buffer-size.html": 0.3299,
+    "conformance2/rendering/vertex-id-large-count.html": 0.5691,
+    "conformance2/rendering/vertex-id.html": 0.2575,
+    "conformance2/samplers/multi-context-sampler-test.html": 0.314,
+    "conformance2/samplers/sampler-drawing-test.html": 0.2457,
+    "conformance2/samplers/samplers.html": 0.134,
+    "conformance2/state/gl-enum-tests.html": 0.2009,
+    "conformance2/state/gl-get-calls.html": 0.2563,
+    "conformance2/state/gl-getstring.html": 0.2046,
+    "conformance2/state/gl-object-get-calls.html": 16.607,
+    "conformance2/sync/sync-webgl-specific.html": 6.1901,
+    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.1309,
+    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.9611,
+    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.7912,
+    "conformance2/textures/canvas/tex-2d-r16f-red-float.html": 1.0189,
+    "conformance2/textures/canvas/tex-2d-r16f-red-half_float.html": 1.115,
+    "conformance2/textures/canvas/tex-2d-r32f-red-float.html": 0.907,
+    "conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html": 0.8688,
+    "conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.2862,
+    "conformance2/textures/canvas/tex-2d-rg16f-rg-float.html": 1.2889,
+    "conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html": 0.9825,
+    "conformance2/textures/canvas/tex-2d-rg32f-rg-float.html": 1.1716,
+    "conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html": 1.1314,
+    "conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.2398,
+    "conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.02,
+    "conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html": 1.3651,
+    "conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html": 0.9258,
+    "conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html": 1.2748,
+    "conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.1693,
+    "conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.0792,
+    "conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.1352,
+    "conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.2385,
+    "conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 0.9622,
+    "conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.0056,
+    "conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html": 1.163,
+    "conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.2956,
+    "conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html": 1.1037,
+    "conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html": 0.7475,
+    "conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html": 1.1328,
+    "conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 1.2636,
+    "conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.8865,
+    "conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.1004,
+    "conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.8356,
+    "conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.1577,
+    "conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.1529,
+    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 5.3202,
+    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 5.2535,
+    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 5.5832,
+    "conformance2/textures/canvas/tex-3d-r16f-red-float.html": 5.6204,
+    "conformance2/textures/canvas/tex-3d-r16f-red-half_float.html": 5.2174,
+    "conformance2/textures/canvas/tex-3d-r32f-red-float.html": 5.3561,
+    "conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html": 5.3501,
+    "conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 5.3239,
+    "conformance2/textures/canvas/tex-3d-rg16f-rg-float.html": 5.3422,
+    "conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html": 5.4043,
+    "conformance2/textures/canvas/tex-3d-rg32f-rg-float.html": 5.533,
+    "conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html": 5.2682,
+    "conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 5.4221,
+    "conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 5.3596,
+    "conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html": 5.4425,
+    "conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html": 5.3515,
+    "conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html": 5.529,
+    "conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 5.5867,
+    "conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 5.3839,
+    "conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 5.3067,
+    "conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 5.4162,
+    "conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 5.4347,
+    "conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 5.2534,
+    "conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html": 5.2902,
+    "conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html": 5.4064,
+    "conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html": 5.4913,
+    "conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html": 5.3698,
+    "conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html": 5.3331,
+    "conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 5.3223,
+    "conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 5.5025,
+    "conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 5.3386,
+    "conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 5.4422,
+    "conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 5.4594,
+    "conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 5.4672,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.8518,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.9478,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.9596,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html": 0.8468,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html": 0.9018,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html": 0.8749,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html": 0.9901,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.2903,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html": 0.7853,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html": 0.9844,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html": 0.9343,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html": 0.9856,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.0343,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5704,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html": 0.8251,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html": 0.7242,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html": 0.9878,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html": 0.5726,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7363,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.7636,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.7817,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html": 0.8468,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.1423,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html": 0.9447,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html": 1.1481,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html": 0.8127,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html": 1.2459,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html": 0.8613,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html": 1.0398,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7137,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html": 0.6746,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.8519,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html": 0.8797,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.7614,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html": 1.186,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 1.4009,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.1498,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html": 0.9887,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html": 1.1039,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html": 1.182,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html": 1.0644,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html": 1.1639,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html": 0.9629,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html": 1.3599,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html": 1.3295,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html": 1.1178,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.9472,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.0541,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html": 1.126,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html": 1.0924,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html": 1.3172,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html": 1.1953,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 1.1949,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 1.0892,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.9646,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html": 1.0366,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 1.4788,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html": 1.1089,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html": 1.1241,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html": 1.3364,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html": 1.3624,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html": 1.2388,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html": 0.9146,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.1669,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html": 1.0162,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 1.0273,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html": 1.0838,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.976,
+    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.2425,
+    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.2245,
+    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.1988,
+    "conformance2/textures/image/tex-2d-r16f-red-float.html": 0.3363,
+    "conformance2/textures/image/tex-2d-r16f-red-half_float.html": 0.458,
+    "conformance2/textures/image/tex-2d-r32f-red-float.html": 0.4109,
+    "conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html": 0.4669,
+    "conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.3107,
+    "conformance2/textures/image/tex-2d-rg16f-rg-float.html": 0.4995,
+    "conformance2/textures/image/tex-2d-rg16f-rg-half_float.html": 0.4146,
+    "conformance2/textures/image/tex-2d-rg32f-rg-float.html": 0.265,
+    "conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html": 0.2046,
+    "conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.2203,
+    "conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3244,
+    "conformance2/textures/image/tex-2d-rgb16f-rgb-float.html": 0.2221,
+    "conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html": 0.483,
+    "conformance2/textures/image/tex-2d-rgb32f-rgb-float.html": 0.2012,
+    "conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.2233,
+    "conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3133,
+    "conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.1991,
+    "conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.19,
+    "conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.5385,
+    "conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3895,
+    "conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html": 0.1728,
+    "conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html": 0.3576,
+    "conformance2/textures/image/tex-2d-rgba16f-rgba-float.html": 0.353,
+    "conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html": 0.3158,
+    "conformance2/textures/image/tex-2d-rgba32f-rgba-float.html": 0.2366,
+    "conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.2141,
+    "conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3528,
+    "conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.2178,
+    "conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4849,
+    "conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.1858,
+    "conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.2154,
+    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.1704,
+    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.2498,
+    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.3652,
+    "conformance2/textures/image/tex-3d-r16f-red-float.html": 0.435,
+    "conformance2/textures/image/tex-3d-r16f-red-half_float.html": 0.3336,
+    "conformance2/textures/image/tex-3d-r32f-red-float.html": 0.1927,
+    "conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html": 0.1887,
+    "conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.1827,
+    "conformance2/textures/image/tex-3d-rg16f-rg-float.html": 0.1859,
+    "conformance2/textures/image/tex-3d-rg16f-rg-half_float.html": 0.1781,
+    "conformance2/textures/image/tex-3d-rg32f-rg-float.html": 0.2842,
+    "conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html": 0.1821,
+    "conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.5265,
+    "conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.184,
+    "conformance2/textures/image/tex-3d-rgb16f-rgb-float.html": 0.4035,
+    "conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html": 0.1829,
+    "conformance2/textures/image/tex-3d-rgb32f-rgb-float.html": 0.1624,
+    "conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.232,
+    "conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3744,
+    "conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.2895,
+    "conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3294,
+    "conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.35,
+    "conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1729,
+    "conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html": 0.1711,
+    "conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html": 0.1678,
+    "conformance2/textures/image/tex-3d-rgba16f-rgba-float.html": 0.186,
+    "conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html": 0.2181,
+    "conformance2/textures/image/tex-3d-rgba32f-rgba-float.html": 0.1869,
+    "conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3231,
+    "conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.1678,
+    "conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2349,
+    "conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.2844,
+    "conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.159,
+    "conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5209,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.4358,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.4678,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4808,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html": 0.2754,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html": 0.3043,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html": 0.2355,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html": 0.6814,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.3414,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html": 0.4883,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html": 0.2844,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html": 0.2079,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html": 0.4046,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.3091,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3153,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html": 0.2951,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html": 0.1956,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html": 0.2671,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html": 0.2942,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.2811,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.3018,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2624,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html": 0.2012,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4927,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html": 0.2557,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html": 0.4663,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html": 0.23,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html": 0.3059,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html": 0.3732,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html": 0.2823,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3784,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html": 0.475,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.2837,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html": 0.3141,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.2416,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.1437,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.1534,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.1754,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html": 0.204,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html": 0.1492,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html": 0.3414,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html": 0.3174,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.2099,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html": 0.3974,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html": 0.1282,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html": 0.1732,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html": 0.1169,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.1236,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.1514,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html": 0.1225,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html": 0.3417,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html": 0.1445,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html": 0.1556,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.1385,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.1397,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.1739,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html": 0.1799,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1474,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html": 0.1474,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html": 0.2102,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html": 0.1153,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html": 0.1508,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html": 0.1546,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3745,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3728,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html": 0.3513,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.337,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html": 0.1338,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.2382,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.5893,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.5505,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5219,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html": 0.5292,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html": 0.4992,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html": 0.747,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html": 0.4988,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.5694,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html": 0.5198,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html": 0.5672,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html": 0.5766,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html": 0.4855,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.5605,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5548,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html": 0.4611,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html": 0.7148,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html": 0.5659,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 0.5687,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4964,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.5545,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5695,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 0.7029,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3545,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html": 0.8085,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html": 0.4075,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html": 0.3696,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html": 0.5767,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html": 0.6353,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 0.5236,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5509,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 0.3978,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.5523,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 0.5612,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.489,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.4997,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.4646,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.2423,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html": 0.407,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html": 0.1535,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html": 0.5779,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html": 0.5481,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.5471,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html": 0.4367,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html": 0.5948,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html": 0.24,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html": 0.5041,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.4151,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.1531,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html": 0.2824,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html": 0.2042,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html": 0.4285,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 0.4463,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4125,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.4469,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.4351,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 0.412,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4958,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html": 0.3677,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html": 0.4884,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html": 0.2203,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html": 0.4153,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html": 0.4416,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3427,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.2932,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2172,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.1985,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 0.5172,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.1482,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.1875,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.1576,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.1422,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html": 0.2937,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html": 0.2154,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html": 0.1625,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html": 0.3206,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.2262,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html": 0.1733,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html": 0.1886,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html": 0.2557,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html": 0.2066,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.2013,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3829,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html": 0.2031,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html": 0.1581,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html": 0.2387,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.1564,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.2097,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.1913,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.327,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.157,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1674,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html": 0.2127,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html": 0.1863,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html": 0.1733,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html": 0.154,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html": 0.1701,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.3447,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.2669,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.1643,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.1961,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.2748,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.2612,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3347,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.1316,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.126,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html": 0.1616,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html": 0.1324,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html": 0.1215,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html": 0.1274,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.1276,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html": 0.1639,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html": 0.1976,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html": 0.166,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html": 0.1598,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.1315,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3348,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html": 0.2365,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html": 0.2623,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html": 0.1391,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.1796,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.1472,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.1138,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2849,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.1256,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1676,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html": 0.1292,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html": 0.1356,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html": 0.1239,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html": 0.1352,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html": 0.1339,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.2451,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3646,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.1556,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3482,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.1546,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.1587,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.1377,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.1301,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.3484,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html": 0.2428,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html": 0.2193,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html": 0.1627,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html": 0.1303,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.1467,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html": 0.1594,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html": 0.1284,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html": 0.1707,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html": 0.1802,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.1712,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.2673,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html": 0.1634,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html": 0.1916,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html": 0.1819,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html": 0.2084,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.1582,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.2022,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2344,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html": 0.2559,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1501,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html": 0.388,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html": 0.1557,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html": 0.1414,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html": 0.2424,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html": 0.3014,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html": 0.145,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.1598,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html": 0.1496,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.1681,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html": 0.205,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.1728,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.1614,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.1675,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.3939,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html": 0.1208,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html": 0.143,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html": 0.109,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html": 0.1449,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.0993,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html": 0.1164,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html": 0.1075,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html": 0.0969,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html": 0.1211,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.2358,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.1139,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html": 0.1162,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html": 0.1182,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html": 0.2478,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html": 0.1451,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.1593,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.0956,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3139,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html": 0.1182,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1428,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html": 0.1455,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html": 0.1087,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html": 0.1617,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html": 0.3724,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html": 0.114,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html": 0.0928,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.1427,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html": 0.1425,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.2781,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html": 0.3349,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.128,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.1199,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.1677,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.1469,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html": 0.1915,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html": 0.156,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html": 0.1553,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html": 0.2373,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.15,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html": 0.152,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html": 0.1496,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html": 0.2221,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html": 0.1912,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.1625,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.2052,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html": 0.1729,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html": 0.165,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html": 0.185,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html": 0.2904,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.1706,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.2327,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.1901,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html": 0.1774,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1988,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html": 0.1843,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html": 0.1927,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html": 0.3088,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html": 0.2027,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html": 0.2088,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html": 0.1525,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.1478,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html": 0.1645,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.1643,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html": 0.1915,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.1658,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.1143,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3238,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.1424,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html": 0.1563,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html": 0.1551,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html": 0.1258,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html": 0.1636,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.1372,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html": 0.1161,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html": 0.1292,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html": 0.1137,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html": 0.2731,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.2607,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.1352,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html": 0.1473,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html": 0.136,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html": 0.1142,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html": 0.1443,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.1362,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.1444,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.1104,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html": 0.13,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1326,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html": 0.1555,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html": 0.3204,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html": 0.1418,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html": 0.1645,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html": 0.1251,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html": 0.1244,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.1272,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html": 0.0964,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.1361,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html": 0.1304,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.1362,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.8095,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.9812,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.8749,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html": 0.7281,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html": 0.6756,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html": 0.6288,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html": 0.6289,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.6751,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html": 0.6564,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html": 0.6606,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html": 0.7459,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html": 0.5564,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7562,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.7654,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html": 0.6789,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html": 0.618,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html": 0.8397,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html": 0.6957,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7811,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.7172,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.7917,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html": 0.7009,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6659,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html": 0.7328,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html": 0.7254,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html": 0.7031,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html": 0.6882,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html": 0.7207,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7551,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5935,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html": 0.5291,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.785,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7569,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.8861,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.6815,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.7788,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6538,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html": 0.6294,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html": 0.7324,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html": 0.7218,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html": 0.7118,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.7977,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html": 0.7278,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html": 0.6925,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html": 0.5984,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html": 0.8075,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.7251,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.746,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html": 0.661,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html": 0.7244,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html": 0.851,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html": 0.6859,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.8159,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.6882,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.6956,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html": 0.7042,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.7659,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html": 0.7507,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html": 0.737,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html": 0.66,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html": 0.5358,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html": 0.8292,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html": 0.6462,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.8026,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html": 0.6801,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.754,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html": 0.5972,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.7253,
+    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.4662,
+    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.5634,
+    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.2913,
+    "conformance2/textures/image_data/tex-2d-r16f-red-float.html": 0.2925,
+    "conformance2/textures/image_data/tex-2d-r16f-red-half_float.html": 0.3071,
+    "conformance2/textures/image_data/tex-2d-r32f-red-float.html": 0.3043,
+    "conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html": 0.3792,
+    "conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.2742,
+    "conformance2/textures/image_data/tex-2d-rg16f-rg-float.html": 0.3303,
+    "conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html": 0.444,
+    "conformance2/textures/image_data/tex-2d-rg32f-rg-float.html": 0.2732,
+    "conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html": 0.2941,
+    "conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.2499,
+    "conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3745,
+    "conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html": 0.4525,
+    "conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html": 0.2851,
+    "conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html": 0.3888,
+    "conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html": 0.4976,
+    "conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.2495,
+    "conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.3594,
+    "conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3546,
+    "conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html": 0.2665,
+    "conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.2534,
+    "conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html": 0.3262,
+    "conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html": 0.3711,
+    "conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html": 0.4525,
+    "conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html": 0.2616,
+    "conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html": 0.4267,
+    "conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html": 0.2641,
+    "conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.2536,
+    "conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html": 0.3228,
+    "conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.2665,
+    "conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html": 0.5627,
+    "conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.265,
+    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.2747,
+    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.4318,
+    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.2584,
+    "conformance2/textures/image_data/tex-3d-r16f-red-float.html": 0.3447,
+    "conformance2/textures/image_data/tex-3d-r16f-red-half_float.html": 0.3484,
+    "conformance2/textures/image_data/tex-3d-r32f-red-float.html": 0.2725,
+    "conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html": 0.5263,
+    "conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.2506,
+    "conformance2/textures/image_data/tex-3d-rg16f-rg-float.html": 0.2652,
+    "conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html": 0.2714,
+    "conformance2/textures/image_data/tex-3d-rg32f-rg-float.html": 0.2259,
+    "conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html": 0.4899,
+    "conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.2724,
+    "conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4576,
+    "conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html": 0.2695,
+    "conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html": 0.1638,
+    "conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html": 0.3844,
+    "conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html": 0.2601,
+    "conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4442,
+    "conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.2184,
+    "conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.261,
+    "conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html": 0.2434,
+    "conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.2436,
+    "conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html": 0.2428,
+    "conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html": 0.2472,
+    "conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html": 0.3846,
+    "conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html": 0.448,
+    "conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html": 0.3926,
+    "conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3943,
+    "conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.2618,
+    "conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2631,
+    "conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3996,
+    "conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html": 0.2053,
+    "conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.2306,
+    "conformance2/textures/misc/active-3d-texture-bug.html": 0.0772,
+    "conformance2/textures/misc/angle-stuck-depth-textures.html": 0.3597,
+    "conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html": 0.0989,
+    "conformance2/textures/misc/compressed-tex-from-pbo-crash.html": 0.069,
+    "conformance2/textures/misc/compressed-tex-image.html": 0.2267,
+    "conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html": 0.081,
+    "conformance2/textures/misc/copy-texture-cube-map-bug.html": 0.0636,
+    "conformance2/textures/misc/copy-texture-image-luma-format.html": 1.4487,
+    "conformance2/textures/misc/copy-texture-image-same-texture.html": 0.1113,
+    "conformance2/textures/misc/copy-texture-image-webgl-specific.html": 0.0998,
+    "conformance2/textures/misc/copy-texture-image.html": 0.1679,
+    "conformance2/textures/misc/generate-mipmap-with-large-base-level.html": 0.0755,
+    "conformance2/textures/misc/gl-get-tex-parameter.html": 0.134,
+    "conformance2/textures/misc/immutable-tex-render-feedback.html": 1.2116,
+    "conformance2/textures/misc/integer-cubemap-specification-order-bug.html": 0.3908,
+    "conformance2/textures/misc/integer-cubemap-texture-sampling.html": 0.7474,
+    "conformance2/textures/misc/mipmap-fbo.html": 0.0621,
+    "conformance2/textures/misc/npot-video-sizing.html": 0.1387,
+    "conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.1623,
+    "conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html": 0.0814,
+    "conformance2/textures/misc/tex-3d-size-limit.html": 0.3,
+    "conformance2/textures/misc/tex-base-level-bug.html": 0.0697,
+    "conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html": 0.1671,
+    "conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html": 0.3627,
+    "conformance2/textures/misc/tex-image-with-bad-args.html": 0.0881,
+    "conformance2/textures/misc/tex-image-with-different-data-source.html": 0.0931,
+    "conformance2/textures/misc/tex-input-validation.html": 0.1134,
+    "conformance2/textures/misc/tex-mipmap-levels.html": 0.1208,
+    "conformance2/textures/misc/tex-new-formats.html": 0.4209,
+    "conformance2/textures/misc/tex-srgb-mipmap.html": 0.1719,
+    "conformance2/textures/misc/tex-storage-2d.html": 0.1557,
+    "conformance2/textures/misc/tex-storage-and-subimage-3d.html": 0.3088,
+    "conformance2/textures/misc/tex-storage-compressed-formats.html": 0.11,
+    "conformance2/textures/misc/tex-subimage3d-canvas-bug.html": 0.1321,
+    "conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html": 0.241,
+    "conformance2/textures/misc/tex-unpack-params-imagedata.html": 0.3526,
+    "conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html": 0.2983,
+    "conformance2/textures/misc/tex-unpack-params.html": 0.4257,
+    "conformance2/textures/misc/texel-fetch-undefined.html": 0.0976,
+    "conformance2/textures/misc/texture-npot.html": 0.2951,
+    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.2174,
+    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.1231,
+    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.1217,
+    "conformance2/textures/svg_image/tex-2d-r16f-red-float.html": 0.3173,
+    "conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html": 0.1513,
+    "conformance2/textures/svg_image/tex-2d-r32f-red-float.html": 0.1397,
+    "conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html": 0.1357,
+    "conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.1479,
+    "conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html": 0.1107,
+    "conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html": 0.1261,
+    "conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html": 0.3201,
+    "conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html": 0.1111,
+    "conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.1181,
+    "conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.2832,
+    "conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html": 0.3382,
+    "conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html": 0.2965,
+    "conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html": 0.3037,
+    "conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.2587,
+    "conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3958,
+    "conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.1282,
+    "conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.1114,
+    "conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.1662,
+    "conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1013,
+    "conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html": 0.1113,
+    "conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html": 0.1176,
+    "conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html": 0.1277,
+    "conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html": 0.1147,
+    "conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html": 0.1217,
+    "conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.1455,
+    "conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.1071,
+    "conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.1064,
+    "conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.152,
+    "conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.1123,
+    "conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.1778,
+    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.1134,
+    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.2968,
+    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.113,
+    "conformance2/textures/svg_image/tex-3d-r16f-red-float.html": 0.1299,
+    "conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html": 0.1579,
+    "conformance2/textures/svg_image/tex-3d-r32f-red-float.html": 0.1052,
+    "conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html": 0.0973,
+    "conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.12,
+    "conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html": 0.0935,
+    "conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html": 0.1076,
+    "conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html": 0.1072,
+    "conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html": 0.0967,
+    "conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.0994,
+    "conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.0984,
+    "conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html": 0.1302,
+    "conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html": 0.1457,
+    "conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html": 0.2074,
+    "conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.1461,
+    "conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.1158,
+    "conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.1455,
+    "conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.093,
+    "conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.1283,
+    "conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.1288,
+    "conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html": 0.0974,
+    "conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html": 0.1139,
+    "conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html": 0.0958,
+    "conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html": 0.0951,
+    "conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html": 0.1135,
+    "conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.2238,
+    "conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.0908,
+    "conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2404,
+    "conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.1021,
+    "conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.0906,
+    "conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.0827,
+    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.4033,
+    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.1597,
+    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.4259,
+    "conformance2/textures/video/tex-2d-r16f-red-float.html": 1.2689,
+    "conformance2/textures/video/tex-2d-r16f-red-half_float.html": 1.2765,
+    "conformance2/textures/video/tex-2d-r32f-red-float.html": 1.1775,
+    "conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html": 1.3637,
+    "conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.1491,
+    "conformance2/textures/video/tex-2d-rg16f-rg-float.html": 1.4853,
+    "conformance2/textures/video/tex-2d-rg16f-rg-half_float.html": 1.3131,
+    "conformance2/textures/video/tex-2d-rg32f-rg-float.html": 1.1534,
+    "conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html": 1.3584,
+    "conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.2835,
+    "conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.3342,
+    "conformance2/textures/video/tex-2d-rgb16f-rgb-float.html": 1.2337,
+    "conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html": 1.3033,
+    "conformance2/textures/video/tex-2d-rgb32f-rgb-float.html": 1.2406,
+    "conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html": 1.1043,
+    "conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.2286,
+    "conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.2413,
+    "conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.6072,
+    "conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html": 1.3264,
+    "conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.3641,
+    "conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html": 1.4547,
+    "conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html": 1.1804,
+    "conformance2/textures/video/tex-2d-rgba16f-rgba-float.html": 1.2953,
+    "conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html": 1.0759,
+    "conformance2/textures/video/tex-2d-rgba32f-rgba-float.html": 1.3193,
+    "conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html": 1.2061,
+    "conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.4028,
+    "conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html": 1.2991,
+    "conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.252,
+    "conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html": 1.2978,
+    "conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.0255,
+    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html": 1.1531,
+    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 1.4456,
+    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.2704,
+    "conformance2/textures/video/tex-3d-r16f-red-float.html": 1.2646,
+    "conformance2/textures/video/tex-3d-r16f-red-half_float.html": 1.1582,
+    "conformance2/textures/video/tex-3d-r32f-red-float.html": 1.2747,
+    "conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html": 1.2171,
+    "conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html": 1.2426,
+    "conformance2/textures/video/tex-3d-rg16f-rg-float.html": 1.0862,
+    "conformance2/textures/video/tex-3d-rg16f-rg-half_float.html": 1.1875,
+    "conformance2/textures/video/tex-3d-rg32f-rg-float.html": 1.1318,
+    "conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html": 1.1401,
+    "conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 1.1249,
+    "conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.341,
+    "conformance2/textures/video/tex-3d-rgb16f-rgb-float.html": 1.1708,
+    "conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html": 1.1095,
+    "conformance2/textures/video/tex-3d-rgb32f-rgb-float.html": 1.1778,
+    "conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html": 1.3689,
+    "conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 1.1714,
+    "conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 1.2259,
+    "conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.3201,
+    "conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html": 1.3663,
+    "conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 1.3336,
+    "conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html": 1.4072,
+    "conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html": 1.2832,
+    "conformance2/textures/video/tex-3d-rgba16f-rgba-float.html": 1.2549,
+    "conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html": 1.0687,
+    "conformance2/textures/video/tex-3d-rgba32f-rgba-float.html": 1.3727,
+    "conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html": 1.324,
+    "conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.1846,
+    "conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html": 1.2855,
+    "conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 1.1265,
+    "conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html": 1.2346,
+    "conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 1.2599,
+    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.0756,
+    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.3545,
+    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.2859,
+    "conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html": 1.4153,
+    "conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html": 1.3906,
+    "conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html": 1.3376,
+    "conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html": 1.6278,
+    "conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.7461,
+    "conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html": 1.0805,
+    "conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html": 1.4552,
+    "conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html": 1.0593,
+    "conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html": 1.1902,
+    "conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.6956,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.5966,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html": 1.4198,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html": 1.5451,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html": 1.2576,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.2625,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.2469,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.8867,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.6688,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 1.4717,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.4997,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html": 1.5503,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.4675,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html": 1.1233,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html": 1.4464,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html": 1.512,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 1.3105,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.2877,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.1764,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 2.0309,
+    "conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.017,
+    "conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.3229,
+    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 5.623,
+    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 5.3753,
+    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 5.4413,
+    "conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html": 5.3463,
+    "conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html": 5.3006,
+    "conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html": 5.3311,
+    "conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html": 5.4752,
+    "conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 5.4733,
+    "conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html": 5.2895,
+    "conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html": 5.7472,
+    "conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html": 5.2717,
+    "conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html": 5.3733,
+    "conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 5.7421,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 5.4282,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html": 5.5433,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html": 5.4229,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html": 5.4614,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 5.2525,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 5.3095,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 5.4158,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 5.3964,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 5.2582,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 5.3598,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html": 5.3764,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html": 5.3628,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html": 5.4795,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html": 5.2638,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html": 5.4811,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 5.746,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 5.4948,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 5.3419,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 5.4034,
+    "conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 5.2637,
+    "conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 5.2565,
+    "conformance2/transform_feedback/default_transform_feedback.html": 0.0946,
+    "conformance2/transform_feedback/non-existent-varying.html": 0.0723,
+    "conformance2/transform_feedback/same-buffer-two-binding-points.html": 0.0923,
+    "conformance2/transform_feedback/simultaneous_binding.html": 0.1312,
+    "conformance2/transform_feedback/switching-objects.html": 0.1275,
+    "conformance2/transform_feedback/too-small-buffers.html": 0.1391,
+    "conformance2/transform_feedback/transform_feedback.html": 1.1498,
+    "conformance2/transform_feedback/two-unreferenced-varyings.html": 0.088,
+    "conformance2/transform_feedback/unwritten-output-defaults-to-zero.html": 0.1532,
+    "conformance2/uniforms/dependent-buffer-change.html": 0.0926,
+    "conformance2/uniforms/draw-with-uniform-blocks.html": 0.0798,
+    "conformance2/uniforms/gl-uniform-arrays-sub-source.html": 0.4003,
+    "conformance2/uniforms/incompatible-texture-type-for-sampler.html": 2.3807,
+    "conformance2/uniforms/large-uniform-buffers.html": 0.0777,
+    "conformance2/uniforms/query-uniform-blocks-after-shader-detach.html": 0.0957,
+    "conformance2/uniforms/simple-buffer-change.html": 0.1201,
+    "conformance2/uniforms/uniform-blocks-with-arrays.html": 0.1267,
+    "conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html": 0.1526,
+    "conformance2/vertex_arrays/vertex-array-object.html": 0.1791,
+    "deqp/data/gles3/shaders/arrays.html": 4.2564,
+    "deqp/data/gles3/shaders/conditionals.html": 0.9496,
+    "deqp/data/gles3/shaders/constant_expressions.html": 1.597,
+    "deqp/data/gles3/shaders/constants.html": 3.6345,
+    "deqp/data/gles3/shaders/conversions_matrix_combine.html": 10.1076,
+    "deqp/data/gles3/shaders/conversions_matrix_to_matrix.html": 6.6582,
+    "deqp/data/gles3/shaders/conversions_scalar_to_matrix.html": 3.5385,
+    "deqp/data/gles3/shaders/conversions_scalar_to_scalar.html": 1.4969,
+    "deqp/data/gles3/shaders/conversions_scalar_to_vector.html": 4.6979,
+    "deqp/data/gles3/shaders/conversions_vector_combine.html": 15.6718,
+    "deqp/data/gles3/shaders/conversions_vector_illegal.html": 1.1198,
+    "deqp/data/gles3/shaders/conversions_vector_to_scalar.html": 4.718,
+    "deqp/data/gles3/shaders/conversions_vector_to_vector.html": 7.7005,
+    "deqp/data/gles3/shaders/declarations.html": 0.8172,
+    "deqp/data/gles3/shaders/fragdata.html": 0.4339,
+    "deqp/data/gles3/shaders/functions.html": 7.9376,
+    "deqp/data/gles3/shaders/invalid_texture_functions.html": 1.0909,
+    "deqp/data/gles3/shaders/keywords.html": 2.8813,
+    "deqp/data/gles3/shaders/linkage.html": 4.8437,
+    "deqp/data/gles3/shaders/negative.html": 0.2335,
+    "deqp/data/gles3/shaders/preprocessor.html": 11.0219,
+    "deqp/data/gles3/shaders/qualification_order.html": 0.9677,
+    "deqp/data/gles3/shaders/scoping.html": 1.5249,
+    "deqp/data/gles3/shaders/switch.html": 0.7808,
+    "deqp/data/gles3/shaders/swizzles_bvec2.html": 1.9061,
+    "deqp/data/gles3/shaders/swizzles_bvec3.html": 3.7073,
+    "deqp/data/gles3/shaders/swizzles_bvec4.html": 4.1392,
+    "deqp/data/gles3/shaders/swizzles_ivec2.html": 1.8164,
+    "deqp/data/gles3/shaders/swizzles_ivec3.html": 2.9247,
+    "deqp/data/gles3/shaders/swizzles_ivec4.html": 4.0879,
+    "deqp/data/gles3/shaders/swizzles_vec2.html": 2.0529,
+    "deqp/data/gles3/shaders/swizzles_vec3.html": 3.0245,
+    "deqp/data/gles3/shaders/swizzles_vec4.html": 4.0455,
+    "deqp/framework/opengl/simplereference/referencecontext.html": 1.0186,
+    "deqp/functional/gles3/attriblocation.html": 3.9772,
+    "deqp/functional/gles3/booleanstatequery.html": 0.2136,
+    "deqp/functional/gles3/buffercopy.html": 3.5459,
+    "deqp/functional/gles3/bufferobjectquery.html": 0.4909,
+    "deqp/functional/gles3/clipping.html": 4.8554,
+    "deqp/functional/gles3/defaultvertexattribute.html": 9.7482,
+    "deqp/functional/gles3/draw/draw_arrays.html": 11.8995,
+    "deqp/functional/gles3/draw/draw_arrays_instanced.html": 14.7287,
+    "deqp/functional/gles3/draw/draw_elements.html": 9.5415,
+    "deqp/functional/gles3/draw/draw_elements_instanced.html": 12.5562,
+    "deqp/functional/gles3/draw/draw_range_elements.html": 5.0563,
+    "deqp/functional/gles3/draw/instancing.html": 0.7663,
+    "deqp/functional/gles3/draw/random.html": 9.3324,
+    "deqp/functional/gles3/fbocolorbuffer/blend.html": 4.7819,
+    "deqp/functional/gles3/fbocolorbuffer/clear.html": 1.7993,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_00.html": 6.034,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_01.html": 5.5091,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_02.html": 5.4948,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_03.html": 5.6675,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_04.html": 6.0982,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_05.html": 5.4592,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html": 6.3586,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html": 5.6951,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html": 5.7882,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html": 5.9588,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html": 6.694,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html": 5.8601,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_00.html": 6.0239,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_01.html": 5.989,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_02.html": 6.3714,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_03.html": 7.2827,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_04.html": 5.8931,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_05.html": 5.3397,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_00.html": 6.9804,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_01.html": 7.0854,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_02.html": 6.3043,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_03.html": 7.1964,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_04.html": 7.2811,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_05.html": 6.263,
+    "deqp/functional/gles3/fbocompleteness.html": 4.0518,
+    "deqp/functional/gles3/fbodepthbuffer.html": 4.1901,
+    "deqp/functional/gles3/fboinvalidate/default.html": 10.3527,
+    "deqp/functional/gles3/fboinvalidate/format_00.html": 4.4062,
+    "deqp/functional/gles3/fboinvalidate/format_01.html": 4.0083,
+    "deqp/functional/gles3/fboinvalidate/format_02.html": 4.2119,
+    "deqp/functional/gles3/fboinvalidate/sub.html": 6.4434,
+    "deqp/functional/gles3/fboinvalidate/target.html": 13.4971,
+    "deqp/functional/gles3/fboinvalidate/whole.html": 7.34,
+    "deqp/functional/gles3/fbomultisample.2_samples.html": 13.0491,
+    "deqp/functional/gles3/fbomultisample.4_samples.html": 11.728,
+    "deqp/functional/gles3/fbomultisample.8_samples.html": 11.8386,
+    "deqp/functional/gles3/fborender/recreate_color_00.html": 5.0895,
+    "deqp/functional/gles3/fborender/recreate_color_01.html": 4.4185,
+    "deqp/functional/gles3/fborender/recreate_color_02.html": 4.2067,
+    "deqp/functional/gles3/fborender/recreate_color_03.html": 4.4749,
+    "deqp/functional/gles3/fborender/recreate_color_04.html": 4.3622,
+    "deqp/functional/gles3/fborender/recreate_color_05.html": 4.3829,
+    "deqp/functional/gles3/fborender/recreate_color_06.html": 4.9436,
+    "deqp/functional/gles3/fborender/recreate_depth_stencil.html": 5.5767,
+    "deqp/functional/gles3/fborender/resize_00.html": 4.6723,
+    "deqp/functional/gles3/fborender/resize_01.html": 3.8906,
+    "deqp/functional/gles3/fborender/resize_02.html": 3.9737,
+    "deqp/functional/gles3/fborender/resize_03.html": 8.089,
+    "deqp/functional/gles3/fborender/shared_colorbuffer_00.html": 6.6807,
+    "deqp/functional/gles3/fborender/shared_colorbuffer_01.html": 6.5633,
+    "deqp/functional/gles3/fborender/shared_colorbuffer_02.html": 6.9954,
+    "deqp/functional/gles3/fborender/shared_colorbuffer_clear.html": 2.3302,
+    "deqp/functional/gles3/fborender/shared_depth_stencil.html": 4.9313,
+    "deqp/functional/gles3/fborender/stencil_clear.html": 1.898,
+    "deqp/functional/gles3/fbostatequery.html": 0.2669,
+    "deqp/functional/gles3/fbostencilbuffer.html": 3.4918,
+    "deqp/functional/gles3/floatstatequery.html": 0.4461,
+    "deqp/functional/gles3/fragdepth.html": 1.6243,
+    "deqp/functional/gles3/fragmentoutput/array.fixed.html": 3.0145,
+    "deqp/functional/gles3/fragmentoutput/array.float.html": 5.871,
+    "deqp/functional/gles3/fragmentoutput/array.int.html": 5.6197,
+    "deqp/functional/gles3/fragmentoutput/array.uint.html": 5.8505,
+    "deqp/functional/gles3/fragmentoutput/basic.fixed.html": 2.3158,
+    "deqp/functional/gles3/fragmentoutput/basic.float.html": 3.025,
+    "deqp/functional/gles3/fragmentoutput/basic.int.html": 2.8462,
+    "deqp/functional/gles3/fragmentoutput/basic.uint.html": 3.1316,
+    "deqp/functional/gles3/fragmentoutput/random_00.html": 3.1125,
+    "deqp/functional/gles3/fragmentoutput/random_01.html": 3.1887,
+    "deqp/functional/gles3/fragmentoutput/random_02.html": 2.8506,
+    "deqp/functional/gles3/framebufferblit/conversion_00.html": 2.5574,
+    "deqp/functional/gles3/framebufferblit/conversion_01.html": 2.6565,
+    "deqp/functional/gles3/framebufferblit/conversion_02.html": 2.3069,
+    "deqp/functional/gles3/framebufferblit/conversion_03.html": 2.8235,
+    "deqp/functional/gles3/framebufferblit/conversion_04.html": 3.8064,
+    "deqp/functional/gles3/framebufferblit/conversion_05.html": 2.5075,
+    "deqp/functional/gles3/framebufferblit/conversion_06.html": 2.9581,
+    "deqp/functional/gles3/framebufferblit/conversion_07.html": 4.4001,
+    "deqp/functional/gles3/framebufferblit/conversion_08.html": 3.9459,
+    "deqp/functional/gles3/framebufferblit/conversion_09.html": 2.8892,
+    "deqp/functional/gles3/framebufferblit/conversion_10.html": 3.7102,
+    "deqp/functional/gles3/framebufferblit/conversion_11.html": 3.5481,
+    "deqp/functional/gles3/framebufferblit/conversion_12.html": 3.929,
+    "deqp/functional/gles3/framebufferblit/conversion_13.html": 3.9645,
+    "deqp/functional/gles3/framebufferblit/conversion_14.html": 2.6469,
+    "deqp/functional/gles3/framebufferblit/conversion_15.html": 3.0767,
+    "deqp/functional/gles3/framebufferblit/conversion_16.html": 2.6857,
+    "deqp/functional/gles3/framebufferblit/conversion_17.html": 2.7574,
+    "deqp/functional/gles3/framebufferblit/conversion_18.html": 3.4324,
+    "deqp/functional/gles3/framebufferblit/conversion_19.html": 2.4482,
+    "deqp/functional/gles3/framebufferblit/conversion_20.html": 2.9727,
+    "deqp/functional/gles3/framebufferblit/conversion_21.html": 3.0963,
+    "deqp/functional/gles3/framebufferblit/conversion_22.html": 3.1139,
+    "deqp/functional/gles3/framebufferblit/conversion_23.html": 2.4968,
+    "deqp/functional/gles3/framebufferblit/conversion_24.html": 2.6575,
+    "deqp/functional/gles3/framebufferblit/conversion_25.html": 3.6979,
+    "deqp/functional/gles3/framebufferblit/conversion_26.html": 2.4233,
+    "deqp/functional/gles3/framebufferblit/conversion_27.html": 2.7298,
+    "deqp/functional/gles3/framebufferblit/conversion_28.html": 3.6733,
+    "deqp/functional/gles3/framebufferblit/conversion_29.html": 3.8259,
+    "deqp/functional/gles3/framebufferblit/conversion_30.html": 4.1329,
+    "deqp/functional/gles3/framebufferblit/conversion_31.html": 3.9988,
+    "deqp/functional/gles3/framebufferblit/conversion_32.html": 3.8313,
+    "deqp/functional/gles3/framebufferblit/conversion_33.html": 3.9074,
+    "deqp/functional/gles3/framebufferblit/conversion_34.html": 3.8663,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_00.html": 4.4167,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_01.html": 5.554,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_02.html": 3.1668,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_03.html": 4.3217,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_04.html": 10.0441,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_05.html": 5.3556,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_06.html": 5.0696,
+    "deqp/functional/gles3/framebufferblit/depth_stencil.html": 6.6953,
+    "deqp/functional/gles3/framebufferblit/rect_00.html": 3.3539,
+    "deqp/functional/gles3/framebufferblit/rect_01.html": 3.92,
+    "deqp/functional/gles3/framebufferblit/rect_02.html": 2.5329,
+    "deqp/functional/gles3/framebufferblit/rect_03.html": 0.8868,
+    "deqp/functional/gles3/framebufferblit/rect_04.html": 1.1867,
+    "deqp/functional/gles3/framebufferblit/rect_05.html": 0.2149,
+    "deqp/functional/gles3/framebufferblit/rect_06.html": 0.2477,
+    "deqp/functional/gles3/indexedstatequery.html": 0.2672,
+    "deqp/functional/gles3/instancedrendering.html": 6.0157,
+    "deqp/functional/gles3/integerstatequery.html": 0.9475,
+    "deqp/functional/gles3/internalformatquery.html": 0.4393,
+    "deqp/functional/gles3/lifetime.html": 0.5662,
+    "deqp/functional/gles3/multisample/default_fbo.html": 0.371,
+    "deqp/functional/gles3/multisample/fbo_4_samples.html": 5.2223,
+    "deqp/functional/gles3/multisample/fbo_8_samples.html": 9.2253,
+    "deqp/functional/gles3/multisample/fbo_max_samples.html": 9.2144,
+    "deqp/functional/gles3/negativebufferapi.html": 0.4987,
+    "deqp/functional/gles3/negativefragmentapi.html": 0.3093,
+    "deqp/functional/gles3/negativeshaderapi.html": 0.6439,
+    "deqp/functional/gles3/negativestateapi.html": 0.4763,
+    "deqp/functional/gles3/negativetextureapi.html": 0.7913,
+    "deqp/functional/gles3/negativevertexarrayapi.html": 0.4843,
+    "deqp/functional/gles3/occlusionquery_conservative.html": 13.1113,
+    "deqp/functional/gles3/occlusionquery_strict.html": 12.7297,
+    "deqp/functional/gles3/pixelbufferobject.html": 2.0925,
+    "deqp/functional/gles3/primitiverestart/00.html": 2.873,
+    "deqp/functional/gles3/primitiverestart/01.html": 2.6296,
+    "deqp/functional/gles3/primitiverestart/02.html": 2.6711,
+    "deqp/functional/gles3/primitiverestart/03.html": 2.6562,
+    "deqp/functional/gles3/primitiverestart/04.html": 2.8102,
+    "deqp/functional/gles3/primitiverestart/05.html": 2.679,
+    "deqp/functional/gles3/primitiverestart/06.html": 2.8396,
+    "deqp/functional/gles3/primitiverestart/07.html": 2.6154,
+    "deqp/functional/gles3/rasterizerdiscard.html": 2.8013,
+    "deqp/functional/gles3/rbostatequery.html": 0.343,
+    "deqp/functional/gles3/readpixel.html": 1.0972,
+    "deqp/functional/gles3/samplerobject.html": 2.3203,
+    "deqp/functional/gles3/samplerstatequery.html": 0.2016,
+    "deqp/functional/gles3/shaderapi.html": 0.4336,
+    "deqp/functional/gles3/shaderbuiltinvar.html": 2.2499,
+    "deqp/functional/gles3/shadercommonfunction.html": 9.9136,
+    "deqp/functional/gles3/shaderderivate_dfdx.html": 6.3938,
+    "deqp/functional/gles3/shaderderivate_dfdy.html": 5.6427,
+    "deqp/functional/gles3/shaderderivate_fwidth.html": 6.1622,
+    "deqp/functional/gles3/shaderindexing/mat_00.html": 8.6876,
+    "deqp/functional/gles3/shaderindexing/mat_01.html": 8.6191,
+    "deqp/functional/gles3/shaderindexing/mat_02.html": 10.325,
+    "deqp/functional/gles3/shaderindexing/tmp.html": 11.8754,
+    "deqp/functional/gles3/shaderindexing/uniform.html": 3.5122,
+    "deqp/functional/gles3/shaderindexing/varying.html": 6.1786,
+    "deqp/functional/gles3/shaderindexing/vec2.html": 6.7873,
+    "deqp/functional/gles3/shaderindexing/vec3.html": 6.6287,
+    "deqp/functional/gles3/shaderindexing/vec4.html": 6.8774,
+    "deqp/functional/gles3/shaderloop_do_while.html": 16.1482,
+    "deqp/functional/gles3/shaderloop_for.html": 16.6266,
+    "deqp/functional/gles3/shaderloop_while.html": 16.1012,
+    "deqp/functional/gles3/shadermatrix/add_assign.html": 7.8793,
+    "deqp/functional/gles3/shadermatrix/add_const.html": 14.0307,
+    "deqp/functional/gles3/shadermatrix/add_dynamic.html": 14.8518,
+    "deqp/functional/gles3/shadermatrix/add_uniform.html": 14.0436,
+    "deqp/functional/gles3/shadermatrix/determinant.html": 2.8401,
+    "deqp/functional/gles3/shadermatrix/div_assign.html": 7.9849,
+    "deqp/functional/gles3/shadermatrix/div_const.html": 14.0561,
+    "deqp/functional/gles3/shadermatrix/div_dynamic.html": 21.6014,
+    "deqp/functional/gles3/shadermatrix/div_uniform.html": 13.9682,
+    "deqp/functional/gles3/shadermatrix/inverse.html": 6.2836,
+    "deqp/functional/gles3/shadermatrix/matrixcompmult.html": 8.0852,
+    "deqp/functional/gles3/shadermatrix/mul_assign.html": 3.1466,
+    "deqp/functional/gles3/shadermatrix/mul_const_highp.html": 13.3097,
+    "deqp/functional/gles3/shadermatrix/mul_const_lowp.html": 9.8633,
+    "deqp/functional/gles3/shadermatrix/mul_const_mediump.html": 13.3341,
+    "deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html": 14.8296,
+    "deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html": 14.0179,
+    "deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html": 15.4225,
+    "deqp/functional/gles3/shadermatrix/mul_uniform_highp.html": 14.2769,
+    "deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html": 13.3494,
+    "deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html": 14.089,
+    "deqp/functional/gles3/shadermatrix/negation.html": 7.5259,
+    "deqp/functional/gles3/shadermatrix/outerproduct.html": 7.3892,
+    "deqp/functional/gles3/shadermatrix/post_decrement.html": 7.6339,
+    "deqp/functional/gles3/shadermatrix/post_increment.html": 7.2642,
+    "deqp/functional/gles3/shadermatrix/pre_decrement.html": 8.2786,
+    "deqp/functional/gles3/shadermatrix/pre_increment.html": 8.0526,
+    "deqp/functional/gles3/shadermatrix/sub_assign.html": 8.5589,
+    "deqp/functional/gles3/shadermatrix/sub_const.html": 13.9409,
+    "deqp/functional/gles3/shadermatrix/sub_dynamic.html": 15.6899,
+    "deqp/functional/gles3/shadermatrix/sub_uniform.html": 15.2994,
+    "deqp/functional/gles3/shadermatrix/transpose.html": 6.8262,
+    "deqp/functional/gles3/shadermatrix/unary_addition.html": 6.3476,
+    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html": 7.7301,
+    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html": 5.5783,
+    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html": 5.8657,
+    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html": 4.3842,
+    "deqp/functional/gles3/shaderoperator/binary_operator_00.html": 22.6841,
+    "deqp/functional/gles3/shaderoperator/binary_operator_01.html": 22.9253,
+    "deqp/functional/gles3/shaderoperator/binary_operator_02.html": 13.5548,
+    "deqp/functional/gles3/shaderoperator/binary_operator_03.html": 12.9781,
+    "deqp/functional/gles3/shaderoperator/binary_operator_04.html": 18.3209,
+    "deqp/functional/gles3/shaderoperator/binary_operator_05.html": 16.2356,
+    "deqp/functional/gles3/shaderoperator/binary_operator_06.html": 16.8852,
+    "deqp/functional/gles3/shaderoperator/binary_operator_07.html": 9.7102,
+    "deqp/functional/gles3/shaderoperator/binary_operator_08.html": 9.3515,
+    "deqp/functional/gles3/shaderoperator/binary_operator_09.html": 18.4146,
+    "deqp/functional/gles3/shaderoperator/binary_operator_10.html": 16.185,
+    "deqp/functional/gles3/shaderoperator/binary_operator_11.html": 16.5978,
+    "deqp/functional/gles3/shaderoperator/binary_operator_12.html": 9.4947,
+    "deqp/functional/gles3/shaderoperator/binary_operator_13.html": 9.5361,
+    "deqp/functional/gles3/shaderoperator/binary_operator_14.html": 18.2815,
+    "deqp/functional/gles3/shaderoperator/binary_operator_15.html": 34.5142,
+    "deqp/functional/gles3/shaderoperator/bool_compare.html": 3.3175,
+    "deqp/functional/gles3/shaderoperator/common_functions_00.html": 8.8854,
+    "deqp/functional/gles3/shaderoperator/common_functions_01.html": 14.4667,
+    "deqp/functional/gles3/shaderoperator/common_functions_02.html": 9.0388,
+    "deqp/functional/gles3/shaderoperator/common_functions_03.html": 15.138,
+    "deqp/functional/gles3/shaderoperator/common_functions_04.html": 9.4712,
+    "deqp/functional/gles3/shaderoperator/common_functions_05.html": 10.2355,
+    "deqp/functional/gles3/shaderoperator/common_functions_06.html": 7.2982,
+    "deqp/functional/gles3/shaderoperator/exponential.html": 8.5641,
+    "deqp/functional/gles3/shaderoperator/float_compare.html": 21.4985,
+    "deqp/functional/gles3/shaderoperator/geometric.html": 9.5953,
+    "deqp/functional/gles3/shaderoperator/int_compare.html": 10.8826,
+    "deqp/functional/gles3/shaderoperator/selection.html": 7.144,
+    "deqp/functional/gles3/shaderoperator/sequence.html": 5.3591,
+    "deqp/functional/gles3/shaderoperator/unary_operator_00.html": 11.981,
+    "deqp/functional/gles3/shaderoperator/unary_operator_01.html": 20.3104,
+    "deqp/functional/gles3/shaderoperator/unary_operator_02.html": 20.6337,
+    "deqp/functional/gles3/shaderpackingfunction.html": 0.7281,
+    "deqp/functional/gles3/shaderprecision_float.html": 9.8802,
+    "deqp/functional/gles3/shaderprecision_int.html": 8.6372,
+    "deqp/functional/gles3/shaderprecision_uint.html": 8.9896,
+    "deqp/functional/gles3/shaderstatequery.html": 0.7384,
+    "deqp/functional/gles3/shaderstruct.html": 8.775,
+    "deqp/functional/gles3/shaderswitch.html": 10.0804,
+    "deqp/functional/gles3/shadertexturefunction/texelfetch.html": 4.1228,
+    "deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html": 4.0708,
+    "deqp/functional/gles3/shadertexturefunction/texture.html": 7.9808,
+    "deqp/functional/gles3/shadertexturefunction/texturegrad.html": 5.4027,
+    "deqp/functional/gles3/shadertexturefunction/texturegradoffset.html": 3.5107,
+    "deqp/functional/gles3/shadertexturefunction/texturelod.html": 6.9594,
+    "deqp/functional/gles3/shadertexturefunction/texturelodoffset.html": 4.4954,
+    "deqp/functional/gles3/shadertexturefunction/textureoffset.html": 5.7637,
+    "deqp/functional/gles3/shadertexturefunction/textureproj.html": 6.7523,
+    "deqp/functional/gles3/shadertexturefunction/textureprojgrad.html": 3.2336,
+    "deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html": 4.2539,
+    "deqp/functional/gles3/shadertexturefunction/textureprojlod.html": 3.4197,
+    "deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html": 3.1184,
+    "deqp/functional/gles3/shadertexturefunction/textureprojoffset.html": 5.59,
+    "deqp/functional/gles3/shadertexturefunction/texturesize.html": 19.4748,
+    "deqp/functional/gles3/stringquery.html": 0.3229,
+    "deqp/functional/gles3/sync.html": 3.7402,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html": 3.6087,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html": 3.5574,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html": 3.865,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html": 3.9594,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html": 4.004,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html": 4.4502,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_00.html": 1.8791,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_01.html": 1.7892,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_02.html": 1.4789,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_03.html": 1.2344,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_04.html": 1.5254,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_05.html": 1.2785,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_06.html": 1.3061,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_07.html": 1.3009,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_08.html": 1.3107,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_09.html": 1.3896,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html": 1.2268,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html": 1.2764,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html": 1.3722,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html": 1.1437,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html": 4.41,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_00.html": 2.1676,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_01.html": 2.3624,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_02.html": 2.3732,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_03.html": 2.1309,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_04.html": 2.2733,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_05.html": 2.6934,
+    "deqp/functional/gles3/texturefiltering/2d_formats_00.html": 1.4725,
+    "deqp/functional/gles3/texturefiltering/2d_formats_01.html": 1.1709,
+    "deqp/functional/gles3/texturefiltering/2d_formats_02.html": 1.0654,
+    "deqp/functional/gles3/texturefiltering/2d_formats_03.html": 0.9306,
+    "deqp/functional/gles3/texturefiltering/2d_formats_04.html": 1.044,
+    "deqp/functional/gles3/texturefiltering/2d_formats_05.html": 1.0309,
+    "deqp/functional/gles3/texturefiltering/2d_formats_06.html": 1.132,
+    "deqp/functional/gles3/texturefiltering/2d_formats_07.html": 1.1752,
+    "deqp/functional/gles3/texturefiltering/2d_formats_08.html": 1.1555,
+    "deqp/functional/gles3/texturefiltering/2d_formats_09.html": 0.8862,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_00.html": 0.9675,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_01.html": 1.0187,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_02.html": 1.2168,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_03.html": 1.2175,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_04.html": 1.0337,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_05.html": 1.041,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_00.html": 1.8474,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_01.html": 1.7378,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_02.html": 1.8511,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_03.html": 1.9736,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_04.html": 2.0795,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_05.html": 2.0359,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_06.html": 2.0242,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_07.html": 2.025,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_08.html": 2.0547,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_09.html": 2.0342,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_10.html": 1.9968,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_11.html": 2.0275,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_12.html": 1.7243,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_13.html": 1.9463,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_14.html": 1.7035,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_15.html": 2.0286,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_16.html": 2.0866,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_17.html": 2.0734,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_18.html": 2.0313,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_19.html": 2.071,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_20.html": 2.0959,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_21.html": 2.1254,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_22.html": 1.9677,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_23.html": 2.1015,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_24.html": 7.566,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_25.html": 9.8983,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_26.html": 7.9742,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_27.html": 10.7864,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_28.html": 7.235,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_29.html": 8.013,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_30.html": 8.7811,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_31.html": 7.5788,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_32.html": 8.9057,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_33.html": 10.1171,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_34.html": 7.3807,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_35.html": 9.4053,
+    "deqp/functional/gles3/texturefiltering/3d_formats_00.html": 3.9914,
+    "deqp/functional/gles3/texturefiltering/3d_formats_01.html": 3.1322,
+    "deqp/functional/gles3/texturefiltering/3d_formats_02.html": 3.6169,
+    "deqp/functional/gles3/texturefiltering/3d_formats_03.html": 2.6381,
+    "deqp/functional/gles3/texturefiltering/3d_formats_04.html": 3.3581,
+    "deqp/functional/gles3/texturefiltering/3d_formats_05.html": 3.2271,
+    "deqp/functional/gles3/texturefiltering/3d_formats_06.html": 2.9682,
+    "deqp/functional/gles3/texturefiltering/3d_formats_07.html": 2.8763,
+    "deqp/functional/gles3/texturefiltering/3d_formats_08.html": 3.2747,
+    "deqp/functional/gles3/texturefiltering/3d_formats_09.html": 3.2165,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_00.html": 3.4486,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_01.html": 2.8088,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_02.html": 3.3794,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_03.html": 2.5964,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_04.html": 3.3641,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_00.html": 6.7269,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_01.html": 6.6444,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_02.html": 11.2136,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_03.html": 9.58,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_04.html": 11.9239,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_05.html": 14.7871,
+    "deqp/functional/gles3/texturefiltering/cube_formats_00.html": 4.6313,
+    "deqp/functional/gles3/texturefiltering/cube_formats_01.html": 4.7494,
+    "deqp/functional/gles3/texturefiltering/cube_formats_02.html": 4.2146,
+    "deqp/functional/gles3/texturefiltering/cube_formats_03.html": 3.9183,
+    "deqp/functional/gles3/texturefiltering/cube_formats_04.html": 3.7533,
+    "deqp/functional/gles3/texturefiltering/cube_formats_05.html": 3.7244,
+    "deqp/functional/gles3/texturefiltering/cube_formats_06.html": 3.4823,
+    "deqp/functional/gles3/texturefiltering/cube_formats_07.html": 3.7507,
+    "deqp/functional/gles3/texturefiltering/cube_formats_08.html": 4.1335,
+    "deqp/functional/gles3/texturefiltering/cube_formats_09.html": 4.2236,
+    "deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html": 1.4488,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_00.html": 2.5628,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_01.html": 3.9768,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_02.html": 5.5317,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_03.html": 2.6799,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_04.html": 4.4803,
+    "deqp/functional/gles3/textureformat/compressed_2d.html": 0.1497,
+    "deqp/functional/gles3/textureformat/compressed_cube.html": 0.1417,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html": 3.2714,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html": 2.7774,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html": 2.7766,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html": 3.0252,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html": 3.4624,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html": 3.4442,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html": 3.4426,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html": 3.2081,
+    "deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html": 0.8101,
+    "deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html": 0.704,
+    "deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html": 0.7649,
+    "deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html": 0.82,
+    "deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html": 0.8115,
+    "deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html": 1.0319,
+    "deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html": 0.7164,
+    "deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html": 0.8544,
+    "deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html": 2.6729,
+    "deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html": 2.4264,
+    "deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html": 2.6615,
+    "deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html": 2.4288,
+    "deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html": 4.6444,
+    "deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html": 5.1519,
+    "deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html": 6.0086,
+    "deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html": 4.6803,
+    "deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html": 2.7978,
+    "deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html": 2.0348,
+    "deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html": 2.6171,
+    "deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html": 2.5962,
+    "deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html": 2.9587,
+    "deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html": 2.6103,
+    "deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html": 2.4619,
+    "deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html": 2.5286,
+    "deqp/functional/gles3/textureformat/sized_depth_stencil.html": 3.8288,
+    "deqp/functional/gles3/textureformat/unsized_2d.html": 3.7836,
+    "deqp/functional/gles3/textureformat/unsized_2d_array.html": 3.4863,
+    "deqp/functional/gles3/textureformat/unsized_3d.html": 3.9472,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_always.html": 1.0104,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_equal.html": 1.6772,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_greater.html": 1.5143,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html": 1.5246,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_less.html": 1.5192,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html": 1.1707,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html": 1.1245,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html": 1.7871,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html": 2.1567,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html": 2.2346,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html": 2.3007,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html": 2.1147,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html": 0.9691,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html": 1.7879,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html": 0.9291,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html": 1.2111,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html": 1.7355,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html": 1.4156,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html": 1.5521,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html": 1.4041,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html": 0.7785,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html": 1.2462,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_never.html": 1.0806,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html": 1.4203,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_always.html": 0.9622,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html": 1.0865,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html": 0.7292,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html": 0.9987,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_less.html": 0.7155,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html": 1.0433,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html": 1.0606,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html": 1.2317,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html": 1.142,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html": 1.0543,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html": 1.2719,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html": 0.9811,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html": 0.7829,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html": 1.0645,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html": 0.8229,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html": 1.0796,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html": 1.2279,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html": 1.2765,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html": 1.0982,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html": 1.053,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html": 1.093,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html": 1.2459,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_never.html": 1.0296,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html": 0.7169,
+    "deqp/functional/gles3/textureshadow/2d_linear_always.html": 0.8743,
+    "deqp/functional/gles3/textureshadow/2d_linear_equal.html": 1.2305,
+    "deqp/functional/gles3/textureshadow/2d_linear_greater.html": 1.165,
+    "deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html": 1.1756,
+    "deqp/functional/gles3/textureshadow/2d_linear_less.html": 1.1802,
+    "deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html": 1.1587,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html": 0.9713,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html": 2.1924,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html": 1.6456,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html": 2.4759,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html": 2.1396,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html": 1.9216,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html": 0.7548,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html": 1.9629,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html": 1.0018,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html": 1.3053,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html": 1.281,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html": 1.4501,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html": 1.4544,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html": 1.246,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html": 0.7341,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html": 1.3642,
+    "deqp/functional/gles3/textureshadow/2d_linear_never.html": 0.8805,
+    "deqp/functional/gles3/textureshadow/2d_linear_not_equal.html": 1.2329,
+    "deqp/functional/gles3/textureshadow/2d_nearest_always.html": 0.6959,
+    "deqp/functional/gles3/textureshadow/2d_nearest_equal.html": 0.6968,
+    "deqp/functional/gles3/textureshadow/2d_nearest_greater.html": 0.7289,
+    "deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html": 0.952,
+    "deqp/functional/gles3/textureshadow/2d_nearest_less.html": 0.701,
+    "deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html": 0.7129,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html": 0.7109,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html": 1.4594,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html": 0.9627,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html": 1.3495,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html": 1.3258,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html": 0.9803,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html": 0.7139,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html": 1.6334,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html": 0.7672,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html": 0.9975,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html": 1.0467,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html": 1.0891,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html": 1.1477,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html": 1.1612,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html": 0.9119,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html": 1.1307,
+    "deqp/functional/gles3/textureshadow/2d_nearest_never.html": 0.6942,
+    "deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html": 0.9664,
+    "deqp/functional/gles3/textureshadow/cube_linear_always.html": 2.0838,
+    "deqp/functional/gles3/textureshadow/cube_linear_equal.html": 3.0203,
+    "deqp/functional/gles3/textureshadow/cube_linear_greater.html": 2.7838,
+    "deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html": 3.02,
+    "deqp/functional/gles3/textureshadow/cube_linear_less.html": 3.1881,
+    "deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html": 2.8994,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html": 2.1212,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html": 4.2189,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html": 4.0025,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html": 4.5133,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html": 4.2989,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html": 4.0401,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html": 2.1775,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html": 3.8583,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html": 2.1637,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html": 3.128,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html": 3.221,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html": 3.2463,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html": 3.4085,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html": 3.2248,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html": 2.0527,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html": 3.349,
+    "deqp/functional/gles3/textureshadow/cube_linear_never.html": 2.2815,
+    "deqp/functional/gles3/textureshadow/cube_linear_not_equal.html": 2.9582,
+    "deqp/functional/gles3/textureshadow/cube_nearest_always.html": 1.8937,
+    "deqp/functional/gles3/textureshadow/cube_nearest_equal.html": 2.1817,
+    "deqp/functional/gles3/textureshadow/cube_nearest_greater.html": 2.0889,
+    "deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html": 2.3284,
+    "deqp/functional/gles3/textureshadow/cube_nearest_less.html": 2.0044,
+    "deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html": 2.0438,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html": 2.3448,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html": 3.6831,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html": 3.5794,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html": 3.7569,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html": 3.8719,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html": 3.5461,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html": 2.183,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html": 3.947,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html": 2.2487,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html": 3.045,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html": 2.7632,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html": 3.046,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html": 2.759,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html": 2.6931,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html": 2.2413,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html": 2.8723,
+    "deqp/functional/gles3/textureshadow/cube_nearest_never.html": 2.1938,
+    "deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html": 2.1191,
+    "deqp/functional/gles3/texturespecification/basic_copyteximage2d.html": 7.2501,
+    "deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html": 6.758,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html": 4.2402,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html": 3.2694,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html": 3.4046,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html": 4.3215,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html": 3.7806,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html": 4.0943,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html": 3.5995,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html": 3.528,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html": 3.3918,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html": 3.4112,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html": 2.5602,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html": 2.4184,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html": 2.3633,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html": 2.6629,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html": 2.2697,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html": 3.0327,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html": 2.4504,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html": 2.6937,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html": 3.7475,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html": 3.9141,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html": 3.8597,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html": 4.0319,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html": 3.6783,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html": 2.3553,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html": 2.4758,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html": 2.4342,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html": 2.4782,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html": 2.2469,
+    "deqp/functional/gles3/texturespecification/random_teximage2d_2d.html": 2.3848,
+    "deqp/functional/gles3/texturespecification/random_teximage2d_cube.html": 5.4728,
+    "deqp/functional/gles3/texturespecification/teximage2d_align.html": 4.8623,
+    "deqp/functional/gles3/texturespecification/teximage2d_depth.html": 0.9135,
+    "deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html": 0.944,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html": 1.7449,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html": 1.589,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html": 2.8158,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html": 2.9771,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html": 2.7533,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html": 2.958,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html": 2.6007,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html": 1.0696,
+    "deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html": 0.9129,
+    "deqp/functional/gles3/texturespecification/teximage3d_depth.html": 1.4126,
+    "deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html": 1.3702,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html": 1.7648,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html": 1.6815,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html": 1.8878,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html": 1.8817,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html": 1.4346,
+    "deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html": 1.4202,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html": 3.2914,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html": 3.1183,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html": 2.9209,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html": 3.537,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html": 3.1425,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html": 3.1938,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html": 3.288,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html": 3.0597,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html": 2.2026,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_size.html": 2.024,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html": 2.5024,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html": 2.2451,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html": 2.0021,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html": 3.5055,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html": 3.0686,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html": 3.4232,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html": 3.3019,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html": 0.918,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_size.html": 3.1658,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_align.html": 6.2068,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_depth.html": 0.7102,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html": 2.0643,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html": 1.9449,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html": 1.7731,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html": 3.1185,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html": 3.019,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html": 2.8604,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html": 3.1973,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html": 2.6557,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html": 1.6385,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html": 1.3451,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_depth.html": 1.1962,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html": 2.7225,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html": 2.7679,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html": 2.7901,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html": 2.4811,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html": 1.4961,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html": 1.4506,
+    "deqp/functional/gles3/texturestatequery.html": 0.905,
+    "deqp/functional/gles3/texturewrap/eac_r11_npot.html": 0.1561,
+    "deqp/functional/gles3/texturewrap/eac_r11_pot.html": 0.1232,
+    "deqp/functional/gles3/texturewrap/eac_rg11_npot.html": 0.1403,
+    "deqp/functional/gles3/texturewrap/eac_rg11_pot.html": 0.1277,
+    "deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html": 0.143,
+    "deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html": 0.1521,
+    "deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html": 0.1398,
+    "deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html": 0.1472,
+    "deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html": 0.1354,
+    "deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html": 0.1514,
+    "deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html": 0.1229,
+    "deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html": 0.1442,
+    "deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html": 0.1217,
+    "deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html": 0.1412,
+    "deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html": 0.1192,
+    "deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html": 0.1669,
+    "deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html": 0.1695,
+    "deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html": 0.1617,
+    "deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html": 0.138,
+    "deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html": 0.1644,
+    "deqp/functional/gles3/texturewrap/rgba8_npot.html": 2.3267,
+    "deqp/functional/gles3/texturewrap/rgba8_pot.html": 2.4333,
+    "deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html": 1.6846,
+    "deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html": 1.3187,
+    "deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html": 1.5801,
+    "deqp/functional/gles3/transformfeedback/array_element_separate_lines.html": 1.364,
+    "deqp/functional/gles3/transformfeedback/array_element_separate_points.html": 1.3538,
+    "deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html": 1.321,
+    "deqp/functional/gles3/transformfeedback/array_interleaved_lines.html": 1.817,
+    "deqp/functional/gles3/transformfeedback/array_interleaved_points.html": 1.7783,
+    "deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html": 1.7984,
+    "deqp/functional/gles3/transformfeedback/array_separate_lines.html": 1.1954,
+    "deqp/functional/gles3/transformfeedback/array_separate_points.html": 1.2383,
+    "deqp/functional/gles3/transformfeedback/array_separate_triangles.html": 1.6891,
+    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html": 22.4207,
+    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html": 21.9273,
+    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html": 21.8652,
+    "deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html": 14.0773,
+    "deqp/functional/gles3/transformfeedback/basic_types_separate_points.html": 14.3837,
+    "deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html": 13.8491,
+    "deqp/functional/gles3/transformfeedback/interpolation_centroid.html": 6.5049,
+    "deqp/functional/gles3/transformfeedback/interpolation_flat.html": 4.9188,
+    "deqp/functional/gles3/transformfeedback/interpolation_smooth.html": 6.2723,
+    "deqp/functional/gles3/transformfeedback/point_size.html": 1.8039,
+    "deqp/functional/gles3/transformfeedback/position.html": 2.0618,
+    "deqp/functional/gles3/transformfeedback/random_interleaved_lines.html": 3.5559,
+    "deqp/functional/gles3/transformfeedback/random_interleaved_points.html": 2.6434,
+    "deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html": 3.5796,
+    "deqp/functional/gles3/transformfeedback/random_separate_lines.html": 3.6637,
+    "deqp/functional/gles3/transformfeedback/random_separate_points.html": 3.6257,
+    "deqp/functional/gles3/transformfeedback/random_separate_triangles.html": 3.5228,
+    "deqp/functional/gles3/uniformapi/info_query.html": 19.2096,
+    "deqp/functional/gles3/uniformapi/random.html": 4.0751,
+    "deqp/functional/gles3/uniformapi/value_assigned.html": 25.9962,
+    "deqp/functional/gles3/uniformapi/value_initial.html": 10.3354,
+    "deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html": 5.1414,
+    "deqp/functional/gles3/uniformbuffers/multi_basic_types.html": 1.0328,
+    "deqp/functional/gles3/uniformbuffers/multi_nested_struct.html": 1.2297,
+    "deqp/functional/gles3/uniformbuffers/random.html": 15.2336,
+    "deqp/functional/gles3/uniformbuffers/single_basic_array.html": 5.1738,
+    "deqp/functional/gles3/uniformbuffers/single_basic_type.html": 12.9006,
+    "deqp/functional/gles3/uniformbuffers/single_nested_struct.html": 1.1729,
+    "deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html": 1.2934,
+    "deqp/functional/gles3/uniformbuffers/single_struct.html": 0.8882,
+    "deqp/functional/gles3/uniformbuffers/single_struct_array.html": 1.9786,
+    "deqp/functional/gles3/vertexarrayobject.html": 1.049,
+    "deqp/functional/gles3/vertexarrays/multiple_attributes.count.html": 10.0622,
+    "deqp/functional/gles3/vertexarrays/multiple_attributes.output.html": 27.2508,
+    "deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html": 1.982,
+    "deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html": 29.9797,
+    "deqp/functional/gles3/vertexarrays/single_attribute.first.html": 24.7542,
+    "deqp/functional/gles3/vertexarrays/single_attribute.normalize.html": 11.8055,
+    "deqp/functional/gles3/vertexarrays/single_attribute.offset.html": 22.6143,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html": 9.7779,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html": 7.5643,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html": 8.3424,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html": 9.0292,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html": 4.4865,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html": 9.6805,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html": 9.0957,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html": 8.4563,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html": 2.6741,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html": 8.7294,
+    "deqp/functional/gles3/vertexarrays/single_attribute.stride.html": 10.9467,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html": 8.3659,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html": 7.8619,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html": 9.013,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html": 8.9607,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html": 8.028,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html": 9.0463,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html": 8.8628,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html": 8.6544,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html": 8.421
   }
 }
\ No newline at end of file
diff --git a/content/test/data/gpu/webgl_conformance_tests_output.json b/content/test/data/gpu/webgl_conformance_tests_output.json
index 44a2ff2..761a6a4 100644
--- a/content/test/data/gpu/webgl_conformance_tests_output.json
+++ b/content/test/data/gpu/webgl_conformance_tests_output.json
@@ -1,964 +1,997 @@
 {
   "times": {
-    "WebglExtension_ANGLE_instanced_arrays": 0.2108,
-    "WebglExtension_EXT_blend_minmax": 0.1965,
-    "WebglExtension_EXT_color_buffer_half_float": 0.1634,
-    "WebglExtension_EXT_disjoint_timer_query": 0.0684,
-    "WebglExtension_EXT_float_blend": 0.1687,
-    "WebglExtension_EXT_frag_depth": 0.2377,
-    "WebglExtension_EXT_sRGB": 0.1739,
-    "WebglExtension_EXT_shader_texture_lod": 0.1956,
-    "WebglExtension_EXT_texture_compression_bptc": 0.0821,
-    "WebglExtension_EXT_texture_compression_rgtc": 0.0771,
-    "WebglExtension_EXT_texture_filter_anisotropic": 0.1892,
-    "WebglExtension_KHR_parallel_shader_compile": 0.4924,
-    "WebglExtension_OES_element_index_uint": 0.218,
-    "WebglExtension_OES_fbo_render_mipmap": 0.7368,
-    "WebglExtension_OES_standard_derivatives": 0.1756,
-    "WebglExtension_OES_texture_float": 0.0761,
-    "WebglExtension_OES_texture_float_linear": 0.4093,
-    "WebglExtension_OES_texture_half_float": 0.2881,
-    "WebglExtension_OES_texture_half_float_linear": 0.068,
-    "WebglExtension_OES_vertex_array_object": 0.321,
-    "WebglExtension_TestCoverage": 0.1716,
-    "WebglExtension_WEBGL_color_buffer_float": 0.2936,
-    "WebglExtension_WEBGL_compressed_texture_astc": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_etc": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_etc1": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_pvrtc": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_s3tc": 0.2856,
-    "WebglExtension_WEBGL_compressed_texture_s3tc_srgb": 0.0,
-    "WebglExtension_WEBGL_debug_renderer_info": 0.0861,
-    "WebglExtension_WEBGL_debug_shaders": 0.1719,
-    "WebglExtension_WEBGL_depth_texture": 0.1363,
-    "WebglExtension_WEBGL_draw_buffers": 0.1871,
-    "WebglExtension_WEBGL_lose_context": 0.1996,
-    "WebglExtension_WEBGL_multi_draw": 0.2073,
-    "WebglExtension_WEBGL_video_texture": 0.118,
-    "conformance/attribs/gl-bindAttribLocation-aliasing.html": 0.3516,
-    "conformance/attribs/gl-bindAttribLocation-matrix.html": 0.581,
-    "conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html": 0.3075,
-    "conformance/attribs/gl-bindAttribLocation-repeated.html": 0.3123,
-    "conformance/attribs/gl-disabled-vertex-attrib-update.html": 0.439,
-    "conformance/attribs/gl-disabled-vertex-attrib.html": 0.9162,
-    "conformance/attribs/gl-enable-vertex-attrib.html": 0.386,
-    "conformance/attribs/gl-matrix-attributes.html": 0.7427,
-    "conformance/attribs/gl-vertex-attrib-context-switch.html": 0.6917,
-    "conformance/attribs/gl-vertex-attrib-render.html": 0.3389,
-    "conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html": 0.3518,
-    "conformance/attribs/gl-vertex-attrib-zero-issues.html": 0.7659,
-    "conformance/attribs/gl-vertex-attrib.html": 0.7,
-    "conformance/attribs/gl-vertexattribpointer-offsets.html": 0.7074,
-    "conformance/attribs/gl-vertexattribpointer.html": 1.1455,
-    "conformance/buffers/buffer-bind-test.html": 0.1094,
-    "conformance/buffers/buffer-data-and-buffer-sub-data.html": 0.7213,
-    "conformance/buffers/buffer-data-array-buffer-delete.html": 2.2464,
-    "conformance/buffers/buffer-data-dynamic-delay.html": 0.3741,
-    "conformance/buffers/buffer-uninitialized.html": 0.3976,
-    "conformance/buffers/element-array-buffer-delete-recreate.html": 0.2459,
-    "conformance/buffers/index-validation-copies-indices.html": 0.2996,
-    "conformance/buffers/index-validation-crash-with-buffer-sub-data.html": 0.0653,
-    "conformance/buffers/index-validation-large-buffer.html": 0.33,
-    "conformance/buffers/index-validation-verifies-too-many-indices.html": 0.2553,
-    "conformance/buffers/index-validation-with-resized-buffer.html": 0.2534,
-    "conformance/buffers/index-validation.html": 0.2328,
-    "conformance/buffers/vertex-buffer-updated-after-draw.html": 0.1477,
-    "conformance/canvas/buffer-offscreen-test.html": 0.3308,
-    "conformance/canvas/buffer-preserve-test.html": 0.2124,
-    "conformance/canvas/canvas-test.html": 0.4975,
-    "conformance/canvas/canvas-zero-size.html": 0.1104,
-    "conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html": 1.0706,
-    "conformance/canvas/draw-webgl-to-canvas-test.html": 1.0871,
-    "conformance/canvas/drawingbuffer-hd-dpi-test.html": 0.7617,
-    "conformance/canvas/drawingbuffer-static-canvas-test.html": 0.5494,
-    "conformance/canvas/drawingbuffer-test.html": 0.7053,
-    "conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html": 0.2777,
-    "conformance/canvas/framebuffer-bindings-unaffected-on-resize.html": 0.3555,
-    "conformance/canvas/rapid-resizing.html": 2.4653,
-    "conformance/canvas/render-after-resize-test.html": 0.2371,
-    "conformance/canvas/texture-bindings-unaffected-on-resize.html": 0.2999,
-    "conformance/canvas/to-data-url-test.html": 1.0222,
-    "conformance/canvas/viewport-unchanged-upon-resize.html": 0.1452,
-    "conformance/canvas/webgl-to-2d-canvas.html": 0.3172,
-    "conformance/context/constants-and-properties.html": 0.1335,
-    "conformance/context/context-attribute-preserve-drawing-buffer.html": 0.4601,
-    "conformance/context/context-attributes-alpha-depth-stencil-antialias.html": 1.0359,
-    "conformance/context/context-creation-and-destruction.html": 1.6246,
-    "conformance/context/context-creation.html": 1.1629,
-    "conformance/context/context-eviction-with-garbage-collection.html": 1.9231,
-    "conformance/context/context-hidden-alpha.html": 0.3218,
-    "conformance/context/context-lost-restored.html": 0.6639,
-    "conformance/context/context-lost.html": 0.234,
-    "conformance/context/context-no-alpha-fbo-with-alpha.html": 0.499,
-    "conformance/context/context-release-upon-reload.html": 1.6298,
-    "conformance/context/context-release-with-workers.html": 2.037,
-    "conformance/context/context-size-change.html": 0.1939,
-    "conformance/context/context-type-test.html": 0.0668,
-    "conformance/context/deleted-object-behavior.html": 0.4261,
-    "conformance/context/incorrect-context-object-behaviour.html": 0.1942,
-    "conformance/context/methods.html": 0.1247,
-    "conformance/context/premultiplyalpha-test.html": 0.589,
-    "conformance/context/user-defined-properties-on-context.html": 0.1884,
-    "conformance/context/zero-sized-canvas.html": 0.0868,
-    "conformance/extensions/angle-instanced-arrays-out-of-bounds.html": 0.9917,
-    "conformance/extensions/angle-instanced-arrays.html": 0.6216,
-    "conformance/extensions/ext-blend-minmax.html": 0.4937,
-    "conformance/extensions/ext-color-buffer-half-float.html": 0.0,
-    "conformance/extensions/ext-disjoint-timer-query.html": 8.3259,
-    "conformance/extensions/ext-float-blend.html": 0.4015,
-    "conformance/extensions/ext-frag-depth.html": 0.87,
-    "conformance/extensions/ext-sRGB.html": 0.345,
-    "conformance/extensions/ext-shader-texture-lod.html": 1.1702,
-    "conformance/extensions/ext-texture-compression-bptc.html": 0.4059,
-    "conformance/extensions/ext-texture-compression-rgtc.html": 0.1986,
-    "conformance/extensions/ext-texture-filter-anisotropic.html": 0.1764,
-    "conformance/extensions/get-extension.html": 0.5002,
-    "conformance/extensions/oes-element-index-uint.html": 0.6993,
-    "conformance/extensions/oes-fbo-render-mipmap.html": 0.3958,
-    "conformance/extensions/oes-standard-derivatives.html": 1.1448,
-    "conformance/extensions/oes-texture-float-linear.html": 0.7294,
-    "conformance/extensions/oes-texture-float-with-canvas.html": 1.4109,
-    "conformance/extensions/oes-texture-float-with-image-data.html": 0.5105,
-    "conformance/extensions/oes-texture-float-with-image.html": 0.5445,
-    "conformance/extensions/oes-texture-float-with-video.html": 1.9408,
-    "conformance/extensions/oes-texture-float.html": 0.7521,
-    "conformance/extensions/oes-texture-half-float-linear.html": 1.0852,
-    "conformance/extensions/oes-texture-half-float-with-canvas.html": 1.5686,
-    "conformance/extensions/oes-texture-half-float-with-image-data.html": 0.5837,
-    "conformance/extensions/oes-texture-half-float-with-image.html": 0.5444,
-    "conformance/extensions/oes-texture-half-float-with-video.html": 1.6989,
-    "conformance/extensions/oes-texture-half-float.html": 0.7452,
-    "conformance/extensions/oes-vertex-array-object-bufferData.html": 0.7095,
-    "conformance/extensions/oes-vertex-array-object.html": 0.3833,
-    "conformance/extensions/s3tc-and-rgtc.html": 8.5598,
-    "conformance/extensions/webgl-compressed-texture-astc.html": 0.3703,
-    "conformance/extensions/webgl-compressed-texture-etc.html": 13.5663,
-    "conformance/extensions/webgl-compressed-texture-etc1.html": 0.1278,
-    "conformance/extensions/webgl-compressed-texture-pvrtc.html": 0.3433,
-    "conformance/extensions/webgl-compressed-texture-s3tc-srgb.html": 1.2726,
-    "conformance/extensions/webgl-compressed-texture-size-limit.html": 4.8276,
-    "conformance/extensions/webgl-debug-renderer-info.html": 0.1147,
-    "conformance/extensions/webgl-debug-shaders.html": 0.2516,
-    "conformance/extensions/webgl-depth-texture.html": 0.5856,
-    "conformance/extensions/webgl-draw-buffers-broadcast-return.html": 0.7614,
-    "conformance/extensions/webgl-draw-buffers-framebuffer-unsupported.html": 0.3848,
-    "conformance/extensions/webgl-draw-buffers-max-draw-buffers.html": 0.238,
-    "conformance/extensions/webgl-draw-buffers.html": 1.4059,
-    "conformance/extensions/webgl-multi-draw.html": 1.1873,
-    "conformance/glsl/bugs/angle-ambiguous-function-call.html": 0.1967,
-    "conformance/glsl/bugs/angle-constructor-invalid-parameters.html": 0.2965,
-    "conformance/glsl/bugs/angle-d3d11-compiler-error.html": 0.1336,
-    "conformance/glsl/bugs/angle-dx-variable-bug.html": 0.2294,
-    "conformance/glsl/bugs/array-of-struct-with-int-first-position.html": 0.4338,
-    "conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html": 0.3891,
-    "conformance/glsl/bugs/bool-type-cast-bug-int-float.html": 0.4529,
-    "conformance/glsl/bugs/character-set.html": 0.3221,
-    "conformance/glsl/bugs/compare-loop-index-to-uniform.html": 0.2844,
-    "conformance/glsl/bugs/complex-glsl-does-not-crash.html": 2.9063,
-    "conformance/glsl/bugs/compound-assignment-type-combination.html": 1.7933,
-    "conformance/glsl/bugs/conditional-discard-in-loop.html": 0.4243,
-    "conformance/glsl/bugs/conditional-discard-optimization.html": 0.4994,
-    "conformance/glsl/bugs/conditional-texture-fetch.html": 0.4362,
-    "conformance/glsl/bugs/constant-precision-qualifier.html": 0.5617,
-    "conformance/glsl/bugs/essl3-shaders-with-webgl1.html": 0.2734,
-    "conformance/glsl/bugs/floor-div-cos-should-not-truncate.html": 0.2686,
-    "conformance/glsl/bugs/floored-division-accuracy.html": 0.219,
-    "conformance/glsl/bugs/fragcoord-linking-bug.html": 0.3447,
-    "conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html": 0.693,
-    "conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html": 0.1979,
-    "conformance/glsl/bugs/if-return-and-elseif.html": 0.325,
-    "conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html": 0.2277,
-    "conformance/glsl/bugs/init-array-with-loop.html": 0.24,
-    "conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html": 0.4107,
-    "conformance/glsl/bugs/logic-inside-block-without-braces.html": 0.388,
-    "conformance/glsl/bugs/long-expressions-should-not-crash.html": 0.9868,
-    "conformance/glsl/bugs/loop-if-loop-gradient.html": 0.2235,
-    "conformance/glsl/bugs/modulo-arithmetic-accuracy.html": 0.3025,
-    "conformance/glsl/bugs/multiplication-assignment.html": 0.3171,
-    "conformance/glsl/bugs/nested-functions-should-not-crash.html": 0.59,
-    "conformance/glsl/bugs/nested-loops-with-break-and-continue.html": 0.3225,
-    "conformance/glsl/bugs/nested-sequence-operator.html": 0.461,
-    "conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html": 0.5753,
-    "conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html": 0.4651,
-    "conformance/glsl/bugs/qualcomm-crash.html": 0.5284,
-    "conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html": 0.4618,
-    "conformance/glsl/bugs/sampler-array-struct-function-arg.html": 0.4026,
-    "conformance/glsl/bugs/sampler-array-using-loop-index.html": 0.3848,
-    "conformance/glsl/bugs/sampler-struct-function-arg.html": 0.3871,
-    "conformance/glsl/bugs/sequence-operator-evaluation-order.html": 0.5248,
-    "conformance/glsl/bugs/sketchfab-lighting-shader-crash.html": 0.3698,
-    "conformance/glsl/bugs/struct-constructor-highp-bug.html": 0.3757,
-    "conformance/glsl/bugs/struct-with-single-member-constructor.html": 0.3316,
-    "conformance/glsl/bugs/temp-expressions-should-not-crash.html": 1.4286,
-    "conformance/glsl/bugs/unary-minus-operator-float-bug.html": 0.4501,
-    "conformance/glsl/bugs/undefined-index-should-not-crash.html": 0.3293,
-    "conformance/glsl/bugs/uniforms-should-not-lose-values.html": 0.2941,
-    "conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html": 0.5024,
-    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html": 0.4406,
-    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html": 0.54,
-    "conformance/glsl/constructors/glsl-construct-bvec2.html": 0.9874,
-    "conformance/glsl/constructors/glsl-construct-bvec3.html": 1.1782,
-    "conformance/glsl/constructors/glsl-construct-bvec4.html": 1.2385,
-    "conformance/glsl/constructors/glsl-construct-ivec2.html": 0.9196,
-    "conformance/glsl/constructors/glsl-construct-ivec3.html": 1.317,
-    "conformance/glsl/constructors/glsl-construct-ivec4.html": 1.2571,
-    "conformance/glsl/constructors/glsl-construct-mat2.html": 1.2239,
-    "conformance/glsl/constructors/glsl-construct-mat3.html": 0.7537,
-    "conformance/glsl/constructors/glsl-construct-mat4.html": 0.8378,
-    "conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html": 0.5298,
-    "conformance/glsl/constructors/glsl-construct-vec-mat-index.html": 0.3885,
-    "conformance/glsl/constructors/glsl-construct-vec2.html": 0.8781,
-    "conformance/glsl/constructors/glsl-construct-vec3.html": 1.2949,
-    "conformance/glsl/constructors/glsl-construct-vec4.html": 1.3134,
-    "conformance/glsl/functions/glsl-function-abs.html": 1.0391,
-    "conformance/glsl/functions/glsl-function-acos.html": 1.1049,
-    "conformance/glsl/functions/glsl-function-asin.html": 1.1588,
-    "conformance/glsl/functions/glsl-function-atan-xy.html": 1.3247,
-    "conformance/glsl/functions/glsl-function-atan.html": 1.1388,
-    "conformance/glsl/functions/glsl-function-ceil.html": 0.9449,
-    "conformance/glsl/functions/glsl-function-clamp-float.html": 0.9284,
-    "conformance/glsl/functions/glsl-function-clamp-gentype.html": 0.9534,
-    "conformance/glsl/functions/glsl-function-cos.html": 0.8816,
-    "conformance/glsl/functions/glsl-function-cross.html": 0.4983,
-    "conformance/glsl/functions/glsl-function-distance.html": 0.9191,
-    "conformance/glsl/functions/glsl-function-dot.html": 0.8134,
-    "conformance/glsl/functions/glsl-function-faceforward.html": 0.8428,
-    "conformance/glsl/functions/glsl-function-floor.html": 0.9721,
-    "conformance/glsl/functions/glsl-function-fract.html": 0.9325,
-    "conformance/glsl/functions/glsl-function-length.html": 0.997,
-    "conformance/glsl/functions/glsl-function-max-float.html": 0.968,
-    "conformance/glsl/functions/glsl-function-max-gentype.html": 0.8564,
-    "conformance/glsl/functions/glsl-function-min-float.html": 0.9443,
-    "conformance/glsl/functions/glsl-function-min-gentype.html": 0.9893,
-    "conformance/glsl/functions/glsl-function-mix-float.html": 0.8882,
-    "conformance/glsl/functions/glsl-function-mix-gentype.html": 0.8643,
-    "conformance/glsl/functions/glsl-function-mod-float.html": 1.0725,
-    "conformance/glsl/functions/glsl-function-mod-gentype.html": 0.885,
-    "conformance/glsl/functions/glsl-function-normalize.html": 0.8573,
-    "conformance/glsl/functions/glsl-function-reflect.html": 1.0133,
-    "conformance/glsl/functions/glsl-function-sign.html": 0.9243,
-    "conformance/glsl/functions/glsl-function-sin.html": 1.0841,
-    "conformance/glsl/functions/glsl-function-smoothstep-float.html": 1.1326,
-    "conformance/glsl/functions/glsl-function-smoothstep-gentype.html": 0.9903,
-    "conformance/glsl/functions/glsl-function-step-float.html": 1.0122,
-    "conformance/glsl/functions/glsl-function-step-gentype.html": 0.9841,
-    "conformance/glsl/functions/glsl-function.html": 0.8605,
-    "conformance/glsl/implicit/add_int_float.vert.html": 0.3298,
-    "conformance/glsl/implicit/add_int_mat2.vert.html": 0.4416,
-    "conformance/glsl/implicit/add_int_mat3.vert.html": 0.1895,
-    "conformance/glsl/implicit/add_int_mat4.vert.html": 0.2445,
-    "conformance/glsl/implicit/add_int_vec2.vert.html": 0.1663,
-    "conformance/glsl/implicit/add_int_vec3.vert.html": 0.2751,
-    "conformance/glsl/implicit/add_int_vec4.vert.html": 0.2576,
-    "conformance/glsl/implicit/add_ivec2_vec2.vert.html": 0.1339,
-    "conformance/glsl/implicit/add_ivec3_vec3.vert.html": 0.2803,
-    "conformance/glsl/implicit/add_ivec4_vec4.vert.html": 0.1636,
-    "conformance/glsl/implicit/assign_int_to_float.vert.html": 0.1834,
-    "conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html": 0.2438,
-    "conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html": 0.2676,
-    "conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html": 0.2467,
-    "conformance/glsl/implicit/construct_struct.vert.html": 0.2932,
-    "conformance/glsl/implicit/divide_int_float.vert.html": 0.2568,
-    "conformance/glsl/implicit/divide_int_mat2.vert.html": 0.2598,
-    "conformance/glsl/implicit/divide_int_mat3.vert.html": 0.1625,
-    "conformance/glsl/implicit/divide_int_mat4.vert.html": 0.1973,
-    "conformance/glsl/implicit/divide_int_vec2.vert.html": 0.0899,
-    "conformance/glsl/implicit/divide_int_vec3.vert.html": 0.1656,
-    "conformance/glsl/implicit/divide_int_vec4.vert.html": 0.2454,
-    "conformance/glsl/implicit/divide_ivec2_vec2.vert.html": 0.2475,
-    "conformance/glsl/implicit/divide_ivec3_vec3.vert.html": 0.1482,
-    "conformance/glsl/implicit/divide_ivec4_vec4.vert.html": 0.2275,
-    "conformance/glsl/implicit/equal_int_float.vert.html": 0.2491,
-    "conformance/glsl/implicit/equal_ivec2_vec2.vert.html": 0.1568,
-    "conformance/glsl/implicit/equal_ivec3_vec3.vert.html": 0.1459,
-    "conformance/glsl/implicit/equal_ivec4_vec4.vert.html": 0.1335,
-    "conformance/glsl/implicit/function_int_float.vert.html": 0.1227,
-    "conformance/glsl/implicit/function_ivec2_vec2.vert.html": 0.1472,
-    "conformance/glsl/implicit/function_ivec3_vec3.vert.html": 0.2459,
-    "conformance/glsl/implicit/function_ivec4_vec4.vert.html": 0.1471,
-    "conformance/glsl/implicit/greater_than.vert.html": 0.1942,
-    "conformance/glsl/implicit/greater_than_equal.vert.html": 0.2617,
-    "conformance/glsl/implicit/less_than.vert.html": 0.2622,
-    "conformance/glsl/implicit/less_than_equal.vert.html": 0.1604,
-    "conformance/glsl/implicit/multiply_int_float.vert.html": 0.2171,
-    "conformance/glsl/implicit/multiply_int_mat2.vert.html": 0.147,
-    "conformance/glsl/implicit/multiply_int_mat3.vert.html": 0.2591,
-    "conformance/glsl/implicit/multiply_int_mat4.vert.html": 0.1572,
-    "conformance/glsl/implicit/multiply_int_vec2.vert.html": 0.1155,
-    "conformance/glsl/implicit/multiply_int_vec3.vert.html": 0.278,
-    "conformance/glsl/implicit/multiply_int_vec4.vert.html": 0.2667,
-    "conformance/glsl/implicit/multiply_ivec2_vec2.vert.html": 0.2497,
-    "conformance/glsl/implicit/multiply_ivec3_vec3.vert.html": 0.2452,
-    "conformance/glsl/implicit/multiply_ivec4_vec4.vert.html": 0.1266,
-    "conformance/glsl/implicit/not_equal_int_float.vert.html": 0.1724,
-    "conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html": 0.1931,
-    "conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html": 0.2573,
-    "conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html": 0.1712,
-    "conformance/glsl/implicit/subtract_int_float.vert.html": 0.1501,
-    "conformance/glsl/implicit/subtract_int_mat2.vert.html": 0.1567,
-    "conformance/glsl/implicit/subtract_int_mat3.vert.html": 0.2485,
-    "conformance/glsl/implicit/subtract_int_mat4.vert.html": 0.2301,
-    "conformance/glsl/implicit/subtract_int_vec2.vert.html": 0.157,
-    "conformance/glsl/implicit/subtract_int_vec3.vert.html": 0.2486,
-    "conformance/glsl/implicit/subtract_int_vec4.vert.html": 0.1296,
-    "conformance/glsl/implicit/subtract_ivec2_vec2.vert.html": 0.2637,
-    "conformance/glsl/implicit/subtract_ivec3_vec3.vert.html": 0.2004,
-    "conformance/glsl/implicit/subtract_ivec4_vec4.vert.html": 0.2662,
-    "conformance/glsl/implicit/ternary_int_float.vert.html": 0.2632,
-    "conformance/glsl/implicit/ternary_ivec2_vec2.vert.html": 0.226,
-    "conformance/glsl/implicit/ternary_ivec3_vec3.vert.html": 0.2483,
-    "conformance/glsl/implicit/ternary_ivec4_vec4.vert.html": 0.258,
-    "conformance/glsl/literals/float_literal.vert.html": 0.1248,
-    "conformance/glsl/literals/literal_precision.html": 0.1601,
-    "conformance/glsl/literals/overflow_leak.vert.html": 0.1014,
-    "conformance/glsl/matrices/glsl-mat3-construction.html": 0.6947,
-    "conformance/glsl/matrices/glsl-mat4-to-mat3.html": 0.5344,
-    "conformance/glsl/matrices/matrix-compound-multiply.html": 0.7121,
-    "conformance/glsl/misc/attrib-location-length-limits.html": 0.4669,
-    "conformance/glsl/misc/boolean_precision.html": 0.4844,
-    "conformance/glsl/misc/const-variable-initialization.html": 2.0921,
-    "conformance/glsl/misc/embedded-struct-definitions-forbidden.html": 0.3723,
-    "conformance/glsl/misc/empty-declaration.html": 0.3099,
-    "conformance/glsl/misc/empty_main.vert.html": 0.3723,
-    "conformance/glsl/misc/expression-list-in-declarator-initializer.html": 0.9353,
-    "conformance/glsl/misc/fragcolor-fragdata-invariant.html": 0.4527,
-    "conformance/glsl/misc/gl_position_unset.vert.html": 0.4561,
-    "conformance/glsl/misc/global-variable-init.html": 0.6306,
-    "conformance/glsl/misc/glsl-function-nodes.html": 0.5641,
-    "conformance/glsl/misc/glsl-long-variable-names.html": 0.4852,
-    "conformance/glsl/misc/glsl-vertex-branch.html": 0.5482,
-    "conformance/glsl/misc/large-loop-compile.html": 0.9762,
-    "conformance/glsl/misc/local-variable-shadowing-outer-function.html": 0.5218,
-    "conformance/glsl/misc/non-ascii-comments.vert.html": 0.3849,
-    "conformance/glsl/misc/non-ascii.vert.html": 0.4465,
-    "conformance/glsl/misc/re-compile-re-link.html": 0.3566,
-    "conformance/glsl/misc/sampler-operand.html": 0.3272,
-    "conformance/glsl/misc/sequence-operator-returns-constant.html": 0.2994,
-    "conformance/glsl/misc/shader-precision-format-obeyed.html": 0.3996,
-    "conformance/glsl/misc/shader-struct-scope.html": 0.2878,
-    "conformance/glsl/misc/shader-uniform-packing-restrictions.html": 3.684,
-    "conformance/glsl/misc/shader-varying-packing-restrictions.html": 0.8899,
-    "conformance/glsl/misc/shader-with-256-character-define.html": 0.2862,
-    "conformance/glsl/misc/shader-with-256-character-identifier.frag.html": 0.3883,
-    "conformance/glsl/misc/shader-with-257-character-define.html": 0.3911,
-    "conformance/glsl/misc/shader-with-257-character-identifier.frag.html": 0.2043,
-    "conformance/glsl/misc/shader-with-_webgl-identifier.vert.html": 0.2459,
-    "conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html": 0.2206,
-    "conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html": 0.2202,
-    "conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html": 0.5653,
-    "conformance/glsl/misc/shader-with-array-of-structs-uniform.html": 0.4091,
-    "conformance/glsl/misc/shader-with-attrib-array.vert.html": 0.2095,
-    "conformance/glsl/misc/shader-with-attrib-struct.vert.html": 0.4973,
-    "conformance/glsl/misc/shader-with-clipvertex.vert.html": 0.3012,
-    "conformance/glsl/misc/shader-with-comma-assignment.html": 0.2726,
-    "conformance/glsl/misc/shader-with-comma-conditional-assignment.html": 0.4552,
-    "conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html": 0.3651,
-    "conformance/glsl/misc/shader-with-conditional-scoping-negative.html": 0.3643,
-    "conformance/glsl/misc/shader-with-conditional-scoping.html": 0.267,
-    "conformance/glsl/misc/shader-with-default-precision.frag.html": 0.4519,
-    "conformance/glsl/misc/shader-with-default-precision.vert.html": 0.4618,
-    "conformance/glsl/misc/shader-with-define-line-continuation.frag.html": 0.4634,
-    "conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html": 0.4573,
-    "conformance/glsl/misc/shader-with-dfdx.frag.html": 0.1872,
-    "conformance/glsl/misc/shader-with-do-loop.html": 0.2858,
-    "conformance/glsl/misc/shader-with-error-directive.html": 0.193,
-    "conformance/glsl/misc/shader-with-explicit-int-cast.vert.html": 0.2157,
-    "conformance/glsl/misc/shader-with-float-return-value.frag.html": 0.1577,
-    "conformance/glsl/misc/shader-with-for-loop.html": 0.4547,
-    "conformance/glsl/misc/shader-with-for-scoping.html": 0.3784,
-    "conformance/glsl/misc/shader-with-frag-depth.frag.html": 0.4927,
-    "conformance/glsl/misc/shader-with-function-recursion.frag.html": 0.1183,
-    "conformance/glsl/misc/shader-with-function-scoped-struct.html": 0.1713,
-    "conformance/glsl/misc/shader-with-functional-scoping.html": 0.2215,
-    "conformance/glsl/misc/shader-with-glcolor.vert.html": 0.2119,
-    "conformance/glsl/misc/shader-with-gles-1.frag.html": 0.2337,
-    "conformance/glsl/misc/shader-with-gles-symbol.frag.html": 0.2498,
-    "conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html": 0.4903,
-    "conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html": 0.1615,
-    "conformance/glsl/misc/shader-with-hex-int-constant-macro.html": 0.3669,
-    "conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html": 0.2513,
-    "conformance/glsl/misc/shader-with-include.vert.html": 0.1912,
-    "conformance/glsl/misc/shader-with-int-return-value.frag.html": 0.3381,
-    "conformance/glsl/misc/shader-with-invalid-identifier.frag.html": 0.2499,
-    "conformance/glsl/misc/shader-with-ivec2-return-value.frag.html": 0.359,
-    "conformance/glsl/misc/shader-with-ivec3-return-value.frag.html": 0.3809,
-    "conformance/glsl/misc/shader-with-ivec4-return-value.frag.html": 0.3264,
-    "conformance/glsl/misc/shader-with-limited-indexing.frag.html": 0.3339,
-    "conformance/glsl/misc/shader-with-long-line.html": 0.4736,
-    "conformance/glsl/misc/shader-with-non-ascii-error.frag.html": 0.3527,
-    "conformance/glsl/misc/shader-with-non-reserved-words.html": 28.1745,
-    "conformance/glsl/misc/shader-with-precision.frag.html": 0.1262,
-    "conformance/glsl/misc/shader-with-preprocessor-whitespace.html": 0.3546,
-    "conformance/glsl/misc/shader-with-quoted-error.frag.html": 0.4896,
-    "conformance/glsl/misc/shader-with-reserved-words.html": 4.0307,
-    "conformance/glsl/misc/shader-with-short-circuiting-operators.html": 0.9213,
-    "conformance/glsl/misc/shader-with-similar-uniform-array-names.html": 0.7654,
-    "conformance/glsl/misc/shader-with-too-many-uniforms.html": 0.9555,
-    "conformance/glsl/misc/shader-with-two-initializer-types.html": 0.3112,
-    "conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html": 0.1542,
-    "conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html": 0.3484,
-    "conformance/glsl/misc/shader-with-vec2-return-value.frag.html": 0.2487,
-    "conformance/glsl/misc/shader-with-vec3-return-value.frag.html": 0.1889,
-    "conformance/glsl/misc/shader-with-vec4-return-value.frag.html": 0.3494,
-    "conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html": 0.4281,
-    "conformance/glsl/misc/shader-with-version-100.frag.html": 0.4731,
-    "conformance/glsl/misc/shader-with-version-100.vert.html": 0.3497,
-    "conformance/glsl/misc/shader-with-version-120.vert.html": 0.3377,
-    "conformance/glsl/misc/shader-with-version-130.vert.html": 0.2546,
-    "conformance/glsl/misc/shader-with-webgl-identifier.vert.html": 0.1863,
-    "conformance/glsl/misc/shader-with-while-loop.html": 0.2153,
-    "conformance/glsl/misc/shader-without-precision.frag.html": 0.1857,
-    "conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html": 0.518,
-    "conformance/glsl/misc/shaders-with-invariance.html": 0.3628,
-    "conformance/glsl/misc/shaders-with-mis-matching-uniforms.html": 0.7217,
-    "conformance/glsl/misc/shaders-with-mis-matching-varyings.html": 0.5457,
-    "conformance/glsl/misc/shaders-with-missing-varyings.html": 0.3449,
-    "conformance/glsl/misc/shaders-with-name-conflicts.html": 0.2649,
-    "conformance/glsl/misc/shaders-with-uniform-structs.html": 0.2991,
-    "conformance/glsl/misc/shaders-with-varyings.html": 0.2603,
-    "conformance/glsl/misc/shared.html": 0.5164,
-    "conformance/glsl/misc/struct-as-inout-parameter.html": 0.439,
-    "conformance/glsl/misc/struct-as-out-parameter.html": 0.5047,
-    "conformance/glsl/misc/struct-assign.html": 0.6433,
-    "conformance/glsl/misc/struct-equals.html": 0.5659,
-    "conformance/glsl/misc/struct-mixed-array-declarators.html": 1.0818,
-    "conformance/glsl/misc/struct-nesting-exceeds-maximum.html": 0.4578,
-    "conformance/glsl/misc/struct-nesting-of-variable-names.html": 2.886,
-    "conformance/glsl/misc/struct-nesting-under-maximum.html": 0.2116,
-    "conformance/glsl/misc/struct-specifiers-in-uniforms.html": 0.7079,
-    "conformance/glsl/misc/struct-unary-operators.html": 0.6934,
-    "conformance/glsl/misc/ternary-operator-on-arrays.html": 0.1615,
-    "conformance/glsl/misc/ternary-operators-in-global-initializers.html": 0.57,
-    "conformance/glsl/misc/ternary-operators-in-initializers.html": 0.624,
-    "conformance/glsl/misc/uniform-location-length-limits.html": 0.128,
-    "conformance/glsl/misc/uninitialized-local-global-variables.html": 0.7618,
-    "conformance/glsl/preprocessor/comments.html": 0.4354,
-    "conformance/glsl/preprocessor/macro-expansion-tricky.html": 0.4733,
-    "conformance/glsl/reserved/_webgl_field.vert.html": 0.4417,
-    "conformance/glsl/reserved/_webgl_function.vert.html": 0.4681,
-    "conformance/glsl/reserved/_webgl_struct.vert.html": 0.1503,
-    "conformance/glsl/reserved/_webgl_variable.vert.html": 0.1858,
-    "conformance/glsl/reserved/webgl_field.vert.html": 0.242,
-    "conformance/glsl/reserved/webgl_function.vert.html": 0.1479,
-    "conformance/glsl/reserved/webgl_struct.vert.html": 0.139,
-    "conformance/glsl/reserved/webgl_variable.vert.html": 0.2299,
-    "conformance/glsl/samplers/glsl-function-texture2d-bias.html": 0.4459,
-    "conformance/glsl/samplers/glsl-function-texture2dlod.html": 0.8137,
-    "conformance/glsl/samplers/glsl-function-texture2dproj.html": 0.4705,
-    "conformance/glsl/samplers/glsl-function-texture2dprojlod.html": 1.4089,
-    "conformance/glsl/variables/gl-fragcoord-xy-values.html": 0.3019,
-    "conformance/glsl/variables/gl-fragcoord.html": 0.4436,
-    "conformance/glsl/variables/gl-fragdata-and-fragcolor.html": 0.4123,
-    "conformance/glsl/variables/gl-frontfacing.html": 0.4304,
-    "conformance/glsl/variables/gl-pointcoord.html": 0.4373,
-    "conformance/glsl/variables/glsl-built-ins.html": 0.3709,
-    "conformance/limits/gl-line-width.html": 0.3446,
-    "conformance/limits/gl-max-texture-dimensions.html": 0.2941,
-    "conformance/limits/gl-min-attribs.html": 0.3158,
-    "conformance/limits/gl-min-textures.html": 0.2636,
-    "conformance/limits/gl-min-uniforms.html": 0.2759,
-    "conformance/misc/bad-arguments-test.html": 0.3597,
-    "conformance/misc/boolean-argument-conversion.html": 0.3114,
-    "conformance/misc/delayed-drawing.html": 1.1728,
-    "conformance/misc/error-reporting.html": 0.1545,
-    "conformance/misc/expando-loss.html": 0.229,
-    "conformance/misc/functions-returning-strings.html": 0.1661,
-    "conformance/misc/instanceof-test.html": 0.2698,
-    "conformance/misc/invalid-passed-params.html": 0.33,
-    "conformance/misc/is-object.html": 0.3016,
-    "conformance/misc/null-object-behaviour.html": 0.1747,
-    "conformance/misc/object-deletion-behaviour.html": 0.7011,
-    "conformance/misc/shader-precision-format.html": 0.7092,
-    "conformance/misc/type-conversion-test.html": 0.4929,
-    "conformance/misc/uninitialized-test.html": 0.4662,
-    "conformance/misc/webgl-specific-stencil-settings.html": 1.0675,
-    "conformance/misc/webgl-specific.html": 0.174,
-    "conformance/more/conformance/constants.html": 0.2216,
-    "conformance/more/conformance/getContext.html": 0.2363,
-    "conformance/more/conformance/methods.html": 0.1697,
-    "conformance/more/conformance/quickCheckAPI-A.html": 0.2306,
-    "conformance/more/conformance/quickCheckAPI-B1.html": 0.4825,
-    "conformance/more/conformance/quickCheckAPI-B2.html": 0.2986,
-    "conformance/more/conformance/quickCheckAPI-B3.html": 0.4818,
-    "conformance/more/conformance/quickCheckAPI-B4.html": 0.3138,
-    "conformance/more/conformance/quickCheckAPI-C.html": 0.2751,
-    "conformance/more/conformance/quickCheckAPI-D_G.html": 0.3502,
-    "conformance/more/conformance/quickCheckAPI-G_I.html": 0.5583,
-    "conformance/more/conformance/quickCheckAPI-L_S.html": 0.2702,
-    "conformance/more/conformance/quickCheckAPI-S_V.html": 0.3351,
-    "conformance/more/conformance/webGLArrays.html": 0.2269,
-    "conformance/more/functions/bindBuffer.html": 0.1835,
-    "conformance/more/functions/bindBufferBadArgs.html": 0.2486,
-    "conformance/more/functions/bindFramebufferLeaveNonZero.html": 0.1685,
-    "conformance/more/functions/bufferData.html": 0.4168,
-    "conformance/more/functions/bufferDataBadArgs.html": 0.1819,
-    "conformance/more/functions/bufferSubData.html": 0.2141,
-    "conformance/more/functions/bufferSubDataBadArgs.html": 0.1811,
-    "conformance/more/functions/copyTexImage2D.html": 0.2411,
-    "conformance/more/functions/copyTexImage2DBadArgs.html": 0.2275,
-    "conformance/more/functions/copyTexSubImage2D.html": 0.4325,
-    "conformance/more/functions/copyTexSubImage2DBadArgs.html": 0.1798,
-    "conformance/more/functions/deleteBufferBadArgs.html": 0.1491,
-    "conformance/more/functions/drawArrays.html": 0.2024,
-    "conformance/more/functions/drawElements.html": 0.3889,
-    "conformance/more/functions/isTests.html": 0.2304,
-    "conformance/more/functions/isTestsBadArgs.html": 0.1855,
-    "conformance/more/functions/readPixels.html": 0.1548,
-    "conformance/more/functions/readPixelsBadArgs.html": 0.2126,
-    "conformance/more/functions/texImage2D.html": 0.47,
-    "conformance/more/functions/texImage2DBadArgs.html": 0.2109,
-    "conformance/more/functions/texImage2DHTML.html": 0.3482,
-    "conformance/more/functions/texImage2DHTMLBadArgs.html": 0.3758,
-    "conformance/more/functions/texSubImage2D.html": 0.2087,
-    "conformance/more/functions/texSubImage2DBadArgs.html": 0.2308,
-    "conformance/more/functions/texSubImage2DHTML.html": 0.3058,
-    "conformance/more/functions/texSubImage2DHTMLBadArgs.html": 0.1752,
-    "conformance/more/functions/uniformMatrix.html": 0.1962,
-    "conformance/more/functions/uniformMatrixBadArgs.html": 0.4036,
-    "conformance/more/functions/uniformf.html": 0.3315,
-    "conformance/more/functions/uniformfArrayLen1.html": 0.3787,
-    "conformance/more/functions/uniformfBadArgs.html": 0.3923,
-    "conformance/more/functions/uniformi.html": 0.3857,
-    "conformance/more/functions/uniformiBadArgs.html": 0.438,
-    "conformance/more/functions/vertexAttrib.html": 0.4085,
-    "conformance/more/functions/vertexAttribBadArgs.html": 0.2996,
-    "conformance/more/functions/vertexAttribPointer.html": 0.372,
-    "conformance/more/functions/vertexAttribPointerBadArgs.html": 0.1796,
-    "conformance/more/glsl/arrayOutOfBounds.html": 0.2983,
-    "conformance/more/glsl/uniformOutOfBounds.html": 0.3697,
-    "conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html": 0.8863,
-    "conformance/offscreencanvas/context-creation-worker.html": 0.1972,
-    "conformance/offscreencanvas/context-creation.html": 0.1756,
-    "conformance/offscreencanvas/context-lost-restored-worker.html": 0.2918,
-    "conformance/offscreencanvas/context-lost-restored.html": 0.2506,
-    "conformance/offscreencanvas/context-lost-worker.html": 0.1784,
-    "conformance/offscreencanvas/context-lost.html": 0.2545,
-    "conformance/offscreencanvas/methods-worker.html": 0.1871,
-    "conformance/offscreencanvas/methods.html": 0.1238,
-    "conformance/offscreencanvas/offscreencanvas-resize.html": 0.118,
-    "conformance/offscreencanvas/offscreencanvas-timer-query.html": 0.1545,
-    "conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.1624,
-    "conformance/ogles/GL/abs/abs_001_to_006.html": 3.0576,
-    "conformance/ogles/GL/acos/acos_001_to_006.html": 3.1756,
-    "conformance/ogles/GL/all/all_001_to_004.html": 2.7893,
-    "conformance/ogles/GL/any/any_001_to_004.html": 2.8931,
-    "conformance/ogles/GL/array/array_001_to_006.html": 0.8615,
-    "conformance/ogles/GL/asin/asin_001_to_006.html": 3.083,
-    "conformance/ogles/GL/atan/atan_001_to_008.html": 3.309,
-    "conformance/ogles/GL/atan/atan_009_to_012.html": 3.0116,
-    "conformance/ogles/GL/biConstants/biConstants_001_to_008.html": 3.0817,
-    "conformance/ogles/GL/biConstants/biConstants_009_to_016.html": 3.1362,
-    "conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html": 2.4285,
-    "conformance/ogles/GL/build/build_001_to_008.html": 0.5295,
-    "conformance/ogles/GL/build/build_009_to_016.html": 0.3772,
-    "conformance/ogles/GL/build/build_017_to_024.html": 0.3625,
-    "conformance/ogles/GL/build/build_025_to_032.html": 0.4222,
-    "conformance/ogles/GL/build/build_033_to_040.html": 0.4141,
-    "conformance/ogles/GL/build/build_041_to_048.html": 0.3879,
-    "conformance/ogles/GL/build/build_049_to_056.html": 0.2814,
-    "conformance/ogles/GL/build/build_057_to_064.html": 0.3656,
-    "conformance/ogles/GL/build/build_065_to_072.html": 0.3606,
-    "conformance/ogles/GL/build/build_073_to_080.html": 0.2728,
-    "conformance/ogles/GL/build/build_081_to_088.html": 0.2589,
-    "conformance/ogles/GL/build/build_089_to_096.html": 0.3023,
-    "conformance/ogles/GL/build/build_097_to_104.html": 0.2908,
-    "conformance/ogles/GL/build/build_105_to_112.html": 0.3813,
-    "conformance/ogles/GL/build/build_113_to_120.html": 0.3016,
-    "conformance/ogles/GL/build/build_121_to_128.html": 0.2615,
-    "conformance/ogles/GL/build/build_129_to_136.html": 0.2834,
-    "conformance/ogles/GL/build/build_137_to_144.html": 0.2286,
-    "conformance/ogles/GL/build/build_145_to_152.html": 0.3143,
-    "conformance/ogles/GL/build/build_153_to_160.html": 0.5004,
-    "conformance/ogles/GL/build/build_161_to_168.html": 0.2334,
-    "conformance/ogles/GL/build/build_169_to_176.html": 0.3228,
-    "conformance/ogles/GL/build/build_177_to_178.html": 0.4456,
-    "conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html": 0.2985,
-    "conformance/ogles/GL/ceil/ceil_001_to_006.html": 2.8113,
-    "conformance/ogles/GL/clamp/clamp_001_to_006.html": 2.7438,
-    "conformance/ogles/GL/control_flow/control_flow_001_to_008.html": 0.8988,
-    "conformance/ogles/GL/control_flow/control_flow_009_to_010.html": 0.6353,
-    "conformance/ogles/GL/cos/cos_001_to_006.html": 2.9236,
-    "conformance/ogles/GL/cross/cross_001_to_002.html": 2.3791,
-    "conformance/ogles/GL/default/default_001_to_001.html": 0.5495,
-    "conformance/ogles/GL/degrees/degrees_001_to_006.html": 2.988,
-    "conformance/ogles/GL/discard/discard_001_to_002.html": 0.6335,
-    "conformance/ogles/GL/distance/distance_001_to_006.html": 2.8008,
-    "conformance/ogles/GL/dot/dot_001_to_006.html": 2.9553,
-    "conformance/ogles/GL/equal/equal_001_to_008.html": 3.2366,
-    "conformance/ogles/GL/equal/equal_009_to_012.html": 2.865,
-    "conformance/ogles/GL/exp/exp_001_to_008.html": 3.1542,
-    "conformance/ogles/GL/exp/exp_009_to_012.html": 2.71,
-    "conformance/ogles/GL/exp2/exp2_001_to_008.html": 3.2164,
-    "conformance/ogles/GL/exp2/exp2_009_to_012.html": 2.5925,
-    "conformance/ogles/GL/faceforward/faceforward_001_to_006.html": 2.913,
-    "conformance/ogles/GL/floor/floor_001_to_006.html": 2.8012,
-    "conformance/ogles/GL/fract/fract_001_to_006.html": 2.9837,
-    "conformance/ogles/GL/functions/functions_001_to_008.html": 2.9413,
-    "conformance/ogles/GL/functions/functions_009_to_016.html": 0.9236,
-    "conformance/ogles/GL/functions/functions_017_to_024.html": 0.8332,
-    "conformance/ogles/GL/functions/functions_025_to_032.html": 0.8598,
-    "conformance/ogles/GL/functions/functions_033_to_040.html": 0.9865,
-    "conformance/ogles/GL/functions/functions_041_to_048.html": 0.9595,
-    "conformance/ogles/GL/functions/functions_049_to_056.html": 0.971,
-    "conformance/ogles/GL/functions/functions_057_to_064.html": 0.9378,
-    "conformance/ogles/GL/functions/functions_065_to_072.html": 0.9406,
-    "conformance/ogles/GL/functions/functions_073_to_080.html": 0.96,
-    "conformance/ogles/GL/functions/functions_081_to_088.html": 0.8297,
-    "conformance/ogles/GL/functions/functions_089_to_096.html": 0.8457,
-    "conformance/ogles/GL/functions/functions_097_to_104.html": 0.7903,
-    "conformance/ogles/GL/functions/functions_105_to_112.html": 0.8379,
-    "conformance/ogles/GL/functions/functions_113_to_120.html": 0.8257,
-    "conformance/ogles/GL/functions/functions_121_to_126.html": 0.8514,
-    "conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html": 0.7954,
-    "conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html": 0.5474,
-    "conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html": 3.2756,
-    "conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html": 3.178,
-    "conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html": 2.9927,
-    "conformance/ogles/GL/length/length_001_to_006.html": 2.8224,
-    "conformance/ogles/GL/lessThan/lessThan_001_to_008.html": 3.1085,
-    "conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html": 3.2011,
-    "conformance/ogles/GL/log/log_001_to_008.html": 3.2484,
-    "conformance/ogles/GL/log/log_009_to_012.html": 2.7251,
-    "conformance/ogles/GL/log2/log2_001_to_008.html": 3.2877,
-    "conformance/ogles/GL/log2/log2_009_to_012.html": 3.0291,
-    "conformance/ogles/GL/mat/mat_001_to_008.html": 1.0346,
-    "conformance/ogles/GL/mat/mat_009_to_016.html": 0.9352,
-    "conformance/ogles/GL/mat/mat_017_to_024.html": 0.9576,
-    "conformance/ogles/GL/mat/mat_025_to_032.html": 3.2795,
-    "conformance/ogles/GL/mat/mat_033_to_040.html": 2.7373,
-    "conformance/ogles/GL/mat/mat_041_to_046.html": 0.8201,
-    "conformance/ogles/GL/mat3/mat3_001_to_006.html": 0.7504,
-    "conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html": 2.7801,
-    "conformance/ogles/GL/max/max_001_to_006.html": 2.8404,
-    "conformance/ogles/GL/min/min_001_to_006.html": 2.9012,
-    "conformance/ogles/GL/mix/mix_001_to_006.html": 2.856,
-    "conformance/ogles/GL/mod/mod_001_to_008.html": 2.9104,
-    "conformance/ogles/GL/normalize/normalize_001_to_006.html": 3.0215,
-    "conformance/ogles/GL/not/not_001_to_004.html": 2.8427,
-    "conformance/ogles/GL/notEqual/notEqual_001_to_008.html": 3.2998,
-    "conformance/ogles/GL/notEqual/notEqual_009_to_012.html": 2.8511,
-    "conformance/ogles/GL/operators/operators_001_to_008.html": 0.9772,
-    "conformance/ogles/GL/operators/operators_009_to_016.html": 1.0223,
-    "conformance/ogles/GL/operators/operators_017_to_024.html": 0.9853,
-    "conformance/ogles/GL/operators/operators_025_to_026.html": 0.5819,
-    "conformance/ogles/GL/pow/pow_001_to_008.html": 1.1755,
-    "conformance/ogles/GL/pow/pow_009_to_016.html": 3.0542,
-    "conformance/ogles/GL/pow/pow_017_to_024.html": 3.4157,
-    "conformance/ogles/GL/radians/radians_001_to_006.html": 2.9386,
-    "conformance/ogles/GL/reflect/reflect_001_to_006.html": 3.0921,
-    "conformance/ogles/GL/refract/refract_001_to_006.html": 2.903,
-    "conformance/ogles/GL/sign/sign_001_to_006.html": 2.9341,
-    "conformance/ogles/GL/sin/sin_001_to_006.html": 3.1525,
-    "conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html": 2.8567,
-    "conformance/ogles/GL/sqrt/sqrt_001_to_006.html": 2.8436,
-    "conformance/ogles/GL/step/step_001_to_006.html": 2.8796,
-    "conformance/ogles/GL/struct/struct_001_to_008.html": 3.0879,
-    "conformance/ogles/GL/struct/struct_009_to_016.html": 3.1023,
-    "conformance/ogles/GL/struct/struct_017_to_024.html": 3.1827,
-    "conformance/ogles/GL/struct/struct_025_to_032.html": 3.183,
-    "conformance/ogles/GL/struct/struct_033_to_040.html": 3.1225,
-    "conformance/ogles/GL/struct/struct_041_to_048.html": 3.143,
-    "conformance/ogles/GL/struct/struct_049_to_056.html": 3.1715,
-    "conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html": 3.2537,
-    "conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html": 3.2345,
-    "conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html": 3.2211,
-    "conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html": 3.1643,
-    "conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html": 3.1953,
-    "conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html": 3.1934,
-    "conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html": 3.2093,
-    "conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html": 3.2287,
-    "conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html": 3.1772,
-    "conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html": 3.2557,
-    "conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html": 3.2179,
-    "conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html": 3.1973,
-    "conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html": 3.1944,
-    "conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html": 3.1898,
-    "conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html": 3.2581,
-    "conformance/ogles/GL/tan/tan_001_to_006.html": 2.9109,
-    "conformance/ogles/GL/vec/vec_001_to_008.html": 0.9127,
-    "conformance/ogles/GL/vec/vec_009_to_016.html": 1.0669,
-    "conformance/ogles/GL/vec/vec_017_to_018.html": 0.7283,
-    "conformance/ogles/GL/vec3/vec3_001_to_008.html": 0.9121,
-    "conformance/programs/get-active-test.html": 0.4897,
-    "conformance/programs/gl-bind-attrib-location-long-names-test.html": 0.5214,
-    "conformance/programs/gl-bind-attrib-location-test.html": 0.2709,
-    "conformance/programs/gl-get-active-attribute.html": 0.3877,
-    "conformance/programs/gl-get-active-uniform.html": 0.5135,
-    "conformance/programs/gl-getshadersource.html": 0.2037,
-    "conformance/programs/gl-shader-test.html": 0.1974,
-    "conformance/programs/invalid-UTF-16.html": 0.1365,
-    "conformance/programs/program-handling.html": 0.8657,
-    "conformance/programs/program-infolog.html": 0.9789,
-    "conformance/programs/program-test.html": 0.4145,
-    "conformance/programs/use-program-crash-with-discard-in-fragment-shader.html": 0.2757,
-    "conformance/reading/fbo-remains-unchanged-after-read-pixels.html": 0.2413,
-    "conformance/reading/read-pixels-pack-alignment.html": 0.5429,
-    "conformance/reading/read-pixels-test.html": 0.908,
-    "conformance/renderbuffers/depth-renderbuffer-initialization.html": 0.6365,
-    "conformance/renderbuffers/feedback-loop.html": 0.1258,
-    "conformance/renderbuffers/framebuffer-object-attachment.html": 0.4768,
-    "conformance/renderbuffers/framebuffer-state-restoration.html": 0.7746,
-    "conformance/renderbuffers/framebuffer-test.html": 0.4586,
-    "conformance/renderbuffers/renderbuffer-initialization.html": 0.4642,
-    "conformance/renderbuffers/stencil-renderbuffer-initialization.html": 0.2946,
-    "conformance/rendering/bind-framebuffer-flush-bug.html": 0.1121,
-    "conformance/rendering/blending.html": 1.0546,
-    "conformance/rendering/canvas-alpha-bug.html": 0.4214,
-    "conformance/rendering/clear-after-copyTexImage2D.html": 0.4166,
-    "conformance/rendering/clipping-wide-points.html": 0.1645,
-    "conformance/rendering/color-mask-preserved-during-implicit-clears.html": 1.9985,
-    "conformance/rendering/culling.html": 0.107,
-    "conformance/rendering/default-texture-draw-bug.html": 0.3504,
-    "conformance/rendering/draw-arrays-out-of-bounds.html": 0.2342,
-    "conformance/rendering/draw-elements-out-of-bounds.html": 0.2948,
-    "conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html": 0.4038,
-    "conformance/rendering/draw-with-changing-start-vertex-bug.html": 0.459,
-    "conformance/rendering/framebuffer-switch.html": 0.5087,
-    "conformance/rendering/framebuffer-texture-clear.html": 0.481,
-    "conformance/rendering/framebuffer-texture-switch.html": 0.3826,
-    "conformance/rendering/gl-clear.html": 0.1101,
-    "conformance/rendering/gl-drawarrays.html": 0.1088,
-    "conformance/rendering/gl-drawelements.html": 0.3154,
-    "conformance/rendering/gl-scissor-canvas-dimensions.html": 0.3893,
-    "conformance/rendering/gl-scissor-fbo-test.html": 0.261,
-    "conformance/rendering/gl-scissor-test.html": 0.524,
-    "conformance/rendering/gl-viewport-test.html": 0.5979,
-    "conformance/rendering/line-loop-tri-fan.html": 0.1209,
-    "conformance/rendering/line-rendering-quality.html": 0.2936,
-    "conformance/rendering/many-draw-calls.html": 1.7749,
-    "conformance/rendering/more-than-65536-indices.html": 0.6858,
-    "conformance/rendering/multisample-corruption.html": 3.6258,
-    "conformance/rendering/negative-one-index.html": 0.1928,
-    "conformance/rendering/out-of-bounds-array-buffers.html": 0.2525,
-    "conformance/rendering/out-of-bounds-index-buffers.html": 0.1841,
-    "conformance/rendering/point-no-attributes.html": 0.2197,
-    "conformance/rendering/point-size.html": 0.3316,
-    "conformance/rendering/point-specific-shader-variables.html": 0.2577,
-    "conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html": 0.2656,
-    "conformance/rendering/polygon-offset.html": 0.3308,
-    "conformance/rendering/preservedrawingbuffer-leak.html": 1.2922,
-    "conformance/rendering/rendering-sampling-feedback-loop.html": 0.1385,
-    "conformance/rendering/rendering-stencil-large-viewport.html": 0.4007,
-    "conformance/rendering/scissor-rect-repeated-rendering.html": 0.4413,
-    "conformance/rendering/simple.html": 0.1883,
-    "conformance/rendering/texture-switch-performance.html": 0.0,
-    "conformance/rendering/triangle.html": 0.2996,
-    "conformance/state/fb-attach-implicit-target-assignment.html": 0.1146,
-    "conformance/state/gl-enable-enum-test.html": 0.266,
-    "conformance/state/gl-enum-tests.html": 0.2238,
-    "conformance/state/gl-get-calls.html": 0.3832,
-    "conformance/state/gl-geterror.html": 0.3304,
-    "conformance/state/gl-getstring.html": 0.0951,
-    "conformance/state/gl-initial-state.html": 0.131,
-    "conformance/state/gl-object-get-calls.html": 7.1149,
-    "conformance/state/state-uneffected-after-compositing.html": 0.4893,
-    "conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.8493,
-    "conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.2914,
-    "conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.9837,
-    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html": 2.6841,
-    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.9426,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html": 3.4007,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.0556,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.827,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html": 0.1809,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html": 0.1995,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.0875,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html": 0.157,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1512,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html": 0.1895,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1876,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.1984,
-    "conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html": 0.3552,
-    "conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html": 0.5588,
-    "conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3324,
-    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html": 0.6323,
-    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4369,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html": 0.4787,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3904,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4344,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html": 0.5385,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html": 0.54,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5671,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html": 0.5036,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5253,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html": 0.5308,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5746,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4893,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.9737,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.9797,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.7274,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 0.6119,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5978,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 0.6679,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5633,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7369,
-    "conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.475,
-    "conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.4807,
-    "conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.4719,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3944,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.451,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.457,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5221,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4809,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html": 0.512,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html": 0.4707,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.4172,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html": 0.4466,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.445,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html": 0.4293,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5003,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4892,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.5605,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.6354,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.524,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.5249,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5095,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.6235,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.6355,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4894,
-    "conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html": 0.5687,
-    "conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html": 0.524,
-    "conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.6411,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html": 0.4747,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4616,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html": 0.6793,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4566,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5401,
-    "conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.6215,
-    "conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.5455,
-    "conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5971,
-    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.5267,
-    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4956,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.4639,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.6631,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5259,
-    "conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html": 0.3446,
-    "conformance/textures/misc/compressed-tex-image.html": 0.2083,
-    "conformance/textures/misc/copy-tex-image-2d-formats.html": 0.4334,
-    "conformance/textures/misc/copy-tex-image-and-sub-image-2d.html": 0.9236,
-    "conformance/textures/misc/copy-tex-image-crash.html": 0.1926,
-    "conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html": 0.4571,
-    "conformance/textures/misc/copytexsubimage2d-subrects.html": 0.1339,
-    "conformance/textures/misc/cube-incomplete-fbo.html": 0.1922,
-    "conformance/textures/misc/cube-map-uploads-out-of-order.html": 1.1653,
-    "conformance/textures/misc/default-texture.html": 0.1888,
-    "conformance/textures/misc/exif-orientation.html": 0.8605,
-    "conformance/textures/misc/gl-get-tex-parameter.html": 0.1578,
-    "conformance/textures/misc/gl-pixelstorei.html": 0.2241,
-    "conformance/textures/misc/gl-teximage.html": 1.1716,
-    "conformance/textures/misc/mipmap-fbo.html": 0.4778,
-    "conformance/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.3053,
-    "conformance/textures/misc/origin-clean-conformance.html": 0.1891,
-    "conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html": 4.0711,
-    "conformance/textures/misc/tex-image-and-uniform-binding-bugs.html": 0.1228,
-    "conformance/textures/misc/tex-image-canvas-corruption.html": 0.593,
-    "conformance/textures/misc/tex-image-webgl.html": 0.3849,
-    "conformance/textures/misc/tex-image-with-format-and-type.html": 1.026,
-    "conformance/textures/misc/tex-image-with-invalid-data.html": 0.1227,
-    "conformance/textures/misc/tex-input-validation.html": 0.2681,
-    "conformance/textures/misc/tex-sub-image-2d-bad-args.html": 0.1811,
-    "conformance/textures/misc/tex-sub-image-2d.html": 0.191,
-    "conformance/textures/misc/tex-video-using-tex-unit-non-zero.html": 0.8904,
-    "conformance/textures/misc/texparameter-test.html": 0.2504,
-    "conformance/textures/misc/texture-active-bind-2.html": 0.1543,
-    "conformance/textures/misc/texture-active-bind.html": 0.1893,
-    "conformance/textures/misc/texture-attachment-formats.html": 0.3092,
-    "conformance/textures/misc/texture-clear.html": 0.2923,
-    "conformance/textures/misc/texture-complete.html": 0.1221,
-    "conformance/textures/misc/texture-copying-and-deletion.html": 1.1053,
-    "conformance/textures/misc/texture-copying-feedback-loops.html": 0.1152,
-    "conformance/textures/misc/texture-corner-case-videos.html": 0.3581,
-    "conformance/textures/misc/texture-cube-as-fbo-attachment.html": 0.175,
-    "conformance/textures/misc/texture-draw-with-2d-and-cube.html": 0.1214,
-    "conformance/textures/misc/texture-fakeblack.html": 0.354,
-    "conformance/textures/misc/texture-formats-test.html": 0.2335,
-    "conformance/textures/misc/texture-hd-dpi.html": 0.3072,
-    "conformance/textures/misc/texture-mips.html": 0.265,
-    "conformance/textures/misc/texture-npot-video.html": 0.3558,
-    "conformance/textures/misc/texture-npot.html": 0.5314,
-    "conformance/textures/misc/texture-size-cube-maps.html": 1.1634,
-    "conformance/textures/misc/texture-size-limit.html": 0.5874,
-    "conformance/textures/misc/texture-size.html": 1.0896,
-    "conformance/textures/misc/texture-sub-image-cube-maps.html": 0.3962,
-    "conformance/textures/misc/texture-transparent-pixels-initialized.html": 0.2917,
-    "conformance/textures/misc/texture-upload-cube-maps.html": 0.3579,
-    "conformance/textures/misc/texture-upload-size.html": 0.4869,
-    "conformance/textures/misc/texture-video-transparent.html": 2.4969,
-    "conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html": 0.0899,
-    "conformance/textures/misc/upload-from-srcset-with-empty-data.html": 0.1374,
-    "conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.3167,
-    "conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.3677,
-    "conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3603,
-    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3335,
-    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.327,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.3637,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.376,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.2022,
-    "conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html": 0.4417,
-    "conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html": 0.5069,
-    "conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5131,
-    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html": 0.4837,
-    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4512,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html": 0.4132,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4095,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4376,
-    "conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.2666,
-    "conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.1763,
-    "conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.3798,
-    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 4.2373,
-    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.3754,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 3.8548,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.4663,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.3928,
-    "conformance/typedarrays/array-buffer-crash.html": 0.1286,
-    "conformance/typedarrays/array-buffer-view-crash.html": 0.1012,
-    "conformance/typedarrays/array-large-array-tests.html": 0.2515,
-    "conformance/typedarrays/array-unit-tests.html": 0.162,
-    "conformance/typedarrays/data-view-crash.html": 0.0458,
-    "conformance/typedarrays/data-view-test.html": 0.1401,
-    "conformance/typedarrays/typed-arrays-in-workers.html": 0.1708,
-    "conformance/uniforms/gl-uniform-arrays.html": 0.1844,
-    "conformance/uniforms/gl-uniform-bool.html": 0.2675,
-    "conformance/uniforms/gl-uniformmatrix4fv.html": 0.2983,
-    "conformance/uniforms/gl-unknown-uniform.html": 0.2563,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-00.html": 1.4036,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-01.html": 1.3243,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-02.html": 1.5677,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-03.html": 1.641,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-04.html": 1.5674,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-05.html": 1.5321,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-06.html": 1.6355,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-07.html": 1.4944,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-08.html": 1.4715,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-09.html": 1.5012,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-10.html": 1.4667,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-11.html": 1.6077,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-12.html": 1.4357,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-13.html": 1.9725,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-14.html": 1.645,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-15.html": 1.8384,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-16.html": 1.6414,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-17.html": 1.9326,
-    "conformance/uniforms/null-uniform-location.html": 0.3311,
-    "conformance/uniforms/out-of-bounds-uniform-array-access.html": 3.946,
-    "conformance/uniforms/uniform-default-values.html": 1.6615,
-    "conformance/uniforms/uniform-location.html": 0.4927,
-    "conformance/uniforms/uniform-samplers-test.html": 23.5508,
-    "conformance/uniforms/uniform-values-per-program.html": 1.5434,
-    "deqp/data/gles2/shaders/conditionals.html": 1.5326,
-    "deqp/data/gles2/shaders/constant_expressions.html": 1.6228,
-    "deqp/data/gles2/shaders/constants.html": 2.9544,
-    "deqp/data/gles2/shaders/conversions.html": 34.2201,
-    "deqp/data/gles2/shaders/declarations.html": 0.6276,
-    "deqp/data/gles2/shaders/fragdata.html": 0.5656,
-    "deqp/data/gles2/shaders/functions.html": 9.5772,
-    "deqp/data/gles2/shaders/invalid_texture_functions.html": 0.3042,
-    "deqp/data/gles2/shaders/keywords.html": 3.5592,
-    "deqp/data/gles2/shaders/linkage.html": 2.6213,
-    "deqp/data/gles2/shaders/preprocessor.html": 14.1594,
-    "deqp/data/gles2/shaders/qualification_order.html": 1.5231,
-    "deqp/data/gles2/shaders/reserved_operators.html": 0.742,
-    "deqp/data/gles2/shaders/scoping.html": 2.6424,
-    "deqp/data/gles2/shaders/swizzles.html": 38.9196
+    "WebglExtension_ANGLE_instanced_arrays": 0.2954,
+    "WebglExtension_EXT_blend_minmax": 0.2979,
+    "WebglExtension_EXT_color_buffer_half_float": 0.4416,
+    "WebglExtension_EXT_disjoint_timer_query": 0.3224,
+    "WebglExtension_EXT_float_blend": 0.4506,
+    "WebglExtension_EXT_frag_depth": 0.5017,
+    "WebglExtension_EXT_sRGB": 0.3729,
+    "WebglExtension_EXT_shader_texture_lod": 0.2195,
+    "WebglExtension_EXT_texture_compression_bptc": 0.2703,
+    "WebglExtension_EXT_texture_compression_rgtc": 0.4798,
+    "WebglExtension_EXT_texture_filter_anisotropic": 0.4524,
+    "WebglExtension_KHR_parallel_shader_compile": 0.3542,
+    "WebglExtension_OES_element_index_uint": 0.2213,
+    "WebglExtension_OES_fbo_render_mipmap": 0.2715,
+    "WebglExtension_OES_standard_derivatives": 0.224,
+    "WebglExtension_OES_texture_float": 0.3952,
+    "WebglExtension_OES_texture_float_linear": 0.379,
+    "WebglExtension_OES_texture_half_float": 0.3361,
+    "WebglExtension_OES_texture_half_float_linear": 0.1533,
+    "WebglExtension_OES_vertex_array_object": 0.1737,
+    "WebglExtension_TestCoverage": 0.1803,
+    "WebglExtension_WEBGL_color_buffer_float": 0.1872,
+    "WebglExtension_WEBGL_compressed_texture_astc": 0,
+    "WebglExtension_WEBGL_compressed_texture_etc": 0,
+    "WebglExtension_WEBGL_compressed_texture_etc1": 0,
+    "WebglExtension_WEBGL_compressed_texture_pvrtc": 0,
+    "WebglExtension_WEBGL_compressed_texture_s3tc": 0.1456,
+    "WebglExtension_WEBGL_compressed_texture_s3tc_srgb": 0,
+    "WebglExtension_WEBGL_debug_renderer_info": 0.1807,
+    "WebglExtension_WEBGL_debug_shaders": 0.1823,
+    "WebglExtension_WEBGL_depth_texture": 0.1319,
+    "WebglExtension_WEBGL_draw_buffers": 0.1403,
+    "WebglExtension_WEBGL_lose_context": 0.1421,
+    "WebglExtension_WEBGL_multi_draw": 0.1295,
+    "WebglExtension_WEBGL_video_texture": 0.135,
+    "WebglExtension_WEBGL_webcodecs_video_frame": 0,
+    "conformance/attribs/gl-bindAttribLocation-aliasing.html": 0.1652,
+    "conformance/attribs/gl-bindAttribLocation-matrix.html": 0.3649,
+    "conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html": 0.1191,
+    "conformance/attribs/gl-bindAttribLocation-repeated.html": 0.1365,
+    "conformance/attribs/gl-disabled-vertex-attrib-update.html": 0.1041,
+    "conformance/attribs/gl-disabled-vertex-attrib.html": 0.421,
+    "conformance/attribs/gl-enable-vertex-attrib.html": 0.2382,
+    "conformance/attribs/gl-matrix-attributes.html": 0.5124,
+    "conformance/attribs/gl-vertex-attrib-context-switch.html": 0.4843,
+    "conformance/attribs/gl-vertex-attrib-render.html": 0.2106,
+    "conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html": 0.1247,
+    "conformance/attribs/gl-vertex-attrib-zero-issues.html": 0.2875,
+    "conformance/attribs/gl-vertex-attrib.html": 0.365,
+    "conformance/attribs/gl-vertexattribpointer-offsets.html": 0.1604,
+    "conformance/attribs/gl-vertexattribpointer.html": 0.4548,
+    "conformance/buffers/buffer-bind-test.html": 0.1658,
+    "conformance/buffers/buffer-data-and-buffer-sub-data.html": 0.0684,
+    "conformance/buffers/buffer-data-array-buffer-delete.html": 2.1136,
+    "conformance/buffers/buffer-data-dynamic-delay.html": 0.2366,
+    "conformance/buffers/buffer-uninitialized.html": 0.5386,
+    "conformance/buffers/element-array-buffer-delete-recreate.html": 0.1137,
+    "conformance/buffers/index-validation-copies-indices.html": 0.0749,
+    "conformance/buffers/index-validation-crash-with-buffer-sub-data.html": 0.0571,
+    "conformance/buffers/index-validation-large-buffer.html": 0.0842,
+    "conformance/buffers/index-validation-verifies-too-many-indices.html": 0.2369,
+    "conformance/buffers/index-validation-with-resized-buffer.html": 0.2725,
+    "conformance/buffers/index-validation.html": 0.0708,
+    "conformance/buffers/vertex-buffer-updated-after-draw.html": 0.3269,
+    "conformance/canvas/buffer-offscreen-test.html": 0.4334,
+    "conformance/canvas/buffer-preserve-test.html": 0.9941,
+    "conformance/canvas/canvas-test.html": 0.3836,
+    "conformance/canvas/canvas-zero-size.html": 0.2065,
+    "conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html": 0.7498,
+    "conformance/canvas/draw-webgl-to-canvas-test.html": 0.5381,
+    "conformance/canvas/drawingbuffer-hd-dpi-test.html": 0.389,
+    "conformance/canvas/drawingbuffer-static-canvas-test.html": 0.2443,
+    "conformance/canvas/drawingbuffer-test.html": 0.2461,
+    "conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html": 0.2054,
+    "conformance/canvas/framebuffer-bindings-unaffected-on-resize.html": 0.2734,
+    "conformance/canvas/rapid-resizing.html": 2.3716,
+    "conformance/canvas/render-after-resize-test.html": 0.0964,
+    "conformance/canvas/texture-bindings-unaffected-on-resize.html": 0.2536,
+    "conformance/canvas/to-data-url-after-composite.html": 0.1871,
+    "conformance/canvas/to-data-url-test.html": 0.449,
+    "conformance/canvas/viewport-unchanged-upon-resize.html": 0.1672,
+    "conformance/canvas/webgl-to-2d-canvas.html": 0.6557,
+    "conformance/context/constants-and-properties.html": 0.0596,
+    "conformance/context/context-attribute-preserve-drawing-buffer-antialias.html": 0.3003,
+    "conformance/context/context-attribute-preserve-drawing-buffer.html": 0.5817,
+    "conformance/context/context-attributes-alpha-depth-stencil-antialias.html": 0.7126,
+    "conformance/context/context-creation-and-destruction.html": 0.854,
+    "conformance/context/context-creation.html": 0.9662,
+    "conformance/context/context-eviction-with-garbage-collection.html": 1.2282,
+    "conformance/context/context-hidden-alpha.html": 0.3076,
+    "conformance/context/context-lost-restored.html": 0.3534,
+    "conformance/context/context-lost.html": 0.1318,
+    "conformance/context/context-no-alpha-fbo-with-alpha.html": 0.1964,
+    "conformance/context/context-release-upon-reload.html": 1.9936,
+    "conformance/context/context-release-with-workers.html": 1.8933,
+    "conformance/context/context-size-change.html": 0.141,
+    "conformance/context/context-type-test.html": 0.0612,
+    "conformance/context/deleted-object-behavior.html": 0.1444,
+    "conformance/context/incorrect-context-object-behaviour.html": 0.3601,
+    "conformance/context/methods.html": 0.0814,
+    "conformance/context/premultiplyalpha-test.html": 0.6756,
+    "conformance/context/user-defined-properties-on-context.html": 0.0915,
+    "conformance/context/zero-sized-canvas.html": 0.1955,
+    "conformance/extensions/angle-instanced-arrays-out-of-bounds.html": 0.8169,
+    "conformance/extensions/angle-instanced-arrays.html": 2.1623,
+    "conformance/extensions/ext-blend-minmax.html": 0.1119,
+    "conformance/extensions/ext-color-buffer-half-float.html": 0.1703,
+    "conformance/extensions/ext-disjoint-timer-query.html": 5.1028,
+    "conformance/extensions/ext-float-blend.html": 0.2188,
+    "conformance/extensions/ext-frag-depth.html": 0.4029,
+    "conformance/extensions/ext-sRGB.html": 0.1686,
+    "conformance/extensions/ext-shader-texture-lod.html": 0.7634,
+    "conformance/extensions/ext-texture-compression-bptc.html": 0.2826,
+    "conformance/extensions/ext-texture-compression-rgtc.html": 0.2313,
+    "conformance/extensions/ext-texture-filter-anisotropic.html": 0.1141,
+    "conformance/extensions/get-extension.html": 0.2334,
+    "conformance/extensions/khr-parallel-shader-compile.html": 10.3414,
+    "conformance/extensions/oes-element-index-uint.html": 0.4272,
+    "conformance/extensions/oes-fbo-render-mipmap.html": 0.0961,
+    "conformance/extensions/oes-standard-derivatives.html": 0.5339,
+    "conformance/extensions/oes-texture-float-linear.html": 0.2648,
+    "conformance/extensions/oes-texture-float-with-canvas.html": 0.7468,
+    "conformance/extensions/oes-texture-float-with-image-data.html": 0.1692,
+    "conformance/extensions/oes-texture-float-with-image.html": 0.2275,
+    "conformance/extensions/oes-texture-float-with-video.html": 1.7888,
+    "conformance/extensions/oes-texture-float.html": 0.1654,
+    "conformance/extensions/oes-texture-half-float-linear.html": 0.4341,
+    "conformance/extensions/oes-texture-half-float-with-canvas.html": 1.2674,
+    "conformance/extensions/oes-texture-half-float-with-image-data.html": 0.3967,
+    "conformance/extensions/oes-texture-half-float-with-image.html": 0.3557,
+    "conformance/extensions/oes-texture-half-float-with-video.html": 2.7621,
+    "conformance/extensions/oes-texture-half-float.html": 0.4073,
+    "conformance/extensions/oes-vertex-array-object-bufferData.html": 0.2238,
+    "conformance/extensions/oes-vertex-array-object.html": 0.3544,
+    "conformance/extensions/s3tc-and-rgtc.html": 0.7811,
+    "conformance/extensions/webgl-compressed-texture-astc.html": 0.1371,
+    "conformance/extensions/webgl-compressed-texture-etc.html": 0.0538,
+    "conformance/extensions/webgl-compressed-texture-etc1.html": 0.0668,
+    "conformance/extensions/webgl-compressed-texture-pvrtc.html": 0.2166,
+    "conformance/extensions/webgl-compressed-texture-s3tc-srgb.html": 0.6658,
+    "conformance/extensions/webgl-compressed-texture-size-limit.html": 2.965,
+    "conformance/extensions/webgl-debug-renderer-info.html": 0.2422,
+    "conformance/extensions/webgl-debug-shaders.html": 0.0899,
+    "conformance/extensions/webgl-depth-texture.html": 0.2964,
+    "conformance/extensions/webgl-draw-buffers-broadcast-return.html": 0.1102,
+    "conformance/extensions/webgl-draw-buffers-framebuffer-unsupported.html": 0.1252,
+    "conformance/extensions/webgl-draw-buffers-max-draw-buffers.html": 0.1059,
+    "conformance/extensions/webgl-draw-buffers.html": 0.7193,
+    "conformance/extensions/webgl-multi-draw.html": 2.9188,
+    "conformance/glsl/bugs/angle-ambiguous-function-call.html": 0.2495,
+    "conformance/glsl/bugs/angle-constructor-invalid-parameters.html": 0.2971,
+    "conformance/glsl/bugs/angle-d3d11-compiler-error.html": 0.0792,
+    "conformance/glsl/bugs/angle-dx-variable-bug.html": 0.263,
+    "conformance/glsl/bugs/array-of-struct-with-int-first-position.html": 0.1561,
+    "conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html": 0.1098,
+    "conformance/glsl/bugs/bool-type-cast-bug-int-float.html": 0.2237,
+    "conformance/glsl/bugs/character-set.html": 0.1703,
+    "conformance/glsl/bugs/compare-loop-index-to-uniform.html": 0.0836,
+    "conformance/glsl/bugs/complex-glsl-does-not-crash.html": 1.3748,
+    "conformance/glsl/bugs/compound-assignment-type-combination.html": 0.9665,
+    "conformance/glsl/bugs/conditional-discard-in-loop.html": 0.1418,
+    "conformance/glsl/bugs/conditional-discard-optimization.html": 0.2566,
+    "conformance/glsl/bugs/conditional-texture-fetch.html": 0.2261,
+    "conformance/glsl/bugs/constant-precision-qualifier.html": 0.1489,
+    "conformance/glsl/bugs/essl3-shaders-with-webgl1.html": 0.1587,
+    "conformance/glsl/bugs/floor-div-cos-should-not-truncate.html": 0.163,
+    "conformance/glsl/bugs/floored-division-accuracy.html": 0.2966,
+    "conformance/glsl/bugs/fragcoord-linking-bug.html": 0.2227,
+    "conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html": 0.4446,
+    "conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html": 0.2097,
+    "conformance/glsl/bugs/if-return-and-elseif.html": 0.1172,
+    "conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html": 0.1463,
+    "conformance/glsl/bugs/init-array-with-loop.html": 0.2667,
+    "conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html": 0.0628,
+    "conformance/glsl/bugs/logic-inside-block-without-braces.html": 0.2493,
+    "conformance/glsl/bugs/long-expressions-should-not-crash.html": 0.4816,
+    "conformance/glsl/bugs/loop-if-loop-gradient.html": 0.1585,
+    "conformance/glsl/bugs/modulo-arithmetic-accuracy.html": 0.2321,
+    "conformance/glsl/bugs/multiplication-assignment.html": 0.1263,
+    "conformance/glsl/bugs/nested-functions-should-not-crash.html": 0.2823,
+    "conformance/glsl/bugs/nested-loops-with-break-and-continue.html": 0.2533,
+    "conformance/glsl/bugs/nested-sequence-operator.html": 0.2252,
+    "conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html": 0.2409,
+    "conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html": 0.2765,
+    "conformance/glsl/bugs/qualcomm-crash.html": 0.1565,
+    "conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html": 0.2304,
+    "conformance/glsl/bugs/sampler-array-struct-function-arg.html": 0.2436,
+    "conformance/glsl/bugs/sampler-array-using-loop-index.html": 0.1375,
+    "conformance/glsl/bugs/sampler-struct-function-arg.html": 0.1593,
+    "conformance/glsl/bugs/sequence-operator-evaluation-order.html": 0.2428,
+    "conformance/glsl/bugs/sketchfab-lighting-shader-crash.html": 0.3022,
+    "conformance/glsl/bugs/struct-constructor-highp-bug.html": 0.2332,
+    "conformance/glsl/bugs/struct-with-single-member-constructor.html": 0.2039,
+    "conformance/glsl/bugs/temp-expressions-should-not-crash.html": 1.0923,
+    "conformance/glsl/bugs/unary-minus-operator-float-bug.html": 0.2482,
+    "conformance/glsl/bugs/undefined-index-should-not-crash.html": 0.1833,
+    "conformance/glsl/bugs/uniforms-should-not-lose-values.html": 0.3134,
+    "conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html": 0.3162,
+    "conformance/glsl/bugs/vector-matrix-constructor-scalarization.html": 0.3397,
+    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html": 0.1147,
+    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html": 0.2863,
+    "conformance/glsl/constructors/glsl-construct-bvec2.html": 0.543,
+    "conformance/glsl/constructors/glsl-construct-bvec3.html": 0.6266,
+    "conformance/glsl/constructors/glsl-construct-bvec4.html": 0.7449,
+    "conformance/glsl/constructors/glsl-construct-ivec2.html": 0.4901,
+    "conformance/glsl/constructors/glsl-construct-ivec3.html": 0.6368,
+    "conformance/glsl/constructors/glsl-construct-ivec4.html": 0.7637,
+    "conformance/glsl/constructors/glsl-construct-mat2.html": 0.5897,
+    "conformance/glsl/constructors/glsl-construct-mat3.html": 0.39,
+    "conformance/glsl/constructors/glsl-construct-mat4.html": 0.4407,
+    "conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html": 0.3853,
+    "conformance/glsl/constructors/glsl-construct-vec-mat-index.html": 0.143,
+    "conformance/glsl/constructors/glsl-construct-vec2.html": 0.534,
+    "conformance/glsl/constructors/glsl-construct-vec3.html": 0.5353,
+    "conformance/glsl/constructors/glsl-construct-vec4.html": 0.6553,
+    "conformance/glsl/functions/glsl-function-abs.html": 0.3746,
+    "conformance/glsl/functions/glsl-function-acos.html": 0.4584,
+    "conformance/glsl/functions/glsl-function-asin.html": 0.39,
+    "conformance/glsl/functions/glsl-function-atan-xy.html": 0.5189,
+    "conformance/glsl/functions/glsl-function-atan.html": 0.3459,
+    "conformance/glsl/functions/glsl-function-ceil.html": 0.4053,
+    "conformance/glsl/functions/glsl-function-clamp-float.html": 0.3989,
+    "conformance/glsl/functions/glsl-function-clamp-gentype.html": 0.4101,
+    "conformance/glsl/functions/glsl-function-cos.html": 0.4171,
+    "conformance/glsl/functions/glsl-function-cross.html": 0.2917,
+    "conformance/glsl/functions/glsl-function-distance.html": 0.4186,
+    "conformance/glsl/functions/glsl-function-dot.html": 0.499,
+    "conformance/glsl/functions/glsl-function-faceforward.html": 0.4768,
+    "conformance/glsl/functions/glsl-function-floor.html": 0.3929,
+    "conformance/glsl/functions/glsl-function-fract.html": 0.3965,
+    "conformance/glsl/functions/glsl-function-length.html": 0.4651,
+    "conformance/glsl/functions/glsl-function-max-float.html": 0.4929,
+    "conformance/glsl/functions/glsl-function-max-gentype.html": 0.4665,
+    "conformance/glsl/functions/glsl-function-min-float.html": 0.4508,
+    "conformance/glsl/functions/glsl-function-min-gentype.html": 0.4654,
+    "conformance/glsl/functions/glsl-function-mix-float.html": 0.4836,
+    "conformance/glsl/functions/glsl-function-mix-gentype.html": 0.478,
+    "conformance/glsl/functions/glsl-function-mod-float.html": 0.4759,
+    "conformance/glsl/functions/glsl-function-mod-gentype.html": 0.4792,
+    "conformance/glsl/functions/glsl-function-normalize.html": 0.4508,
+    "conformance/glsl/functions/glsl-function-reflect.html": 0.4643,
+    "conformance/glsl/functions/glsl-function-sign.html": 0.4836,
+    "conformance/glsl/functions/glsl-function-sin.html": 0.4277,
+    "conformance/glsl/functions/glsl-function-smoothstep-float.html": 0.419,
+    "conformance/glsl/functions/glsl-function-smoothstep-gentype.html": 0.4501,
+    "conformance/glsl/functions/glsl-function-step-float.html": 0.4445,
+    "conformance/glsl/functions/glsl-function-step-gentype.html": 0.6626,
+    "conformance/glsl/functions/glsl-function.html": 0.6304,
+    "conformance/glsl/implicit/add_int_float.vert.html": 0.1978,
+    "conformance/glsl/implicit/add_int_mat2.vert.html": 0.2332,
+    "conformance/glsl/implicit/add_int_mat3.vert.html": 0.205,
+    "conformance/glsl/implicit/add_int_mat4.vert.html": 0.1693,
+    "conformance/glsl/implicit/add_int_vec2.vert.html": 0.2275,
+    "conformance/glsl/implicit/add_int_vec3.vert.html": 0.2346,
+    "conformance/glsl/implicit/add_int_vec4.vert.html": 0.1699,
+    "conformance/glsl/implicit/add_ivec2_vec2.vert.html": 0.2385,
+    "conformance/glsl/implicit/add_ivec3_vec3.vert.html": 0.1068,
+    "conformance/glsl/implicit/add_ivec4_vec4.vert.html": 0.1071,
+    "conformance/glsl/implicit/assign_int_to_float.vert.html": 0.1002,
+    "conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html": 0.105,
+    "conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html": 0.116,
+    "conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html": 0.0948,
+    "conformance/glsl/implicit/construct_struct.vert.html": 0.1004,
+    "conformance/glsl/implicit/divide_int_float.vert.html": 0.0969,
+    "conformance/glsl/implicit/divide_int_mat2.vert.html": 0.0755,
+    "conformance/glsl/implicit/divide_int_mat3.vert.html": 0.0957,
+    "conformance/glsl/implicit/divide_int_mat4.vert.html": 0.0907,
+    "conformance/glsl/implicit/divide_int_vec2.vert.html": 0.1387,
+    "conformance/glsl/implicit/divide_int_vec3.vert.html": 0.1369,
+    "conformance/glsl/implicit/divide_int_vec4.vert.html": 0.1136,
+    "conformance/glsl/implicit/divide_ivec2_vec2.vert.html": 0.114,
+    "conformance/glsl/implicit/divide_ivec3_vec3.vert.html": 0.1003,
+    "conformance/glsl/implicit/divide_ivec4_vec4.vert.html": 0.0973,
+    "conformance/glsl/implicit/equal_int_float.vert.html": 0.1138,
+    "conformance/glsl/implicit/equal_ivec2_vec2.vert.html": 0.1138,
+    "conformance/glsl/implicit/equal_ivec3_vec3.vert.html": 0.0928,
+    "conformance/glsl/implicit/equal_ivec4_vec4.vert.html": 0.0982,
+    "conformance/glsl/implicit/function_int_float.vert.html": 0.1181,
+    "conformance/glsl/implicit/function_ivec2_vec2.vert.html": 0.1125,
+    "conformance/glsl/implicit/function_ivec3_vec3.vert.html": 0.1132,
+    "conformance/glsl/implicit/function_ivec4_vec4.vert.html": 0.1167,
+    "conformance/glsl/implicit/greater_than.vert.html": 0.1134,
+    "conformance/glsl/implicit/greater_than_equal.vert.html": 0.0795,
+    "conformance/glsl/implicit/less_than.vert.html": 0.1086,
+    "conformance/glsl/implicit/less_than_equal.vert.html": 0.1131,
+    "conformance/glsl/implicit/multiply_int_float.vert.html": 0.1102,
+    "conformance/glsl/implicit/multiply_int_mat2.vert.html": 0.1105,
+    "conformance/glsl/implicit/multiply_int_mat3.vert.html": 0.1177,
+    "conformance/glsl/implicit/multiply_int_mat4.vert.html": 0.1313,
+    "conformance/glsl/implicit/multiply_int_vec2.vert.html": 0.1243,
+    "conformance/glsl/implicit/multiply_int_vec3.vert.html": 0.0786,
+    "conformance/glsl/implicit/multiply_int_vec4.vert.html": 0.1141,
+    "conformance/glsl/implicit/multiply_ivec2_vec2.vert.html": 0.0935,
+    "conformance/glsl/implicit/multiply_ivec3_vec3.vert.html": 0.0933,
+    "conformance/glsl/implicit/multiply_ivec4_vec4.vert.html": 0.0962,
+    "conformance/glsl/implicit/not_equal_int_float.vert.html": 0.1053,
+    "conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html": 0.0911,
+    "conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html": 0.1171,
+    "conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html": 0.099,
+    "conformance/glsl/implicit/subtract_int_float.vert.html": 0.101,
+    "conformance/glsl/implicit/subtract_int_mat2.vert.html": 0.0807,
+    "conformance/glsl/implicit/subtract_int_mat3.vert.html": 0.0908,
+    "conformance/glsl/implicit/subtract_int_mat4.vert.html": 0.0966,
+    "conformance/glsl/implicit/subtract_int_vec2.vert.html": 0.0989,
+    "conformance/glsl/implicit/subtract_int_vec3.vert.html": 0.1002,
+    "conformance/glsl/implicit/subtract_int_vec4.vert.html": 0.0966,
+    "conformance/glsl/implicit/subtract_ivec2_vec2.vert.html": 0.0975,
+    "conformance/glsl/implicit/subtract_ivec3_vec3.vert.html": 0.0899,
+    "conformance/glsl/implicit/subtract_ivec4_vec4.vert.html": 0.0902,
+    "conformance/glsl/implicit/ternary_int_float.vert.html": 0.0771,
+    "conformance/glsl/implicit/ternary_ivec2_vec2.vert.html": 0.09,
+    "conformance/glsl/implicit/ternary_ivec3_vec3.vert.html": 0.0907,
+    "conformance/glsl/implicit/ternary_ivec4_vec4.vert.html": 0.1202,
+    "conformance/glsl/literals/float_literal.vert.html": 0.1189,
+    "conformance/glsl/literals/literal_precision.html": 0.0905,
+    "conformance/glsl/literals/overflow_leak.vert.html": 0.0981,
+    "conformance/glsl/matrices/glsl-mat3-construction.html": 0.171,
+    "conformance/glsl/matrices/glsl-mat4-to-mat3.html": 0.1514,
+    "conformance/glsl/matrices/matrix-compound-multiply.html": 0.1228,
+    "conformance/glsl/misc/attrib-location-length-limits.html": 0.119,
+    "conformance/glsl/misc/boolean_precision.html": 0.0737,
+    "conformance/glsl/misc/const-variable-initialization.html": 1.233,
+    "conformance/glsl/misc/embedded-struct-definitions-forbidden.html": 0.2487,
+    "conformance/glsl/misc/empty-declaration.html": 0.096,
+    "conformance/glsl/misc/empty_main.vert.html": 0.2902,
+    "conformance/glsl/misc/expression-list-in-declarator-initializer.html": 0.5329,
+    "conformance/glsl/misc/fragcolor-fragdata-invariant.html": 0.2746,
+    "conformance/glsl/misc/gl_position_unset.vert.html": 0.0963,
+    "conformance/glsl/misc/global-variable-init.html": 0.2986,
+    "conformance/glsl/misc/glsl-function-nodes.html": 0.4746,
+    "conformance/glsl/misc/glsl-long-variable-names.html": 0.2797,
+    "conformance/glsl/misc/glsl-vertex-branch.html": 0.2033,
+    "conformance/glsl/misc/large-loop-compile.html": 0.7511,
+    "conformance/glsl/misc/local-variable-shadowing-outer-function.html": 0.1987,
+    "conformance/glsl/misc/non-ascii-comments.vert.html": 0.2392,
+    "conformance/glsl/misc/non-ascii.vert.html": 0.2973,
+    "conformance/glsl/misc/re-compile-re-link.html": 0.3436,
+    "conformance/glsl/misc/sampler-operand.html": 0.2311,
+    "conformance/glsl/misc/sequence-operator-returns-constant.html": 0.2742,
+    "conformance/glsl/misc/shader-precision-format-obeyed.html": 0.1562,
+    "conformance/glsl/misc/shader-struct-scope.html": 0.1874,
+    "conformance/glsl/misc/shader-uniform-packing-restrictions.html": 1.8062,
+    "conformance/glsl/misc/shader-varying-packing-restrictions.html": 0.3289,
+    "conformance/glsl/misc/shader-with-256-character-define.html": 0.1372,
+    "conformance/glsl/misc/shader-with-256-character-identifier.frag.html": 0.1243,
+    "conformance/glsl/misc/shader-with-257-character-define.html": 0.2579,
+    "conformance/glsl/misc/shader-with-257-character-identifier.frag.html": 0.0864,
+    "conformance/glsl/misc/shader-with-_webgl-identifier.vert.html": 0.086,
+    "conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html": 0.2387,
+    "conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html": 0.1294,
+    "conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html": 0.2471,
+    "conformance/glsl/misc/shader-with-array-of-structs-uniform.html": 0.1488,
+    "conformance/glsl/misc/shader-with-attrib-array.vert.html": 0.1387,
+    "conformance/glsl/misc/shader-with-attrib-struct.vert.html": 0.0673,
+    "conformance/glsl/misc/shader-with-clipvertex.vert.html": 0.2418,
+    "conformance/glsl/misc/shader-with-comma-assignment.html": 0.2241,
+    "conformance/glsl/misc/shader-with-comma-conditional-assignment.html": 0.1531,
+    "conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html": 0.0844,
+    "conformance/glsl/misc/shader-with-conditional-scoping-negative.html": 0.1199,
+    "conformance/glsl/misc/shader-with-conditional-scoping.html": 0.0838,
+    "conformance/glsl/misc/shader-with-default-precision.frag.html": 0.084,
+    "conformance/glsl/misc/shader-with-default-precision.vert.html": 0.1797,
+    "conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html": 0.2279,
+    "conformance/glsl/misc/shader-with-dfdx.frag.html": 0.0725,
+    "conformance/glsl/misc/shader-with-do-loop.html": 0.2266,
+    "conformance/glsl/misc/shader-with-error-directive.html": 0.2826,
+    "conformance/glsl/misc/shader-with-explicit-int-cast.vert.html": 0.0827,
+    "conformance/glsl/misc/shader-with-float-return-value.frag.html": 0.0914,
+    "conformance/glsl/misc/shader-with-for-loop.html": 0.1484,
+    "conformance/glsl/misc/shader-with-for-scoping.html": 0.0791,
+    "conformance/glsl/misc/shader-with-frag-depth.frag.html": 0.0828,
+    "conformance/glsl/misc/shader-with-function-recursion.frag.html": 0.2266,
+    "conformance/glsl/misc/shader-with-function-scoped-struct.html": 0.1274,
+    "conformance/glsl/misc/shader-with-functional-scoping.html": 0.1607,
+    "conformance/glsl/misc/shader-with-glcolor.vert.html": 0.0784,
+    "conformance/glsl/misc/shader-with-gles-1.frag.html": 0.2326,
+    "conformance/glsl/misc/shader-with-gles-symbol.frag.html": 0.0839,
+    "conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html": 0.1475,
+    "conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html": 0.1052,
+    "conformance/glsl/misc/shader-with-hex-int-constant-macro.html": 0.0809,
+    "conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html": 0.0802,
+    "conformance/glsl/misc/shader-with-include.vert.html": 0.1058,
+    "conformance/glsl/misc/shader-with-int-return-value.frag.html": 0.2533,
+    "conformance/glsl/misc/shader-with-invalid-identifier.frag.html": 0.2626,
+    "conformance/glsl/misc/shader-with-ivec2-return-value.frag.html": 0.0876,
+    "conformance/glsl/misc/shader-with-ivec3-return-value.frag.html": 0.2621,
+    "conformance/glsl/misc/shader-with-ivec4-return-value.frag.html": 0.0838,
+    "conformance/glsl/misc/shader-with-limited-indexing.frag.html": 0.0855,
+    "conformance/glsl/misc/shader-with-long-line.html": 0.1005,
+    "conformance/glsl/misc/shader-with-non-ascii-error.frag.html": 0.2034,
+    "conformance/glsl/misc/shader-with-non-reserved-words-1-of-8.html": 2.53,
+    "conformance/glsl/misc/shader-with-non-reserved-words-2-of-8.html": 2.6368,
+    "conformance/glsl/misc/shader-with-non-reserved-words-3-of-8.html": 2.8,
+    "conformance/glsl/misc/shader-with-non-reserved-words-4-of-8.html": 2.6504,
+    "conformance/glsl/misc/shader-with-non-reserved-words-5-of-8.html": 1.3289,
+    "conformance/glsl/misc/shader-with-non-reserved-words-6-of-8.html": 1.766,
+    "conformance/glsl/misc/shader-with-non-reserved-words-7-of-8.html": 2.5428,
+    "conformance/glsl/misc/shader-with-non-reserved-words-8-of-8.html": 1.2359,
+    "conformance/glsl/misc/shader-with-precision.frag.html": 0.1895,
+    "conformance/glsl/misc/shader-with-preprocessor-whitespace.html": 0.2401,
+    "conformance/glsl/misc/shader-with-quoted-error.frag.html": 0.203,
+    "conformance/glsl/misc/shader-with-reserved-words.html": 3.0814,
+    "conformance/glsl/misc/shader-with-short-circuiting-operators.html": 0.4275,
+    "conformance/glsl/misc/shader-with-similar-uniform-array-names.html": 0.2297,
+    "conformance/glsl/misc/shader-with-too-many-uniforms.html": 0.6535,
+    "conformance/glsl/misc/shader-with-two-initializer-types.html": 0.2418,
+    "conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html": 0.2238,
+    "conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html": 0.1904,
+    "conformance/glsl/misc/shader-with-vec2-return-value.frag.html": 0.1114,
+    "conformance/glsl/misc/shader-with-vec3-return-value.frag.html": 0.2046,
+    "conformance/glsl/misc/shader-with-vec4-return-value.frag.html": 0.1144,
+    "conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html": 0.1635,
+    "conformance/glsl/misc/shader-with-version-100.frag.html": 0.1337,
+    "conformance/glsl/misc/shader-with-version-100.vert.html": 0.2926,
+    "conformance/glsl/misc/shader-with-version-120.vert.html": 0.0937,
+    "conformance/glsl/misc/shader-with-version-130.vert.html": 0.2798,
+    "conformance/glsl/misc/shader-with-webgl-identifier.vert.html": 0.0936,
+    "conformance/glsl/misc/shader-with-while-loop.html": 0.2424,
+    "conformance/glsl/misc/shader-without-precision.frag.html": 0.1732,
+    "conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html": 0.3064,
+    "conformance/glsl/misc/shaders-with-invariance.html": 0.2811,
+    "conformance/glsl/misc/shaders-with-mis-matching-uniforms.html": 0.1765,
+    "conformance/glsl/misc/shaders-with-mis-matching-varyings.html": 0.1166,
+    "conformance/glsl/misc/shaders-with-missing-varyings.html": 0.1161,
+    "conformance/glsl/misc/shaders-with-name-conflicts.html": 0.0799,
+    "conformance/glsl/misc/shaders-with-uniform-structs.html": 0.1286,
+    "conformance/glsl/misc/shaders-with-varyings.html": 0.2496,
+    "conformance/glsl/misc/shared.html": 0.0917,
+    "conformance/glsl/misc/struct-as-inout-parameter.html": 0.1212,
+    "conformance/glsl/misc/struct-as-out-parameter.html": 0.3207,
+    "conformance/glsl/misc/struct-assign.html": 0.1661,
+    "conformance/glsl/misc/struct-equals.html": 0.2594,
+    "conformance/glsl/misc/struct-mixed-array-declarators.html": 0.5018,
+    "conformance/glsl/misc/struct-nesting-exceeds-maximum.html": 0.1429,
+    "conformance/glsl/misc/struct-nesting-of-variable-names.html": 1.396,
+    "conformance/glsl/misc/struct-nesting-under-maximum.html": 0.2231,
+    "conformance/glsl/misc/struct-specifiers-in-uniforms.html": 0.1992,
+    "conformance/glsl/misc/struct-unary-operators.html": 0.2128,
+    "conformance/glsl/misc/ternary-operator-on-arrays.html": 0.0915,
+    "conformance/glsl/misc/ternary-operators-in-global-initializers.html": 0.1952,
+    "conformance/glsl/misc/ternary-operators-in-initializers.html": 0.2888,
+    "conformance/glsl/misc/uniform-location-length-limits.html": 0.2552,
+    "conformance/glsl/misc/uninitialized-local-global-variables.html": 0.1988,
+    "conformance/glsl/preprocessor/comments.html": 0.3242,
+    "conformance/glsl/preprocessor/macro-expansion-tricky.html": 0.189,
+    "conformance/glsl/reserved/_webgl_field.vert.html": 0.1952,
+    "conformance/glsl/reserved/_webgl_function.vert.html": 0.1304,
+    "conformance/glsl/reserved/_webgl_struct.vert.html": 0.2127,
+    "conformance/glsl/reserved/_webgl_variable.vert.html": 0.0657,
+    "conformance/glsl/reserved/webgl_field.vert.html": 0.2401,
+    "conformance/glsl/reserved/webgl_function.vert.html": 0.1488,
+    "conformance/glsl/reserved/webgl_struct.vert.html": 0.1285,
+    "conformance/glsl/reserved/webgl_variable.vert.html": 0.2681,
+    "conformance/glsl/samplers/glsl-function-texture2d-bias.html": 0.1365,
+    "conformance/glsl/samplers/glsl-function-texture2dlod.html": 0.1424,
+    "conformance/glsl/samplers/glsl-function-texture2dproj.html": 0.3973,
+    "conformance/glsl/samplers/glsl-function-texture2dprojlod.html": 0.6236,
+    "conformance/glsl/variables/gl-fragcoord-xy-values.html": 0.0823,
+    "conformance/glsl/variables/gl-fragcoord.html": 0.124,
+    "conformance/glsl/variables/gl-fragdata-and-fragcolor.html": 0.12,
+    "conformance/glsl/variables/gl-frontfacing.html": 0.1,
+    "conformance/glsl/variables/gl-pointcoord.html": 0.2164,
+    "conformance/glsl/variables/glsl-built-ins.html": 0.2341,
+    "conformance/limits/gl-line-width.html": 0.0922,
+    "conformance/limits/gl-max-texture-dimensions.html": 0.23,
+    "conformance/limits/gl-min-attribs.html": 0.1537,
+    "conformance/limits/gl-min-textures.html": 0.0933,
+    "conformance/limits/gl-min-uniforms.html": 0.2622,
+    "conformance/misc/bad-arguments-test.html": 0.1467,
+    "conformance/misc/boolean-argument-conversion.html": 0.1111,
+    "conformance/misc/delayed-drawing.html": 1.2227,
+    "conformance/misc/error-reporting.html": 0.2206,
+    "conformance/misc/expando-loss.html": 0.2341,
+    "conformance/misc/functions-returning-strings.html": 0.2166,
+    "conformance/misc/hint.html": 0.1504,
+    "conformance/misc/instanceof-test.html": 0.1955,
+    "conformance/misc/invalid-passed-params.html": 0.1054,
+    "conformance/misc/is-object.html": 0.1621,
+    "conformance/misc/null-object-behaviour.html": 0.323,
+    "conformance/misc/object-deletion-behaviour.html": 0.5662,
+    "conformance/misc/shader-precision-format.html": 0.2032,
+    "conformance/misc/type-conversion-test.html": 0.2409,
+    "conformance/misc/uninitialized-test.html": 0.2263,
+    "conformance/misc/webgl-specific-stencil-settings.html": 0.4479,
+    "conformance/misc/webgl-specific.html": 0.0978,
+    "conformance/more/conformance/constants.html": 0.1012,
+    "conformance/more/conformance/getContext.html": 0.0767,
+    "conformance/more/conformance/methods.html": 0.1094,
+    "conformance/more/conformance/quickCheckAPI-A.html": 0.2504,
+    "conformance/more/conformance/quickCheckAPI-B1.html": 0.1468,
+    "conformance/more/conformance/quickCheckAPI-B2.html": 0.1277,
+    "conformance/more/conformance/quickCheckAPI-B3.html": 0.195,
+    "conformance/more/conformance/quickCheckAPI-B4.html": 0.2546,
+    "conformance/more/conformance/quickCheckAPI-C.html": 0.1174,
+    "conformance/more/conformance/quickCheckAPI-D_G.html": 0.1168,
+    "conformance/more/conformance/quickCheckAPI-G_I.html": 0.1703,
+    "conformance/more/conformance/quickCheckAPI-L_S.html": 0.1263,
+    "conformance/more/conformance/quickCheckAPI-S_V.html": 0.1261,
+    "conformance/more/conformance/webGLArrays.html": 0.1236,
+    "conformance/more/functions/bindBuffer.html": 0.104,
+    "conformance/more/functions/bindBufferBadArgs.html": 0.1337,
+    "conformance/more/functions/bindFramebufferLeaveNonZero.html": 0.108,
+    "conformance/more/functions/bufferData.html": 0.1567,
+    "conformance/more/functions/bufferDataBadArgs.html": 0.1055,
+    "conformance/more/functions/bufferSubData.html": 0.2741,
+    "conformance/more/functions/bufferSubDataBadArgs.html": 0.1166,
+    "conformance/more/functions/copyTexImage2D.html": 0.1406,
+    "conformance/more/functions/copyTexImage2DBadArgs.html": 0.1006,
+    "conformance/more/functions/copyTexSubImage2D.html": 0.1454,
+    "conformance/more/functions/copyTexSubImage2DBadArgs.html": 0.1203,
+    "conformance/more/functions/deleteBufferBadArgs.html": 0.2024,
+    "conformance/more/functions/drawArrays.html": 0.1311,
+    "conformance/more/functions/drawElements.html": 0.1389,
+    "conformance/more/functions/isTests.html": 0.1012,
+    "conformance/more/functions/isTestsBadArgs.html": 0.0983,
+    "conformance/more/functions/readPixels.html": 0.1102,
+    "conformance/more/functions/readPixelsBadArgs.html": 0.525,
+    "conformance/more/functions/texImage2D.html": 0.2485,
+    "conformance/more/functions/texImage2DBadArgs.html": 0.2546,
+    "conformance/more/functions/texImage2DHTML.html": 0.203,
+    "conformance/more/functions/texImage2DHTMLBadArgs.html": 0.0931,
+    "conformance/more/functions/texSubImage2D.html": 0.1157,
+    "conformance/more/functions/texSubImage2DBadArgs.html": 0.1063,
+    "conformance/more/functions/texSubImage2DHTML.html": 0.2406,
+    "conformance/more/functions/texSubImage2DHTMLBadArgs.html": 0.0924,
+    "conformance/more/functions/uniformMatrix.html": 0.1221,
+    "conformance/more/functions/uniformMatrixBadArgs.html": 0.3614,
+    "conformance/more/functions/uniformf.html": 0.258,
+    "conformance/more/functions/uniformfArrayLen1.html": 0.1232,
+    "conformance/more/functions/uniformfBadArgs.html": 0.1142,
+    "conformance/more/functions/uniformi.html": 0.2724,
+    "conformance/more/functions/uniformiBadArgs.html": 0.1271,
+    "conformance/more/functions/vertexAttrib.html": 0.1894,
+    "conformance/more/functions/vertexAttribBadArgs.html": 0.2444,
+    "conformance/more/functions/vertexAttribPointer.html": 0.3443,
+    "conformance/more/functions/vertexAttribPointerBadArgs.html": 0.0967,
+    "conformance/more/glsl/arrayOutOfBounds.html": 0.3239,
+    "conformance/more/glsl/uniformOutOfBounds.html": 0.1941,
+    "conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html": 0.7889,
+    "conformance/offscreencanvas/context-creation-worker.html": 0.3039,
+    "conformance/offscreencanvas/context-creation.html": 0.0779,
+    "conformance/offscreencanvas/context-lost-restored-worker.html": 0.1813,
+    "conformance/offscreencanvas/context-lost-restored.html": 0.3395,
+    "conformance/offscreencanvas/context-lost-worker.html": 0.3197,
+    "conformance/offscreencanvas/context-lost.html": 0.2465,
+    "conformance/offscreencanvas/methods-worker.html": 0.0878,
+    "conformance/offscreencanvas/methods.html": 0.3203,
+    "conformance/offscreencanvas/offscreencanvas-resize.html": 0.0727,
+    "conformance/offscreencanvas/offscreencanvas-timer-query.html": 0.1123,
+    "conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.1415,
+    "conformance/ogles/GL/abs/abs_001_to_006.html": 0.6659,
+    "conformance/ogles/GL/acos/acos_001_to_006.html": 0.9022,
+    "conformance/ogles/GL/all/all_001_to_004.html": 0.6822,
+    "conformance/ogles/GL/any/any_001_to_004.html": 0.5216,
+    "conformance/ogles/GL/array/array_001_to_006.html": 0.4976,
+    "conformance/ogles/GL/asin/asin_001_to_006.html": 0.9452,
+    "conformance/ogles/GL/atan/atan_001_to_008.html": 0.9979,
+    "conformance/ogles/GL/atan/atan_009_to_012.html": 0.7771,
+    "conformance/ogles/GL/biConstants/biConstants_001_to_008.html": 0.7331,
+    "conformance/ogles/GL/biConstants/biConstants_009_to_016.html": 0.9132,
+    "conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html": 0.3612,
+    "conformance/ogles/GL/build/build_001_to_008.html": 0.2429,
+    "conformance/ogles/GL/build/build_009_to_016.html": 0.6728,
+    "conformance/ogles/GL/build/build_017_to_024.html": 0.6907,
+    "conformance/ogles/GL/build/build_025_to_032.html": 0.3008,
+    "conformance/ogles/GL/build/build_033_to_040.html": 0.358,
+    "conformance/ogles/GL/build/build_041_to_048.html": 0.3489,
+    "conformance/ogles/GL/build/build_049_to_056.html": 0.3899,
+    "conformance/ogles/GL/build/build_057_to_064.html": 0.2566,
+    "conformance/ogles/GL/build/build_065_to_072.html": 0.2947,
+    "conformance/ogles/GL/build/build_073_to_080.html": 0.2579,
+    "conformance/ogles/GL/build/build_081_to_088.html": 0.2223,
+    "conformance/ogles/GL/build/build_089_to_096.html": 0.1522,
+    "conformance/ogles/GL/build/build_097_to_104.html": 0.3712,
+    "conformance/ogles/GL/build/build_105_to_112.html": 0.155,
+    "conformance/ogles/GL/build/build_113_to_120.html": 0.1638,
+    "conformance/ogles/GL/build/build_121_to_128.html": 0.1658,
+    "conformance/ogles/GL/build/build_129_to_136.html": 0.1552,
+    "conformance/ogles/GL/build/build_137_to_144.html": 0.1361,
+    "conformance/ogles/GL/build/build_145_to_152.html": 0.1609,
+    "conformance/ogles/GL/build/build_153_to_160.html": 0.162,
+    "conformance/ogles/GL/build/build_161_to_168.html": 0.1587,
+    "conformance/ogles/GL/build/build_169_to_176.html": 0.2497,
+    "conformance/ogles/GL/build/build_177_to_178.html": 0.1055,
+    "conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html": 0.1138,
+    "conformance/ogles/GL/ceil/ceil_001_to_006.html": 0.6835,
+    "conformance/ogles/GL/clamp/clamp_001_to_006.html": 0.6682,
+    "conformance/ogles/GL/control_flow/control_flow_001_to_008.html": 0.6888,
+    "conformance/ogles/GL/control_flow/control_flow_009_to_010.html": 0.2724,
+    "conformance/ogles/GL/cos/cos_001_to_006.html": 0.7796,
+    "conformance/ogles/GL/cross/cross_001_to_002.html": 0.3429,
+    "conformance/ogles/GL/default/default_001_to_001.html": 0.1945,
+    "conformance/ogles/GL/degrees/degrees_001_to_006.html": 0.6062,
+    "conformance/ogles/GL/discard/discard_001_to_002.html": 0.2686,
+    "conformance/ogles/GL/distance/distance_001_to_006.html": 0.6953,
+    "conformance/ogles/GL/dot/dot_001_to_006.html": 0.716,
+    "conformance/ogles/GL/equal/equal_001_to_008.html": 0.9415,
+    "conformance/ogles/GL/equal/equal_009_to_012.html": 0.6035,
+    "conformance/ogles/GL/exp/exp_001_to_008.html": 0.9144,
+    "conformance/ogles/GL/exp/exp_009_to_012.html": 0.666,
+    "conformance/ogles/GL/exp2/exp2_001_to_008.html": 0.9709,
+    "conformance/ogles/GL/exp2/exp2_009_to_012.html": 0.7244,
+    "conformance/ogles/GL/faceforward/faceforward_001_to_006.html": 0.7897,
+    "conformance/ogles/GL/floor/floor_001_to_006.html": 0.8036,
+    "conformance/ogles/GL/fract/fract_001_to_006.html": 0.7743,
+    "conformance/ogles/GL/functions/functions_001_to_008.html": 0.797,
+    "conformance/ogles/GL/functions/functions_009_to_016.html": 0.6236,
+    "conformance/ogles/GL/functions/functions_017_to_024.html": 0.6024,
+    "conformance/ogles/GL/functions/functions_025_to_032.html": 0.6618,
+    "conformance/ogles/GL/functions/functions_033_to_040.html": 0.6277,
+    "conformance/ogles/GL/functions/functions_041_to_048.html": 0.6231,
+    "conformance/ogles/GL/functions/functions_049_to_056.html": 0.6524,
+    "conformance/ogles/GL/functions/functions_057_to_064.html": 0.6549,
+    "conformance/ogles/GL/functions/functions_065_to_072.html": 0.7586,
+    "conformance/ogles/GL/functions/functions_073_to_080.html": 0.5695,
+    "conformance/ogles/GL/functions/functions_081_to_088.html": 0.6636,
+    "conformance/ogles/GL/functions/functions_089_to_096.html": 0.6282,
+    "conformance/ogles/GL/functions/functions_097_to_104.html": 0.6189,
+    "conformance/ogles/GL/functions/functions_105_to_112.html": 0.6164,
+    "conformance/ogles/GL/functions/functions_113_to_120.html": 0.6732,
+    "conformance/ogles/GL/functions/functions_121_to_126.html": 0.5203,
+    "conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html": 0.2973,
+    "conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html": 0.2413,
+    "conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html": 0.8711,
+    "conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html": 0.8112,
+    "conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html": 0.7179,
+    "conformance/ogles/GL/length/length_001_to_006.html": 0.6617,
+    "conformance/ogles/GL/lessThan/lessThan_001_to_008.html": 0.9011,
+    "conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html": 0.8619,
+    "conformance/ogles/GL/log/log_001_to_008.html": 0.918,
+    "conformance/ogles/GL/log/log_009_to_012.html": 0.8586,
+    "conformance/ogles/GL/log2/log2_001_to_008.html": 0.8761,
+    "conformance/ogles/GL/log2/log2_009_to_012.html": 0.703,
+    "conformance/ogles/GL/mat/mat_001_to_008.html": 0.7119,
+    "conformance/ogles/GL/mat/mat_009_to_016.html": 0.6919,
+    "conformance/ogles/GL/mat/mat_017_to_024.html": 0.5982,
+    "conformance/ogles/GL/mat/mat_025_to_032.html": 0.7637,
+    "conformance/ogles/GL/mat/mat_033_to_040.html": 0.7145,
+    "conformance/ogles/GL/mat/mat_041_to_046.html": 0.5618,
+    "conformance/ogles/GL/mat3/mat3_001_to_006.html": 0.506,
+    "conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html": 0.5471,
+    "conformance/ogles/GL/max/max_001_to_006.html": 0.6888,
+    "conformance/ogles/GL/min/min_001_to_006.html": 0.6582,
+    "conformance/ogles/GL/mix/mix_001_to_006.html": 0.7354,
+    "conformance/ogles/GL/mod/mod_001_to_008.html": 0.8397,
+    "conformance/ogles/GL/normalize/normalize_001_to_006.html": 0.7854,
+    "conformance/ogles/GL/not/not_001_to_004.html": 0.5982,
+    "conformance/ogles/GL/notEqual/notEqual_001_to_008.html": 0.8446,
+    "conformance/ogles/GL/notEqual/notEqual_009_to_012.html": 0.5854,
+    "conformance/ogles/GL/operators/operators_001_to_008.html": 0.6289,
+    "conformance/ogles/GL/operators/operators_009_to_016.html": 0.6461,
+    "conformance/ogles/GL/operators/operators_017_to_024.html": 0.5489,
+    "conformance/ogles/GL/operators/operators_025_to_026.html": 0.3062,
+    "conformance/ogles/GL/pow/pow_001_to_008.html": 0.7297,
+    "conformance/ogles/GL/pow/pow_009_to_016.html": 0.9468,
+    "conformance/ogles/GL/pow/pow_017_to_024.html": 1.0422,
+    "conformance/ogles/GL/radians/radians_001_to_006.html": 0.784,
+    "conformance/ogles/GL/reflect/reflect_001_to_006.html": 0.7374,
+    "conformance/ogles/GL/refract/refract_001_to_006.html": 0.8109,
+    "conformance/ogles/GL/sign/sign_001_to_006.html": 0.7545,
+    "conformance/ogles/GL/sin/sin_001_to_006.html": 0.8209,
+    "conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html": 0.7666,
+    "conformance/ogles/GL/sqrt/sqrt_001_to_006.html": 0.6877,
+    "conformance/ogles/GL/step/step_001_to_006.html": 0.6819,
+    "conformance/ogles/GL/struct/struct_001_to_008.html": 0.819,
+    "conformance/ogles/GL/struct/struct_009_to_016.html": 0.765,
+    "conformance/ogles/GL/struct/struct_017_to_024.html": 0.7484,
+    "conformance/ogles/GL/struct/struct_025_to_032.html": 0.8742,
+    "conformance/ogles/GL/struct/struct_033_to_040.html": 0.7766,
+    "conformance/ogles/GL/struct/struct_041_to_048.html": 0.8604,
+    "conformance/ogles/GL/struct/struct_049_to_056.html": 0.7804,
+    "conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html": 0.817,
+    "conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html": 0.8278,
+    "conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html": 0.756,
+    "conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html": 0.9236,
+    "conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html": 0.8303,
+    "conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html": 0.8984,
+    "conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html": 0.8557,
+    "conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html": 0.8525,
+    "conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html": 0.9002,
+    "conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html": 0.9382,
+    "conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html": 0.813,
+    "conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html": 0.875,
+    "conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html": 0.8453,
+    "conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html": 0.814,
+    "conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html": 0.8311,
+    "conformance/ogles/GL/tan/tan_001_to_006.html": 0.777,
+    "conformance/ogles/GL/vec/vec_001_to_008.html": 0.6235,
+    "conformance/ogles/GL/vec/vec_009_to_016.html": 0.74,
+    "conformance/ogles/GL/vec/vec_017_to_018.html": 0.3154,
+    "conformance/ogles/GL/vec3/vec3_001_to_008.html": 0.6677,
+    "conformance/programs/get-active-test.html": 0.2563,
+    "conformance/programs/gl-bind-attrib-location-long-names-test.html": 0.2019,
+    "conformance/programs/gl-bind-attrib-location-test.html": 0.1508,
+    "conformance/programs/gl-get-active-attribute.html": 0.3413,
+    "conformance/programs/gl-get-active-uniform.html": 0.4894,
+    "conformance/programs/gl-getshadersource.html": 0.1906,
+    "conformance/programs/gl-shader-test.html": 0.2566,
+    "conformance/programs/invalid-UTF-16.html": 0.0956,
+    "conformance/programs/program-handling.html": 0.2927,
+    "conformance/programs/program-infolog.html": 0.2018,
+    "conformance/programs/program-test.html": 0.241,
+    "conformance/programs/use-program-crash-with-discard-in-fragment-shader.html": 0.2512,
+    "conformance/reading/fbo-remains-unchanged-after-read-pixels.html": 0.2391,
+    "conformance/reading/read-pixels-pack-alignment.html": 0.6175,
+    "conformance/reading/read-pixels-test.html": 0.4016,
+    "conformance/renderbuffers/depth-renderbuffer-initialization.html": 0.1376,
+    "conformance/renderbuffers/feedback-loop.html": 0.271,
+    "conformance/renderbuffers/framebuffer-object-attachment.html": 0.5082,
+    "conformance/renderbuffers/framebuffer-state-restoration.html": 0.3643,
+    "conformance/renderbuffers/framebuffer-test.html": 0.1419,
+    "conformance/renderbuffers/renderbuffer-initialization.html": 0.2367,
+    "conformance/renderbuffers/stencil-renderbuffer-initialization.html": 0.1427,
+    "conformance/rendering/bind-framebuffer-flush-bug.html": 0.1064,
+    "conformance/rendering/blending.html": 0.3498,
+    "conformance/rendering/canvas-alpha-bug.html": 0.0833,
+    "conformance/rendering/clear-after-copyTexImage2D.html": 0.1799,
+    "conformance/rendering/clear-default-framebuffer-with-scissor-test.html": 0.0703,
+    "conformance/rendering/clipping-wide-points.html": 0.1808,
+    "conformance/rendering/color-mask-preserved-during-implicit-clears.html": 1.4927,
+    "conformance/rendering/color-mask-should-not-affect-antialiased-framebuffer-resolution.html": 0.0884,
+    "conformance/rendering/culling.html": 0.1048,
+    "conformance/rendering/default-texture-draw-bug.html": 0.2585,
+    "conformance/rendering/draw-arrays-out-of-bounds.html": 0.1442,
+    "conformance/rendering/draw-elements-out-of-bounds.html": 0.1275,
+    "conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html": 0.0782,
+    "conformance/rendering/draw-with-changing-start-vertex-bug.html": 0.2522,
+    "conformance/rendering/framebuffer-switch.html": 0.1474,
+    "conformance/rendering/framebuffer-texture-clear.html": 0.2655,
+    "conformance/rendering/framebuffer-texture-switch.html": 0.0972,
+    "conformance/rendering/gl-clear.html": 0.2071,
+    "conformance/rendering/gl-drawarrays.html": 0.2761,
+    "conformance/rendering/gl-drawelements.html": 0.2101,
+    "conformance/rendering/gl-scissor-canvas-dimensions.html": 0.1061,
+    "conformance/rendering/gl-scissor-fbo-test.html": 0.3053,
+    "conformance/rendering/gl-scissor-test.html": 0.1336,
+    "conformance/rendering/gl-viewport-test.html": 0.2591,
+    "conformance/rendering/line-loop-tri-fan.html": 0.0967,
+    "conformance/rendering/line-rendering-quality.html": 0.1238,
+    "conformance/rendering/many-draw-calls.html": 1.79,
+    "conformance/rendering/more-than-65536-indices.html": 0.1479,
+    "conformance/rendering/multisample-corruption.html": 3.1151,
+    "conformance/rendering/negative-one-index.html": 0.0939,
+    "conformance/rendering/out-of-bounds-array-buffers.html": 0.2009,
+    "conformance/rendering/out-of-bounds-index-buffers.html": 0.3005,
+    "conformance/rendering/point-no-attributes.html": 0.2902,
+    "conformance/rendering/point-size.html": 0.1035,
+    "conformance/rendering/point-specific-shader-variables.html": 0.1123,
+    "conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html": 0.1297,
+    "conformance/rendering/polygon-offset.html": 0.2163,
+    "conformance/rendering/preservedrawingbuffer-leak.html": 0.3926,
+    "conformance/rendering/rendering-sampling-feedback-loop.html": 0.1849,
+    "conformance/rendering/rendering-stencil-large-viewport.html": 0.1604,
+    "conformance/rendering/scissor-rect-repeated-rendering.html": 0.3855,
+    "conformance/rendering/simple.html": 0.2125,
+    "conformance/rendering/texture-switch-performance.html": 0,
+    "conformance/rendering/triangle.html": 0.2871,
+    "conformance/state/fb-attach-implicit-target-assignment.html": 0.272,
+    "conformance/state/gl-enable-enum-test.html": 0.1731,
+    "conformance/state/gl-enum-tests.html": 0.2265,
+    "conformance/state/gl-get-calls.html": 0.2561,
+    "conformance/state/gl-geterror.html": 0.2744,
+    "conformance/state/gl-getstring.html": 0.0763,
+    "conformance/state/gl-initial-state.html": 0.301,
+    "conformance/state/gl-object-get-calls.html": 7.4816,
+    "conformance/state/state-uneffected-after-compositing.html": 0.2276,
+    "conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.8325,
+    "conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.9644,
+    "conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.9122,
+    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html": 3.6312,
+    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.9485,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html": 2.7615,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.9962,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.1548,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html": 0.0694,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html": 0.0555,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.0472,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html": 0.0494,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.0498,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html": 0.0457,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.0399,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.0523,
+    "conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html": 0.1766,
+    "conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html": 0.3838,
+    "conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.2282,
+    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3783,
+    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3371,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html": 0.4405,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1726,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3592,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html": 0.1875,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html": 0.3356,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.2468,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html": 0.3672,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3828,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html": 0.1983,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.267,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.2168,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.6416,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.5672,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3259,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 0.4804,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.6271,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 0.5779,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3108,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.2833,
+    "conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.266,
+    "conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.2237,
+    "conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.1798,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.1671,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1717,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.1898,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1711,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.2257,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html": 0.1827,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html": 0.1921,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.181,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html": 0.1659,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1735,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html": 0.1745,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1659,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.145,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.1564,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.1528,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.186,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.1577,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1605,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.1759,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1749,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.1632,
+    "conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html": 0.6722,
+    "conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html": 0.5029,
+    "conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5651,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html": 0.5956,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.6388,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html": 0.7239,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5685,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.6533,
+    "conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.2208,
+    "conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.1746,
+    "conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.1312,
+    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.2196,
+    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3846,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.1591,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3392,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.1352,
+    "conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html": 0.1178,
+    "conformance/textures/misc/compressed-tex-image.html": 0.1073,
+    "conformance/textures/misc/copy-tex-image-2d-formats.html": 0.3861,
+    "conformance/textures/misc/copy-tex-image-and-sub-image-2d.html": 0.3809,
+    "conformance/textures/misc/copy-tex-image-crash.html": 0.0833,
+    "conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html": 0.3447,
+    "conformance/textures/misc/copytexsubimage2d-subrects.html": 0.1016,
+    "conformance/textures/misc/cube-incomplete-fbo.html": 0.1018,
+    "conformance/textures/misc/cube-map-uploads-out-of-order.html": 1.0804,
+    "conformance/textures/misc/default-texture.html": 0.0782,
+    "conformance/textures/misc/exif-orientation.html": 0.4186,
+    "conformance/textures/misc/format-filterable-renderable.html": 0.1431,
+    "conformance/textures/misc/gl-get-tex-parameter.html": 0.1402,
+    "conformance/textures/misc/gl-pixelstorei.html": 0.0972,
+    "conformance/textures/misc/gl-teximage.html": 0.2075,
+    "conformance/textures/misc/mipmap-fbo.html": 0.1199,
+    "conformance/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.0947,
+    "conformance/textures/misc/origin-clean-conformance.html": 0.0902,
+    "conformance/textures/misc/png-image-types.html": 0.5828,
+    "conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html": 0.6517,
+    "conformance/textures/misc/tex-image-and-uniform-binding-bugs.html": 0.0953,
+    "conformance/textures/misc/tex-image-canvas-corruption.html": 0.0924,
+    "conformance/textures/misc/tex-image-webgl.html": 0.1109,
+    "conformance/textures/misc/tex-image-with-format-and-type.html": 0.2793,
+    "conformance/textures/misc/tex-image-with-invalid-data.html": 0.0713,
+    "conformance/textures/misc/tex-input-validation.html": 0.1957,
+    "conformance/textures/misc/tex-sub-image-2d-bad-args.html": 0.2433,
+    "conformance/textures/misc/tex-sub-image-2d.html": 0.078,
+    "conformance/textures/misc/tex-video-using-tex-unit-non-zero.html": 0.4942,
+    "conformance/textures/misc/texparameter-test.html": 0.0815,
+    "conformance/textures/misc/texture-active-bind-2.html": 0.1244,
+    "conformance/textures/misc/texture-active-bind.html": 0.1021,
+    "conformance/textures/misc/texture-attachment-formats.html": 0.0999,
+    "conformance/textures/misc/texture-clear.html": 0.0862,
+    "conformance/textures/misc/texture-complete.html": 0.0911,
+    "conformance/textures/misc/texture-copying-and-deletion.html": 1.2972,
+    "conformance/textures/misc/texture-copying-feedback-loops.html": 0.0755,
+    "conformance/textures/misc/texture-corner-case-videos.html": 0.3273,
+    "conformance/textures/misc/texture-cube-as-fbo-attachment.html": 0.2313,
+    "conformance/textures/misc/texture-draw-with-2d-and-cube.html": 0.2848,
+    "conformance/textures/misc/texture-fakeblack.html": 0.0786,
+    "conformance/textures/misc/texture-formats-test.html": 0.1167,
+    "conformance/textures/misc/texture-hd-dpi.html": 0.1598,
+    "conformance/textures/misc/texture-mips.html": 0.0898,
+    "conformance/textures/misc/texture-npot-video.html": 0.2717,
+    "conformance/textures/misc/texture-npot.html": 0.1254,
+    "conformance/textures/misc/texture-size-cube-maps.html": 0.4799,
+    "conformance/textures/misc/texture-size-limit.html": 0.1881,
+    "conformance/textures/misc/texture-size.html": 0.6127,
+    "conformance/textures/misc/texture-sub-image-cube-maps.html": 0.1649,
+    "conformance/textures/misc/texture-transparent-pixels-initialized.html": 0.1018,
+    "conformance/textures/misc/texture-upload-cube-maps.html": 0.2536,
+    "conformance/textures/misc/texture-upload-size.html": 0.6123,
+    "conformance/textures/misc/texture-video-transparent.html": 2.434,
+    "conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html": 0.107,
+    "conformance/textures/misc/upload-from-srcset-with-empty-data.html": 0.0909,
+    "conformance/textures/misc/video-rotation.html": 0.662,
+    "conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.1287,
+    "conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.1082,
+    "conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.265,
+    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3066,
+    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1452,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.1229,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1524,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.1288,
+    "conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html": 0.9548,
+    "conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html": 0.9055,
+    "conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.9399,
+    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html": 0.9383,
+    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.9252,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html": 0.9837,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.9264,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.9329,
+    "conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.4319,
+    "conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.3764,
+    "conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.226,
+    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 3.7699,
+    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.1117,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 3.3296,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.2728,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.1458,
+    "conformance/typedarrays/array-buffer-crash.html": 0.0532,
+    "conformance/typedarrays/array-buffer-view-crash.html": 0.0712,
+    "conformance/typedarrays/array-large-array-tests.html": 0.2066,
+    "conformance/typedarrays/array-unit-tests.html": 0.0799,
+    "conformance/typedarrays/data-view-crash.html": 0.0507,
+    "conformance/typedarrays/data-view-test.html": 0.089,
+    "conformance/typedarrays/typed-arrays-in-workers.html": 0.0832,
+    "conformance/uniforms/gl-uniform-arrays.html": 0.1195,
+    "conformance/uniforms/gl-uniform-bool.html": 0.0776,
+    "conformance/uniforms/gl-uniformmatrix4fv.html": 0.0842,
+    "conformance/uniforms/gl-unknown-uniform.html": 0.087,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-00.html": 0.821,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-01.html": 0.6472,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-02.html": 0.689,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-03.html": 0.656,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-04.html": 0.7808,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-05.html": 0.8638,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-06.html": 0.7185,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-07.html": 0.7783,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-08.html": 0.8244,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-09.html": 0.776,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-10.html": 0.7582,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-11.html": 0.8998,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-12.html": 0.871,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-13.html": 0.8245,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-14.html": 0.8114,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-15.html": 0.8175,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-16.html": 0.8261,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-17.html": 0.7084,
+    "conformance/uniforms/null-uniform-location.html": 0.216,
+    "conformance/uniforms/out-of-bounds-uniform-array-access.html": 2.6503,
+    "conformance/uniforms/uniform-default-values.html": 1.516,
+    "conformance/uniforms/uniform-location.html": 0.3192,
+    "conformance/uniforms/uniform-samplers-test.html": 14.898,
+    "conformance/uniforms/uniform-values-per-program.html": 0.9279,
+    "deqp/data/gles2/shaders/conditionals.html": 1.105,
+    "deqp/data/gles2/shaders/constant_expressions.html": 1.1211,
+    "deqp/data/gles2/shaders/constants.html": 2.3428,
+    "deqp/data/gles2/shaders/conversions_matrix_combine.html": 3.1253,
+    "deqp/data/gles2/shaders/conversions_matrix_to_matrix.html": 1.0784,
+    "deqp/data/gles2/shaders/conversions_scalar_to_matrix.html": 0.9288,
+    "deqp/data/gles2/shaders/conversions_scalar_to_scalar.html": 1.2559,
+    "deqp/data/gles2/shaders/conversions_scalar_to_vector.html": 2.6247,
+    "deqp/data/gles2/shaders/conversions_vector_combine.html": 8.1514,
+    "deqp/data/gles2/shaders/conversions_vector_illegal.html": 0.6708,
+    "deqp/data/gles2/shaders/conversions_vector_to_scalar.html": 2.1617,
+    "deqp/data/gles2/shaders/conversions_vector_to_vector.html": 4.0969,
+    "deqp/data/gles2/shaders/declarations.html": 0.2618,
+    "deqp/data/gles2/shaders/fragdata.html": 0.2356,
+    "deqp/data/gles2/shaders/functions.html": 8.8986,
+    "deqp/data/gles2/shaders/invalid_texture_functions.html": 0.2698,
+    "deqp/data/gles2/shaders/keywords.html": 1.3769,
+    "deqp/data/gles2/shaders/linkage.html": 1.7085,
+    "deqp/data/gles2/shaders/preprocessor.html": 8.757,
+    "deqp/data/gles2/shaders/qualification_order.html": 0.5748,
+    "deqp/data/gles2/shaders/reserved_operators.html": 0.2426,
+    "deqp/data/gles2/shaders/scoping.html": 1.4182,
+    "deqp/data/gles2/shaders/swizzles_bvec2.html": 2.328,
+    "deqp/data/gles2/shaders/swizzles_bvec3.html": 4.9747,
+    "deqp/data/gles2/shaders/swizzles_bvec4.html": 4.4961,
+    "deqp/data/gles2/shaders/swizzles_ivec2.html": 2.1123,
+    "deqp/data/gles2/shaders/swizzles_ivec3.html": 3.8385,
+    "deqp/data/gles2/shaders/swizzles_ivec4.html": 4.3778,
+    "deqp/data/gles2/shaders/swizzles_vec2.html": 2.1098,
+    "deqp/data/gles2/shaders/swizzles_vec3.html": 3.5723,
+    "deqp/data/gles2/shaders/swizzles_vec4.html": 5.1955
   }
 }
\ No newline at end of file
diff --git a/content/test/data/interest_group/auction_only_both_new_and_old_names.har b/content/test/data/interest_group/auction_only_both_new_and_old_names.har
new file mode 100644
index 0000000..4eaab11
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_both_new_and_old_names.har
@@ -0,0 +1,42 @@
+{
+  "log": {
+    "entries": [
+      {
+        "request": {
+          "method": "GET",
+          "url": "/interest_group/auction_only_in_bundle.json",
+          "headers": []
+        },
+        "response": {
+          "status": 200,
+          "headers": [
+            {
+              "name": "Content-type",
+              "value": "application/json"
+            },
+            {
+              "name": "X-Allow-FLEDGE",
+              "value": "true"
+            },
+            {
+              "name": "Ad-Auction-Only",
+              "value": "true"
+            },
+            {
+              "name": "X-FLEDGE-Auction-Only",
+              "value": "true"
+            },
+            {
+              "name": "Access-Control-Allow-Origin",
+              "value": "*"
+            }
+          ],
+          "content": {
+            "text": "{ secret: 2 }"
+          }
+        }
+      }
+    ]
+  }
+}
+
diff --git a/content/test/data/interest_group/auction_only_both_new_and_old_names.html b/content/test/data/interest_group/auction_only_both_new_and_old_names.html
new file mode 100644
index 0000000..b05dd91
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_both_new_and_old_names.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Page with subresource bundle auction-only signals</title>
+<script type="webbundle">
+{
+  "source": "auction_only_both_new_and_old_names.wbn",
+  "resources": ["/interest_group/auction_only_in_bundle.json"]
+}
+</script>
+
diff --git a/content/test/data/interest_group/auction_only_both_new_and_old_names.json b/content/test/data/interest_group/auction_only_both_new_and_old_names.json
new file mode 100644
index 0000000..da3a68b
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_both_new_and_old_names.json
@@ -0,0 +1,2 @@
+{ "secret": 1 }
+
diff --git a/content/test/data/interest_group/auction_only_both_new_and_old_names.json.mock-http-headers b/content/test/data/interest_group/auction_only_both_new_and_old_names.json.mock-http-headers
new file mode 100644
index 0000000..7f48de7
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_both_new_and_old_names.json.mock-http-headers
@@ -0,0 +1,6 @@
+HTTP/1.1 200 OK
+Content-Type: Application/JSON
+X-Allow-FLEDGE: true
+Ad-Auction-Only: true
+X-FLEDGE-Auction-Only: true
+
diff --git a/content/test/data/interest_group/auction_only_both_new_and_old_names.wbn b/content/test/data/interest_group/auction_only_both_new_and_old_names.wbn
new file mode 100644
index 0000000..0fee95cb
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_both_new_and_old_names.wbn
Binary files differ
diff --git a/content/test/data/interest_group/auction_only_both_new_and_old_names.wbn.mock-http-headers b/content/test/data/interest_group/auction_only_both_new_and_old_names.wbn.mock-http-headers
new file mode 100644
index 0000000..3d05e91
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_both_new_and_old_names.wbn.mock-http-headers
@@ -0,0 +1,5 @@
+HTTP/1.1 200 OK
+Content-Type: application/webbundle
+X-Content-Type-Options: nosniff
+Access-Control-Allow-Origin: *
+
diff --git a/content/test/data/interest_group/auction_only_new_name.har b/content/test/data/interest_group/auction_only_new_name.har
new file mode 100644
index 0000000..2a032d0
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_new_name.har
@@ -0,0 +1,37 @@
+{
+  "log": {
+    "entries": [
+      {
+        "request": {
+          "method": "GET",
+          "url": "/interest_group/auction_only_in_bundle.json",
+          "headers": []
+        },
+        "response": {
+          "status": 200,
+          "headers": [
+            {
+              "name": "Content-type",
+              "value": "application/json"
+            },
+            {
+              "name": "X-Allow-FLEDGE",
+              "value": "true"
+            },
+            {
+              "name": "Ad-Auction-Only",
+              "value": "true"
+            },
+            {
+              "name": "Access-Control-Allow-Origin",
+              "value": "*"
+            }
+          ],
+          "content": {
+            "text": "{ secret: 2 }"
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/content/test/data/interest_group/auction_only_new_name.html b/content/test/data/interest_group/auction_only_new_name.html
new file mode 100644
index 0000000..9edde9a
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_new_name.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Page with subresource bundle auction-only signals</title>
+<script type="webbundle">
+{
+  "source": "auction_only_new_name.wbn",
+  "resources": ["/interest_group/auction_only_in_bundle.json"]
+}
+</script>
+
diff --git a/content/test/data/interest_group/auction_only_new_name.json b/content/test/data/interest_group/auction_only_new_name.json
new file mode 100644
index 0000000..da3a68b
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_new_name.json
@@ -0,0 +1,2 @@
+{ "secret": 1 }
+
diff --git a/content/test/data/interest_group/auction_only_new_name.json.mock-http-headers b/content/test/data/interest_group/auction_only_new_name.json.mock-http-headers
new file mode 100644
index 0000000..23a61cc5
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_new_name.json.mock-http-headers
@@ -0,0 +1,4 @@
+HTTP/1.1 200 OK
+Content-Type: Application/JSON
+X-Allow-FLEDGE: true
+Ad-Auction-Only: true
diff --git a/content/test/data/interest_group/auction_only_new_name.wbn b/content/test/data/interest_group/auction_only_new_name.wbn
new file mode 100644
index 0000000..01f7141c
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_new_name.wbn
Binary files differ
diff --git a/content/test/data/interest_group/auction_only_new_name.wbn.mock-http-headers b/content/test/data/interest_group/auction_only_new_name.wbn.mock-http-headers
new file mode 100644
index 0000000..3d05e91
--- /dev/null
+++ b/content/test/data/interest_group/auction_only_new_name.wbn.mock-http-headers
@@ -0,0 +1,5 @@
+HTTP/1.1 200 OK
+Content-Type: application/webbundle
+X-Content-Type-Options: nosniff
+Access-Control-Allow-Origin: *
+
diff --git a/content/test/data/interest_group/generate-test-wbns.sh b/content/test/data/interest_group/generate-test-wbns.sh
index baba362..5ddeebfe 100755
--- a/content/test/data/interest_group/generate-test-wbns.sh
+++ b/content/test/data/interest_group/generate-test-wbns.sh
@@ -14,3 +14,7 @@
 fi
 
 gen-bundle -version b2 -har auction_only.har -o auction_only.wbn
+gen-bundle -version b2 -har auction_only_new_name.har \
+  -o auction_only_new_name.wbn
+gen-bundle -version b2 -har auction_only_both_new_and_old_names.har \
+  -o auction_only_both_new_and_old_names.wbn
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/styles.d41d8cd98f00b204e980.bundle.css b/content/test/data/service_worker/empty2.html
similarity index 100%
copy from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/styles.d41d8cd98f00b204e980.bundle.css
copy to content/test/data/service_worker/empty2.html
diff --git a/content/test/data/shared_dictionary/test.dict.mock-http-headers b/content/test/data/shared_dictionary/test.dict.mock-http-headers
index d8e30085..d07d0cb 100644
--- a/content/test/data/shared_dictionary/test.dict.mock-http-headers
+++ b/content/test/data/shared_dictionary/test.dict.mock-http-headers
@@ -1,2 +1,3 @@
 HTTP/1.1 200 OK
 Use-As-Dictionary: match="/shared_dictionary/path/*"
+Access-Control-Allow-Origin: *
diff --git a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
index 511cb3ce..ad52f14 100644
--- a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
@@ -177,7 +177,7 @@
 
 crbug.com/1419583 [ linux amd-0x7340 angle-vulkan ] ContextLost_WebGLContextRestoredInHiddenTab [ Failure ]
 
-crbug.com/1419558 [ fuchsia ] ContextLost_WebGLContextLostFromQuantity [ Failure ]
+crbug.com/1419558 [ angle-swiftshader clang-coverage fuchsia fuchsia-board-qemu-x64 google-0xc0de ] ContextLost_WebGLContextLostFromQuantity [ Failure ]
 
 #######################################################################
 # Automated Entries After This Point - Do Not Manually Add Below Here #
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index a5fe994..bc21d9f1 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -254,14 +254,12 @@
 crbug.com/1446435 [ chromeos lacros-chrome passthrough ] conformance2/textures/image_bitmap_from_blob/* [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome passthrough ] conformance2/textures/image_bitmap_from_image_bitmap/* [ Skip ]
 
-# Failures on Lacros, skip as failures causes re-login which takes ~1 min
+# Extensions not available on Lacros, skip as failures causes re-login which takes ~1 min
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-octopus passthrough ] WebglExtension_OVR_multiview2 [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-octopus passthrough ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-octopus passthrough ] WebglExtension_WEBGL_provoking_vertex [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-octopus passthrough ] WebglExtension_WEBGL_webcodecs_video_frame [ Skip ]
 
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-octopus passthrough ] conformance/extensions/webgl-compressed-texture-astc.html [ Skip ]
-
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_texture_compression_bptc [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_texture_compression_rgtc [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_texture_norm16 [ Skip ]
@@ -274,25 +272,6 @@
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_WEBGL_provoking_vertex [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_WEBGL_webcodecs_video_frame [ Skip ]
 
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/glsl/bugs/constant-precision-qualifier.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/limits/gl-max-texture-dimensions.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/misc/shader-precision-format.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/renderbuffers/stencil-renderbuffer-initialization.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/buffers/uniform-buffers.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/array-as-return-value.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/matrix-row-major.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/tricky-loop-conditions.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/uninitialized-local-global-variables.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/misc/expando-loss-2.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/misc/uninitialized-test-2.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/programs/active-built-in-attribs.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/query/query.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/reading/read-pixels-pack-parameters.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/rendering/blitframebuffer-multisampled-readbuffer.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/textures/misc/immutable-tex-render-feedback.html [ Skip ]
-crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/transform_feedback/transform_feedback.html [ Skip ]
-
 ###############################
 # Permanent Slow Expectations #
 ###############################
@@ -840,6 +819,31 @@
 # Failures on validating command decoder only; won't fix.
 crbug.com/angleproject/5038 [ chromeos chromeos-board-amd64-generic mesa_ge_21.0 no-passthrough target-cpu-64 ] conformance/extensions/ext-color-buffer-half-float.html [ Failure ]
 
+#####################
+# Lacros failures #
+#####################
+
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-octopus passthrough ] conformance2/textures/misc/immutable-tex-render-feedback.html [ Failure ]
+
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/glsl/bugs/constant-precision-qualifier.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/misc/shader-precision-format.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/renderbuffers/stencil-renderbuffer-initialization.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/buffers/uniform-buffers.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/array-as-return-value.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/matrix-row-major.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/tricky-loop-conditions.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/uninitialized-local-global-variables.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/misc/expando-loss-2.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/misc/uninitialized-test-2.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/programs/active-built-in-attribs.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/query/query.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/reading/read-pixels-pack-parameters.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/rendering/blitframebuffer-multisampled-readbuffer.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/textures/misc/immutable-tex-render-feedback.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/transform_feedback/transform_feedback.html [ Failure ]
+
 ##############################
 # Lacros-like Linux Failures #
 ##############################
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index a31cd81..170de4e 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -345,8 +345,16 @@
 crbug.com/1446435 [ chromeos lacros-chrome passthrough ] conformance/more/* [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome passthrough ] deqp/* [ Skip ]
 
-# Failures on Lacros, skip as failures causes re-login which takes ~1 min
+# Extensions not available on Lacros, skip as failures causes re-login which takes ~1 min
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-octopus passthrough ] WebglExtension_WEBGL_webcodecs_video_frame [ Skip ]
+
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_frag_depth [ Skip ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_texture_compression_bptc [ Skip ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_texture_compression_rgtc [ Skip ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_OES_texture_float_linear [ Skip ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_WEBGL_compressed_texture_s3tc [ Skip ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_WEBGL_draw_buffers [ Skip ]
 crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_WEBGL_webcodecs_video_frame [ Skip ]
 
 ###############################
@@ -675,6 +683,15 @@
 crbug.com/1357064 [ chromeos chromeos-board-amd64-generic no-passthrough ] conformance/rendering/blending.html [ Failure ]
 crbug.com/1429948 [ angle-disabled chromeos chromeos-board-amd64-generic no-passthrough ] conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html [ Failure ]
 
+#####################
+# Lacros failures #
+#####################
+
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi arm angle-opengles passthrough ] conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/glsl/bugs/constant-precision-qualifier.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
+crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance/misc/shader-precision-format.html [ Failure ]
+
 ###########################
 # Lacros/Wayland failures #
 ###########################
diff --git a/content/test/gpu/gpu_tests/webgpu_cts_integration_test.py b/content/test/gpu/gpu_tests/webgpu_cts_integration_test.py
index d316a82..0c213bd7e 100644
--- a/content/test/gpu/gpu_tests/webgpu_cts_integration_test.py
+++ b/content/test/gpu/gpu_tests/webgpu_cts_integration_test.py
@@ -77,6 +77,7 @@
   _use_webgpu_adapter = None  # use the default
   _original_environ = None
   _use_webgpu_power_preference = None
+  _os_name = None
 
   _build_dir = None
 
@@ -94,12 +95,6 @@
     self._query = None
     self._run_in_worker = False
 
-    if WebGpuCtsIntegrationTest._slow_tests is None:
-      with open(SLOW_TESTS_FILE, 'r') as f:
-        expectations = expectations_parser.TestExpectations()
-        expectations.parse_tagged_list(f.read(), f.name)
-        WebGpuCtsIntegrationTest._slow_tests = expectations
-
   # Only perform the pre/post test cleanup every X tests instead of every test
   # to reduce overhead.
   def ShouldPerformMinidumpCleanupOnSetUp(self) -> bool:
@@ -198,6 +193,15 @@
     return set()
 
   @classmethod
+  def _GetSlowTests(cls):
+    if WebGpuCtsIntegrationTest._slow_tests is None:
+      with open(SLOW_TESTS_FILE, 'r') as f:
+        expectations = expectations_parser.TestExpectations()
+        expectations.parse_tagged_list(f.read(), f.name)
+        WebGpuCtsIntegrationTest._slow_tests = expectations
+    return WebGpuCtsIntegrationTest._slow_tests
+
+  @classmethod
   def AddCommandlineArgs(cls, parser: ct.CmdArgParser) -> None:
     super(WebGpuCtsIntegrationTest, cls).AddCommandlineArgs(parser)
     parser.add_option('--override-timeout',
@@ -223,6 +227,11 @@
   def StartBrowser(cls) -> None:
     cls._page_loaded = False
     super(WebGpuCtsIntegrationTest, cls).StartBrowser()
+    cls._os_name = cls.browser.platform.GetOSName()
+    # Set up the slow tests expectations' tags to match the test runner
+    # expectations' tags
+    WebGpuCtsIntegrationTest._GetSlowTests().set_tags(
+        cls.child.expectations.tags)
 
   @classmethod
   def SetUpProcess(cls) -> None:
@@ -311,6 +320,13 @@
       else:
         yield (TestNameFromInputs(*test_inputs), HTML_FILENAME, test_inputs)
 
+  def GetExpectationsForTest(self):
+    if self._os_name == 'android':
+      # Temporarily expect all tests to fail
+      # TODO(crbug.com/1363409): remove this after failures suppressed
+      return (set([gpu_integration_test.ResultType.Failure]), False)
+    return super().GetExpectationsForTest()
+
   def _DetermineRetryWorkaround(self, exception: Exception) -> bool:
     # Instances of WebGpuMessageTimeoutError:
     # https://luci-analysis.appspot.com/p/chromium/rules/b9130da14f0fcab5d6ee415d209bf71b
@@ -531,7 +547,7 @@
     # We access the expectations directly instead of using
     # self.GetExpectationsForTest since we need the raw results, but that method
     # only returns the parsed results and whether the test should be retried.
-    expectation = WebGpuCtsIntegrationTest._slow_tests.expectations_for(
+    expectation = WebGpuCtsIntegrationTest._GetSlowTests().expectations_for(
         TestNameFromInputs(self._query, self._run_in_worker))
     return 'Slow' in expectation.raw_results
 
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc
index 52b03c7..60cd2cd 100644
--- a/content/test/test_web_contents.cc
+++ b/content/test/test_web_contents.cc
@@ -86,11 +86,16 @@
 
 TestWebContents::~TestWebContents() = default;
 
-TestRenderFrameHost* TestWebContents::GetPrimaryMainFrame() {
-  auto* instance = WebContentsImpl::GetPrimaryMainFrame();
+const TestRenderFrameHost* TestWebContents::GetPrimaryMainFrame() const {
+  const auto* const instance = WebContentsImpl::GetPrimaryMainFrame();
   DCHECK(instance->IsTestRenderFrameHost())
       << "You may want to instantiate RenderViewHostTestEnabler.";
-  return static_cast<TestRenderFrameHost*>(instance);
+  return static_cast<const TestRenderFrameHost*>(instance);
+}
+
+TestRenderFrameHost* TestWebContents::GetPrimaryMainFrame() {
+  return const_cast<TestRenderFrameHost*>(
+      std::as_const(*this).GetPrimaryMainFrame());
 }
 
 TestRenderViewHost* TestWebContents::GetRenderViewHost() {
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h
index 0b95b07..e6fb595 100644
--- a/content/test/test_web_contents.h
+++ b/content/test/test_web_contents.h
@@ -54,6 +54,7 @@
   static TestWebContents* Create(const CreateParams& params);
 
   // WebContentsImpl overrides (returning the same values, but in Test* types)
+  const TestRenderFrameHost* GetPrimaryMainFrame() const override;
   TestRenderFrameHost* GetPrimaryMainFrame() override;
   TestRenderViewHost* GetRenderViewHost() override;
   // Overrides to avoid establishing Mojo connection with renderer process.
diff --git a/device/bluetooth/public/mojom/BUILD.gn b/device/bluetooth/public/mojom/BUILD.gn
index 687e1f5..01de33ac 100644
--- a/device/bluetooth/public/mojom/BUILD.gn
+++ b/device/bluetooth/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@
 import("//mojo/public/tools/bindings/mojom.gni")
 
 mojom("mojom") {
+  generate_java = true
   sources = [ "uuid.mojom" ]
   webui_module_path = "/"
 
diff --git a/docs/configuration.md b/docs/configuration.md
index 151d15b..d21f5bda 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -142,7 +142,7 @@
 | :-                                           | :-          | :-             | :--:     | :--:                                | :-                                |
 | Directly surfaced to the user                | ❌          | ❌            | ❌       | ✅                                  | ✅                                |
 | Localized into the user's language           | ❌          | ❌            | ❌       | ❌                                  | ✅                                |
-| Configurable via enterprise policy           | ✅          | ❌            | ✅       | ✅                                  | ❌ but their backing prefs may be |
+| Configurable via enterprise policy           | ✅          | ❌            | ❌ except on ChromeOS | ✅                                  | ❌ but their backing prefs may be |
 | Reported when in use                         | ❌          | via UMA/crash |  ❌      | via UMA<br> `Launch.FlagsAtStartup` | ❌                                |
 | Included in chrome://version                 | ❌          | ✅            | ✅       | ❌                                  | ❌                                |
 | Automatically persistent<br> across restarts | ✅ usually  | ❌            | ❌       | ✅                                  | ✅ via backing prefs              |
diff --git a/docs/webui_build_configuration.md b/docs/webui_build_configuration.md
index 823ac556..7602c411 100644
--- a/docs/webui_build_configuration.md
+++ b/docs/webui_build_configuration.md
@@ -317,9 +317,8 @@
 ### **minify_js**
 ```
 This rule is used to minify Javascript files to reduce build size.
-Also generates a manifest file to |target_gen_dir| named
-minify_js_manifest.json. This can be used alongside bundle_js(), if
-bundling and minifying is desired.
+This can be used alongside bundle_js(), if bundling and minifying is
+desired.
 ```
 
 #### **Arguments**
@@ -327,6 +326,9 @@
 in_folder: The location of the input files to be minified.
 in_files: The list of JS files to minify with respect to the |in_folder|.
 out_folder: The location where minified files will be outputted.
+out_manifest: The location to write the manifest file of all files
+              outputted by minify_js(). Defaults to
+              $target_gen_dir/${target_name}_manifest.json.
 deps: Targets generating any files being minified.
 ```
 
diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h
index 59e4384..ae615f1d 100644
--- a/extensions/browser/extension_event_histogram_value.h
+++ b/extensions/browser/extension_event_histogram_value.h
@@ -538,6 +538,7 @@
   SMART_CARD_PROVIDER_PRIVATE_ON_CONTROL_REQUESTED = 516,
   OS_EVENTS_ON_POWER_EVENT = 517,
   SMART_CARD_PROVIDER_PRIVATE_ON_GET_ATTRIB_REQUESTED = 518,
+  OS_EVENTS_ON_KEYBOARD_DIAGNOSTIC_EVENT = 519,
   // Last entry: Add new entries above, then run:
   // tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index dae76b9..f67b59c 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1853,6 +1853,7 @@
   AUTOTESTPRIVATE_INSTALLBRUSCHETTA = 1790,
   AUTOTESTPRIVATE_REMOVEBRUSCHETTA = 1791,
   AUTOFILLPRIVATE_AUTHENTICATEUSERTOEDITLOCALCARD = 1792,
+  AUTOTESTPRIVATE_ISFEATUREENABLED = 1793,
   // Last entry: Add new entries above, then run:
   // tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc
index 99f5656..a14cd13 100644
--- a/extensions/browser/sandboxed_unpacker.cc
+++ b/extensions/browser/sandboxed_unpacker.cc
@@ -514,7 +514,6 @@
 
 void SandboxedUnpacker::Unpack(const base::FilePath& directory) {
   DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
-
   DCHECK(directory.DirName() == temp_dir_.GetPath());
 
   base::FilePath manifest_path = extension_root_.Append(kManifestFilename);
diff --git a/extensions/browser/zipfile_installer.cc b/extensions/browser/zipfile_installer.cc
index 2a6a54c..3d88f82 100644
--- a/extensions/browser/zipfile_installer.cc
+++ b/extensions/browser/zipfile_installer.cc
@@ -10,12 +10,15 @@
 #include "base/json/json_reader.h"
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/task/sequenced_task_runner.h"
 #include "components/services/unzip/content/unzip_service.h"
 #include "components/services/unzip/public/cpp/unzip.h"
 #include "components/services/unzip/public/mojom/unzipper.mojom.h"
 #include "extensions/browser/extension_file_task_runner.h"
 #include "extensions/common/constants.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/extension_features.h"
 #include "extensions/common/manifest.h"
 #include "extensions/strings/grit/extensions_strings.h"
 #include "services/data_decoder/public/cpp/data_decoder.h"
@@ -28,6 +31,11 @@
 
 constexpr char kExtensionHandlerTempDirError[] =
     "Could not create temporary directory for zipped extension.";
+constexpr char kExtensionHandlerUnpackedDirCreationError[] =
+    "Failed to create root unpacked directory * for "
+    "zip file: *. Encountered error: *.";
+constexpr char kExtensionHandlerZippedDirError[] =
+    "Could not create directory * for zipped extension.";
 constexpr char kExtensionHandlerFileUnzipError[] =
     "Could not unzip extension for install.";
 
@@ -37,8 +45,11 @@
     FILE_PATH_LITERAL(".json"), FILE_PATH_LITERAL(".png"),
     FILE_PATH_LITERAL(".webp")};
 
-absl::optional<base::FilePath> PrepareAndGetUnzipDir(
-    const base::FilePath& zip_file) {
+// Creates a directory in an OS temporary location based on `zip_file`.
+// Directory format is (`zip_file` == "myzip.zip"):
+//   <`root_unzip_dir`>/myzip_XXXXXX
+// XXXXXX is populated with mkdtemp() logic.
+ZipResultVariant PrepareAndGetTempUnzipDir(const base::FilePath& zip_file) {
   base::FilePath dir_temp;
   base::PathService::Get(base::DIR_TEMP, &dir_temp);
 
@@ -46,10 +57,45 @@
       zip_file.RemoveExtension().BaseName().value() + FILE_PATH_LITERAL("_");
 
   base::FilePath unzip_dir;
-  if (!base::CreateTemporaryDirInDir(dir_temp, dir_name, &unzip_dir))
-    return absl::optional<base::FilePath>();
+  ZipResultVariant unzip_dir_or_error;
+  if (!base::CreateTemporaryDirInDir(dir_temp, dir_name, &unzip_dir)) {
+    return ZipResultVariant{kExtensionHandlerTempDirError};
+  }
 
-  return unzip_dir;
+  return ZipResultVariant{unzip_dir};
+}
+
+// Creates a unique directory based on `zip_file` inside `root_unzip_dir`.
+// Directory format is (`zip_file` == "myzip.zip"):
+//   <`root_unzip_dir`>/myzip_XXXXXX
+// XXXXXX is populated with mkdtemp() logic.
+ZipResultVariant PrepareAndGetUnzipDir(const base::FilePath& zip_file,
+                                       const base::FilePath& root_unzip_dir) {
+  // Create `root_unzip_dir`. This should only occur once per profile as
+  // CreateDirectoryAndGetError check for `root_unzip_dir` to exist first.
+  base::File::Error root_unzip_dir_creation_error;
+  if (!base::CreateDirectoryAndGetError(root_unzip_dir,
+                                        &root_unzip_dir_creation_error)) {
+    return ZipResultVariant{ErrorUtils::FormatErrorMessage(
+        kExtensionHandlerUnpackedDirCreationError,
+        base::UTF16ToUTF8(root_unzip_dir.LossyDisplayName()),
+        base::UTF16ToUTF8(zip_file.LossyDisplayName()),
+        base::File::ErrorToString(root_unzip_dir_creation_error))};
+  }
+
+  // Create the root of the unique directory for the .zip file.
+  base::FilePath::StringType dir_name =
+      zip_file.RemoveExtension().BaseName().value() + FILE_PATH_LITERAL("_");
+
+  // Creates the full unique directory path as unzip_dir.
+  base::FilePath unzip_dir;
+  if (!base::CreateTemporaryDirInDir(root_unzip_dir, dir_name, &unzip_dir)) {
+    return ZipResultVariant{ErrorUtils::FormatErrorMessage(
+        kExtensionHandlerZippedDirError,
+        base::UTF16ToUTF8(unzip_dir.LossyDisplayName()))};
+  }
+
+  return ZipResultVariant{unzip_dir};
 }
 
 absl::optional<std::string> ReadFileContent(const base::FilePath& path) {
@@ -69,9 +115,18 @@
       new ZipFileInstaller(io_task_runner, std::move(done_callback)));
 }
 
-void ZipFileInstaller::LoadFromZipFile(const base::FilePath& zip_file) {
+void ZipFileInstaller::InstallZipFileToTempDir(const base::FilePath& zip_file) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  LoadFromZipFileImpl(zip_file, base::FilePath());
+  LoadFromZipFileImpl(zip_file, base::FilePath(), /*create_unzip_dir=*/true);
+}
+
+void ZipFileInstaller::InstallZipFileToUnpackedExtensionsDir(
+    const base::FilePath& zip_file,
+    const base::FilePath& unpacked_extensions_dir) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!unpacked_extensions_dir.empty());
+  LoadFromZipFileImpl(zip_file, unpacked_extensions_dir,
+                      /*create_unzip_dir=*/true);
 }
 
 void ZipFileInstaller::LoadFromZipFileInDir(const base::FilePath& zip_file,
@@ -82,20 +137,33 @@
 }
 
 void ZipFileInstaller::LoadFromZipFileImpl(const base::FilePath& zip_file,
-                                           const base::FilePath& unzip_dir) {
+                                           const base::FilePath& unzip_dir,
+                                           bool create_unzip_dir) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!zip_file.empty());
 
   zip_file_ = zip_file;
 
-  if (!unzip_dir.empty()) {
-    Unzip(unzip_dir);
+  if (create_unzip_dir) {
+    if (base::FeatureList::IsEnabled(
+            extensions_features::kExtensionsZipFileInstalledInProfileDir)) {
+      io_task_runner_->PostTaskAndReplyWithResult(
+          FROM_HERE,
+          base::BindOnce(&PrepareAndGetUnzipDir, zip_file, unzip_dir),
+          base::BindOnce(&ZipFileInstaller::Unzip, this));
+    } else {
+      // `unzip_dir` unneeded since the temp dir gets created in
+      // PrepareAndGetTempUnzipDir.
+      io_task_runner_->PostTaskAndReplyWithResult(
+          FROM_HERE, base::BindOnce(&PrepareAndGetTempUnzipDir, zip_file),
+          base::BindOnce(&ZipFileInstaller::Unzip, this));
+    }
     return;
   }
 
-  io_task_runner_->PostTaskAndReplyWithResult(
-      FROM_HERE, base::BindOnce(&PrepareAndGetUnzipDir, zip_file),
-      base::BindOnce(&ZipFileInstaller::Unzip, this));
+  // Unzip dir should exist so unzip directly there.
+  // ZipResultVariant result = ZipResultVariant{unzip_dir};
+  Unzip(ZipResultVariant{unzip_dir});
 }
 
 ZipFileInstaller::ZipFileInstaller(
@@ -106,24 +174,28 @@
 
 ZipFileInstaller::~ZipFileInstaller() = default;
 
-void ZipFileInstaller::Unzip(absl::optional<base::FilePath> unzip_dir) {
+void ZipFileInstaller::Unzip(ZipResultVariant unzip_dir_or_error) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  if (!unzip_dir) {
-    ReportFailure(std::string(kExtensionHandlerTempDirError));
+  if (absl::holds_alternative<std::string>(unzip_dir_or_error)) {
+    ReportFailure(absl::get<std::string>(unzip_dir_or_error));
     return;
   }
 
+  base::FilePath unzip_dir = absl::get<base::FilePath>(unzip_dir_or_error);
   unzip::UnzipWithFilter(
-      unzip::LaunchUnzipper(), zip_file_, *unzip_dir,
+      unzip::LaunchUnzipper(), zip_file_, unzip_dir,
       base::BindRepeating(&ZipFileInstaller::IsManifestFile),
-      base::BindOnce(&ZipFileInstaller::ManifestUnzipped, this, *unzip_dir));
+      base::BindOnce(&ZipFileInstaller::ManifestUnzipped, this, unzip_dir));
 }
 
 void ZipFileInstaller::ManifestUnzipped(const base::FilePath& unzip_dir,
                                         bool success) {
   if (!success) {
-    ReportFailure(kExtensionHandlerFileUnzipError);
+    base::FeatureList::IsEnabled(
+        extensions_features::kExtensionsZipFileInstalledInProfileDir)
+        ? ReportFailure(kExtensionHandlerTempDirError)
+        : ReportFailure(kExtensionHandlerFileUnzipError);
     return;
   }
 
diff --git a/extensions/browser/zipfile_installer.h b/extensions/browser/zipfile_installer.h
index f9a2f54..698b76c 100644
--- a/extensions/browser/zipfile_installer.h
+++ b/extensions/browser/zipfile_installer.h
@@ -20,6 +20,8 @@
 
 namespace extensions {
 
+using ZipResultVariant = absl::variant<base::FilePath, std::string>;
+
 // ZipFileInstaller unzips an extension safely using the Unzipper and
 // SafeJSONParser services.
 // This class is not thread-safe: it is bound to the sequence it is created on.
@@ -42,28 +44,50 @@
       DoneCallback done_callback);
 
   // Creates a temporary directory and unzips the extension in it.
-  void LoadFromZipFile(const base::FilePath& zip_file);
+  void InstallZipFileToTempDir(const base::FilePath& zip_file);
 
-  // Unzips the extension in |unzip_dir|.
+  // First attempts to create `unpacked_extensions_dir` and does not load the
+  // extension if unsuccessful. If successful, then unzips the extension into a
+  // unique directory within `unpacked_extensions_dir`.
+  // `unpacked_extensions_dir` should be the unpacked extensions directory from
+  // the extensions service. The directory name will have the format of
+  // "hello-world.zip" -> "hello-world_XXXXXX/" in the style of mkdtemp().
+  void InstallZipFileToUnpackedExtensionsDir(
+      const base::FilePath& zip_file,
+      const base::FilePath& unpacked_extensions_dir);
+
+  // Unzips the extension in `unzip_dir`. If `unzip_dir` is empty, the extension
+  // will not be unzipped.
   void LoadFromZipFileInDir(const base::FilePath& zip_file,
                             const base::FilePath& unzip_dir);
 
  private:
   friend class base::RefCountedThreadSafe<ZipFileInstaller>;
-  FRIEND_TEST_ALL_PREFIXES(ZipFileInstallerTest, NonTheme_FileExtractionFilter);
-  FRIEND_TEST_ALL_PREFIXES(ZipFileInstallerTest, Theme_FileExtractionFilter);
-  FRIEND_TEST_ALL_PREFIXES(ZipFileInstallerTest, ManifestExtractionFilter);
+  FRIEND_TEST_ALL_PREFIXES(ZipFileInstallerFilterTest,
+                           NonTheme_FileExtractionFilter);
+  FRIEND_TEST_ALL_PREFIXES(ZipFileInstallerFilterTest,
+                           Theme_FileExtractionFilter);
+  FRIEND_TEST_ALL_PREFIXES(ZipFileInstallerFilterTest,
+                           ManifestExtractionFilter);
 
   explicit ZipFileInstaller(
       const scoped_refptr<base::SequencedTaskRunner>& io_task_runner,
       DoneCallback done_callback);
   ~ZipFileInstaller();
 
+  // Unzip `zip_file` into `unzip_dir`. `create_unzip_dir` indicates that
+  // `unzip_dir` might need to be created before installing the .zip file to the
+  // dir. extensions_features::kExtensionsZipFileInstalledInProfileDir being
+  // enabled causes `create_unzip_dir` to create a
   void LoadFromZipFileImpl(const base::FilePath& zip_file,
-                           const base::FilePath& unzip_dir);
+                           const base::FilePath& unzip_dir,
+                           bool create_unzip_dir = false);
 
-  // Unzip an extension into |unzip_dir| and load it with an UnpackedInstaller.
-  void Unzip(absl::optional<base::FilePath> unzip_dir);
+  // Unzip an extension the `base::FilePath` provided by the result and load it
+  // with an UnpackedInstaller. String in the result is an error explaining why
+  // the path couldn't be created.
+  void Unzip(ZipResultVariant result);
+
   void ManifestUnzipped(const base::FilePath& unzip_dir, bool success);
   void ManifestRead(const base::FilePath& unzip_dir,
                     absl::optional<std::string> manifest_content);
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc
index b72483c..c72172c 100644
--- a/extensions/common/extension_features.cc
+++ b/extensions/common/extension_features.cc
@@ -175,4 +175,11 @@
              "WebviewTagMPArchBehavior",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// If enabled, extensions installed from .zip files (from dev mode) are changed
+// from installing in base::TEMP_DIR to .../<profile_dir>/UnpackedExtensions and
+// persist until removed by the user.
+BASE_FEATURE(kExtensionsZipFileInstalledInProfileDir,
+             "ExtensionsZipFileInstalledInProfileDir",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 }  // namespace extensions_features
diff --git a/extensions/common/extension_features.h b/extensions/common/extension_features.h
index eb88c937b..e26e8b0 100644
--- a/extensions/common/extension_features.h
+++ b/extensions/common/extension_features.h
@@ -95,6 +95,8 @@
 // See the guidance at the top of this file.
 ///////////////////////////////////////////////////////////////////////////////
 
+BASE_DECLARE_FEATURE(kExtensionsZipFileInstalledInProfileDir);
+
 }  // namespace extensions_features
 
 #endif  // EXTENSIONS_COMMON_EXTENSION_FEATURES_H_
diff --git a/extensions/common/file_util.cc b/extensions/common/file_util.cc
index babfc75b7..5fd55d04 100644
--- a/extensions/common/file_util.cc
+++ b/extensions/common/file_util.cc
@@ -186,26 +186,40 @@
 }
 
 void UninstallExtension(const base::FilePath& profile_dir,
-                        const base::FilePath& extensions_dir,
-                        const std::string& id) {
+                        const base::FilePath& extensions_install_dir,
+                        const base::FilePath& extension_dir_to_delete) {
+  // The below conditions are asserting that we should only be deleting
+  // directories that are inside the `extensions_install_dir` which should be
+  // inside the profile directory. Anything outside of that would be considered
+  // invalid and dangerous since this is effectively an `rm -rf
+  // <extension_delete_path>`.
+
+  // Confirm that all the directories involved are not empty and are absolute so
+  // that the subsequent comparisons have some value.
+  if (profile_dir.empty() || extensions_install_dir.empty() ||
+      extension_dir_to_delete.empty() || !profile_dir.IsAbsolute() ||
+      !extensions_install_dir.IsAbsolute() ||
+      !extension_dir_to_delete.IsAbsolute()) {
+    return;
+  }
+
+  // Confirm the directory where we install extensions is a direct subdir of the
+  // profile dir.
+  if (extensions_install_dir.DirName() != profile_dir) {
+    return;
+  }
+
+  // Confirm the directory we are obliterating is a direct subdir of the
+  // extensions install directory.
+  if (extension_dir_to_delete.DirName() != extensions_install_dir) {
+    return;
+  }
+
+  base::DeletePathRecursively(extension_dir_to_delete);
+
   // We don't care about the return value. If this fails (and it can, due to
   // plugins that aren't unloaded yet), it will get cleaned up by
   // ExtensionGarbageCollector::GarbageCollectExtensions.
-
-  // Confirm the profile directory, extensions directory, and the id are not
-  // empty and that the directories are absolute so that the subsequent
-  // comparison has some value.
-  if (profile_dir.empty() || extensions_dir.empty() || id.empty() ||
-      !profile_dir.IsAbsolute() || !extensions_dir.IsAbsolute()) {
-    return;
-  }
-  // Confirm the directory we are deleting from is a direct subdirectory of
-  // the extensions's subdirectory inside the profile directory.
-  if (extensions_dir.DirName() != profile_dir) {
-    return;
-  }
-
-  base::DeletePathRecursively(extensions_dir.AppendASCII(id));
 }
 
 scoped_refptr<Extension> LoadExtension(const base::FilePath& extension_path,
diff --git a/extensions/common/file_util.h b/extensions/common/file_util.h
index d391d92..2df94b6 100644
--- a/extensions/common/file_util.h
+++ b/extensions/common/file_util.h
@@ -45,17 +45,18 @@
                                 const std::string& version,
                                 const base::FilePath& extensions_dir);
 
-// Removes all versions of the extension with `id` from `extensions_dir` with a
-// recursive delete. `profile_dir` is the path to the current Chrome profile
+// Removes all versions of the extension from `extension_dir_to_delete` by
+// deleting the folder. `profile_dir` is the path to the current Chrome profile
 // directory. Requirements:
-//   *) `profile_dir`, `extensions_dir`, and `id` cannot be empty
-//   *) `profile_dir`, and `extensions_dir` must be absolute paths
-//   *) `extensions_dir` must be a subdir of `profile_dir`
+//   *)  all paths cannot be empty
+//   *) all paths must be absolute must be absolute
+//   *) `extensions_dir` must be a direct subdir of `profile_dir`
+//   *  `extension_dir_to_delete` must be a direct subdir of `extensions_dir`
 // Otherwise the deletion will not be performed to avoid the risk of dangerous
 // paths like ".", "..", etc.
 void UninstallExtension(const base::FilePath& profile_dir,
-                        const base::FilePath& extensions_dir,
-                        const std::string& id);
+                        const base::FilePath& extensions_install_dir,
+                        const base::FilePath& extension_dir_to_delete);
 
 // Loads and validates an extension from the specified directory. Uses
 // the default manifest filename. Returns nullptr on failure, with a
diff --git a/extensions/common/file_util_unittest.cc b/extensions/common/file_util_unittest.cc
index 08f9ee0..57afc9a 100644
--- a/extensions/common/file_util_unittest.cc
+++ b/extensions/common/file_util_unittest.cc
@@ -117,8 +117,8 @@
 
 struct UninstallTestData {
   absl::optional<const base::FilePath> profile_dir;
-  absl::optional<const base::FilePath> extensions_dir;
-  const std::string id;
+  absl::optional<const base::FilePath> extensions_install_dir;
+  absl::optional<const base::FilePath> extension_dir_to_delete;
   bool extension_directory_deleted;
 };
 
@@ -128,52 +128,83 @@
   static const auto* test_data = new std::vector<UninstallTestData>{
       // Valid directory.
       {/*profile_dir=*/absl::nullopt,
-       /*extensions_dir=*/absl::nullopt, kExtensionId,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/true},
+
       // Empty profile directory.
       {/*profile_dir=*/base::FilePath(),
-       /*extensions_dir=*/absl::nullopt, kExtensionId,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
       // Empty extensions directory.
       {/*profile_dir=*/absl::nullopt,
-       /*extensions_dir=*/base::FilePath(), kExtensionId,
+       /*extensions_install_dir=*/base::FilePath(),
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
-      // Empty id.
+      // Empty extensions directory to delete.
       {/*profile_dir=*/absl::nullopt,
-       /*extensions_dir=*/absl::nullopt, "",
+       /*extensions_install_dir=*/absl::nullopt, base::FilePath(),
        /*extension_directory_deleted=*/false},
+
       // Nonabsolute profile directory.
       {/*profile_dir=*/base::FilePath(FILE_PATH_LITERAL("not/absolutepath")),
-       /*extensions_dir=*/absl::nullopt, kExtensionId,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
       // Nonabsolute extensions directory.
       {/*profile_dir=*/absl::nullopt,
-       /*extensions_dir=*/base::FilePath(FILE_PATH_LITERAL("not/absolutepath")),
-       kExtensionId,
+       /*extensions_install_dir=*/
+       base::FilePath(FILE_PATH_LITERAL("not/absolutepath")),
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
+      // Nonabsolute extensions directory to delete.
+      {/*profile_dir=*/absl::nullopt,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/
+       base::FilePath(FILE_PATH_LITERAL("not/absolutepath")),
+       /*extension_directory_deleted=*/false},
+
+      // Dangerous extensions directory to delete values.
+      {/*profile_dir=*/absl::nullopt,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/base::FilePath(FILE_PATH_LITERAL(".")),
+       /*extension_directory_deleted=*/false},
+      {/*profile_dir=*/absl::nullopt,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/base::FilePath(FILE_PATH_LITERAL("..")),
+       /*extension_directory_deleted=*/false},
+      {/*profile_dir=*/absl::nullopt,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/base::FilePath(FILE_PATH_LITERAL("/")),
+       /*extension_directory_deleted=*/false},
+
       // Dangerous profile directory values.
       {/*profile_dir=*/base::FilePath(FILE_PATH_LITERAL(".")),
-       /*extensions_dir=*/absl::nullopt, kExtensionId,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
-      // Dangerous profile directory values.
       {/*profile_dir=*/base::FilePath(FILE_PATH_LITERAL("..")),
-       /*extensions_dir=*/absl::nullopt, kExtensionId,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
-      // Dangerous profile directory values.
       {/*profile_dir=*/base::FilePath(FILE_PATH_LITERAL("/")),
-       /*extensions_dir=*/absl::nullopt, kExtensionId,
+       /*extensions_install_dir=*/absl::nullopt,
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
+
       // Dangerous extensions directory values.
       {/*profile_dir=*/absl::nullopt,
-       /*extensions_dir=*/base::FilePath(FILE_PATH_LITERAL(".")), kExtensionId,
+       /*extensions_install_dir=*/base::FilePath(FILE_PATH_LITERAL(".")),
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
-      // Dangerous extensions directory values.
       {/*profile_dir=*/absl::nullopt,
-       /*extensions_dir=*/base::FilePath(FILE_PATH_LITERAL("..")), kExtensionId,
+       /*extensions_install_dir=*/base::FilePath(FILE_PATH_LITERAL("..")),
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false},
-      // Dangerous extensions directory values.
       {/*profile_dir=*/absl::nullopt,
-       /*extensions_dir=*/base::FilePath(FILE_PATH_LITERAL("/")), kExtensionId,
+       /*extensions_install_dir=*/base::FilePath(FILE_PATH_LITERAL("/")),
+       /*extension_dir_to_delete=*/absl::nullopt,
        /*extension_directory_deleted=*/false}};
 
   return *test_data;
@@ -183,7 +214,9 @@
 
 typedef testing::Test FileUtilTest;
 
-TEST_F(FileUtilTest, InstallUninstallGarbageCollect) {
+// Tests that packed extensions have all their versions deleted when the
+// extension is uninstalled.
+TEST_F(FileUtilTest, UninstallRemovesAllPackedExtensionVersions) {
   base::ScopedTempDir temp;
   ASSERT_TRUE(temp.CreateUniqueTempDir());
 
@@ -201,12 +234,14 @@
   base::FilePath extensions_dir = profile_dir.AppendASCII("TestExtensions");
   ASSERT_TRUE(base::CreateDirectory(extensions_dir));
 
+  base::FilePath extensions_dir_to_delete =
+      extensions_dir.AppendASCII(kExtensionId);
+
   // Install in empty directory. Should create parent directories as needed.
   base::FilePath version_1 =
       file_util::InstallExtension(src, kExtensionId, version, extensions_dir);
-  ASSERT_EQ(
-      version_1.value(),
-      extensions_dir.AppendASCII(kExtensionId).AppendASCII("1.0_0").value());
+  EXPECT_EQ(version_1.value(),
+            extensions_dir_to_delete.AppendASCII("1.0_0").value());
   ASSERT_TRUE(base::DirectoryExists(version_1));
   ASSERT_TRUE(base::PathExists(version_1.Append(extension_content.BaseName())));
 
@@ -217,9 +252,8 @@
   ASSERT_TRUE(base::CreateDirectory(src));
   base::FilePath version_2 =
       file_util::InstallExtension(src, kExtensionId, version, extensions_dir);
-  ASSERT_EQ(
-      version_2.value(),
-      extensions_dir.AppendASCII(kExtensionId).AppendASCII("1.0_1").value());
+  EXPECT_EQ(version_2.value(),
+            extensions_dir_to_delete.AppendASCII("1.0_1").value());
   ASSERT_TRUE(base::DirectoryExists(version_2));
 
   // Should have moved the source.
@@ -229,17 +263,17 @@
   ASSERT_TRUE(base::CreateDirectory(src));
   base::FilePath version_3 =
       file_util::InstallExtension(src, kExtensionId, version, extensions_dir);
-  ASSERT_EQ(
-      version_3.value(),
-      extensions_dir.AppendASCII(kExtensionId).AppendASCII("1.0_2").value());
+  EXPECT_EQ(version_3.value(),
+            extensions_dir_to_delete.AppendASCII("1.0_2").value());
   ASSERT_TRUE(base::DirectoryExists(version_3));
 
   // Uninstall. Should remove entire extension subtree.
-  file_util::UninstallExtension(profile_dir, extensions_dir, kExtensionId);
-  ASSERT_FALSE(base::DirectoryExists(version_1.DirName()));
-  ASSERT_FALSE(base::DirectoryExists(version_2.DirName()));
-  ASSERT_FALSE(base::DirectoryExists(version_3.DirName()));
-  ASSERT_TRUE(base::DirectoryExists(extensions_dir));
+  file_util::UninstallExtension(profile_dir, extensions_dir,
+                                extensions_dir_to_delete);
+  EXPECT_FALSE(base::DirectoryExists(version_1.DirName()));
+  EXPECT_FALSE(base::DirectoryExists(version_2.DirName()));
+  EXPECT_FALSE(base::DirectoryExists(version_3.DirName()));
+  EXPECT_TRUE(base::DirectoryExists(extensions_dir));
 }
 
 TEST_F(FileUtilTest, LoadExtensionWithMetadataFolder) {
@@ -719,10 +753,10 @@
   bool ExtensionDirectoryNotDeleted();
 
   base::FilePath profile_dir_;
-  base::FilePath extensions_dir_;
+  base::FilePath extensions_install_dir_;
+  base::FilePath extension_dir_to_delete_;
   base::FilePath extension_id_dir_;
   base::FilePath extension_version_dir_;
-  ExtensionId extension_id_;
 
  private:
   base::ScopedTempDir temp_dir_;
@@ -730,19 +764,19 @@
 
 bool UninstallTest::SetupExtensionsDirForUninstall() {
   profile_dir_ = temp_dir_.GetPath().AppendASCII("Default");
-  extensions_dir_ = profile_dir_.AppendASCII("TestExtensions");
-  extension_id_dir_ = extensions_dir_.AppendASCII(kExtensionId);
+  extensions_install_dir_ = profile_dir_.AppendASCII("TestExtensions");
+  extension_id_dir_ = extensions_install_dir_.AppendASCII(kExtensionId);
   std::string version("1.0_0");
   extension_version_dir_ = extension_id_dir_.AppendASCII(version);
   base::CreateDirectory(profile_dir_);
-  base::CreateDirectory(extensions_dir_);
+  base::CreateDirectory(extensions_install_dir_);
   base::CreateDirectory(extension_id_dir_);
   base::CreateDirectory(extension_version_dir_);
   return base::DirectoryExists(extension_version_dir_);
 }
 
 bool UninstallTest::ExtensionDirectoryDeleted() {
-  return base::DirectoryExists(extensions_dir_) &&
+  return base::DirectoryExists(extensions_install_dir_) &&
          !base::DirectoryExists(extension_id_dir_);
 }
 
@@ -760,13 +794,15 @@
     UninstallTest::SetUp();
 
     // Overrides with parameterized values.
-    if (GetParam().extensions_dir.has_value()) {
-      extensions_dir_ = GetParam().extensions_dir.value();
-    }
     if (GetParam().profile_dir.has_value()) {
       profile_dir_ = GetParam().profile_dir.value();
     }
-    extension_id_ = GetParam().id;
+    if (GetParam().extensions_install_dir.has_value()) {
+      extensions_install_dir_ = GetParam().extensions_install_dir.value();
+    }
+    if (GetParam().extension_dir_to_delete.has_value()) {
+      extension_id_dir_ = GetParam().extension_dir_to_delete.value();
+    }
   }
 };
 
@@ -778,7 +814,8 @@
                          testing::ValuesIn(GetTestData()));
 
 TEST_P(UninstallTestParameterized, UninstallDirectory) {
-  file_util::UninstallExtension(profile_dir_, extensions_dir_, extension_id_);
+  file_util::UninstallExtension(profile_dir_, extensions_install_dir_,
+                                /*extension_dir_to_delete=*/extension_id_dir_);
   if (GetParam().extension_directory_deleted) {
     EXPECT_TRUE(ExtensionDirectoryDeleted());
   } else {
@@ -786,13 +823,26 @@
   }
 }
 
-// Tests when the extension directory we are attempting to delete is outside of
-// the extension's subdirectory of the profile directory.
-TEST_F(UninstallTest, UninstallDirectory_OutsideExtensionsDirectoryFails) {
+// Tests when the extensions install directory is outside of the profile
+// directory.
+TEST_F(UninstallTest,
+       UninstallDirectory_ExtensionsInstallDirNotSubdirOfProfileDir) {
+  file_util::UninstallExtension(profile_dir_,
+                                /*extensions_install_dir=*/
+                                profile_dir_.AppendASCII("OutsideProfileDir"),
+                                /*extension_dir_to_delete=*/extension_id_dir_);
+  EXPECT_TRUE(ExtensionDirectoryNotDeleted());
+}
+
+// Tests when the extension directory to delete is outside of the extensions
+// install directory.
+TEST_F(
+    UninstallTest,
+    UninstallDirectory_ExtensionsDirToDeleteNotSubdirOfExtensionsInstallDir) {
   file_util::UninstallExtension(
-      profile_dir_,
-      /*extensions_dir=*/profile_dir_.AppendASCII("OutsideExtensionsDir"),
-      kExtensionId);
+      profile_dir_, extensions_install_dir_,
+      /*extension_dir_to_delete=*/
+      extensions_install_dir_.AppendASCII("OutsideExtensionsInstallDir"));
   EXPECT_TRUE(ExtensionDirectoryNotDeleted());
 }
 
diff --git a/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc b/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
index f86dc70..05f2a68 100644
--- a/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
+++ b/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
@@ -303,6 +303,17 @@
           }])",
           "Invalid value for 'file_handlers[0]'. `action` must "
           "start with a forward slash.",
+      },
+      {
+          "Error if `launch_type` multiple-clients is singular.",
+          R"([{
+            "name":"test",
+            "action":"/path",
+            "accept": {"text/csv": ".csv"},
+            "launch_type": "multiple-client"
+          }])",
+          "Invalid value for 'file_handlers[0]'. `launch_type` must have a "
+          "valid value.",
       }};
 
   for (const auto& test_case : test_cases) {
diff --git a/extensions/common/manifest_handlers/web_file_handlers_info.cc b/extensions/common/manifest_handlers/web_file_handlers_info.cc
index 6723164d..d030b8b 100644
--- a/extensions/common/manifest_handlers/web_file_handlers_info.cc
+++ b/extensions/common/manifest_handlers/web_file_handlers_info.cc
@@ -166,6 +166,18 @@
       file_handler.icons = std::move(manifest_file_handler.icons);
     }
 
+    // `launch_type` is an optional string that defaults to "single-client".
+    file_handler.launch_type = std::move(manifest_file_handler.launch_type);
+    if (!file_handler.launch_type.has_value()) {
+      file_handler.launch_type = "single-client";
+    } else {
+      const std::string launch_type = file_handler.launch_type.value();
+      if (launch_type != "single-client" && launch_type != "multiple-clients") {
+        *error = get_error(i, "`launch_type` must have a valid value.");
+        return nullptr;
+      }
+    }
+
     // Append file handlers.
     info->file_handlers.emplace_back(std::move(file_handler));
   }
diff --git a/fuchsia_web/webengine/test/isolated_archivist.h b/fuchsia_web/webengine/test/isolated_archivist.h
index 6626eb07..7237a68 100644
--- a/fuchsia_web/webengine/test/isolated_archivist.h
+++ b/fuchsia_web/webengine/test/isolated_archivist.h
@@ -11,7 +11,7 @@
 #include "base/fuchsia/scoped_service_publisher.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-// Runs an isolated archivist-without-attribution, publishing its
+// Runs an isolated archivist-for-embedding, publishing its
 // fuchsia_logger::LogSink into a given OutgoingDirectory, and providing access
 // to its fuchsia.logger.Log. Consumers of this class must use
 // `//build/config/fuchsia/test/archivist.shard.test-cml` in their component
diff --git a/google_apis/gcm/engine/checkin_request.h b/google_apis/gcm/engine/checkin_request.h
index 1c612635..d045ad4 100644
--- a/google_apis/gcm/engine/checkin_request.h
+++ b/google_apis/gcm/engine/checkin_request.h
@@ -86,9 +86,8 @@
                          std::unique_ptr<std::string> body);
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(GCMClientImplCheckinTest, CheckinWithAccounts);
-  FRIEND_TEST_ALL_PREFIXES(GCMClientImplCheckinTest,
-                           CheckinWithAccountsEmptyWithFeature);
+  FRIEND_TEST_ALL_PREFIXES(GCMClientImplCheckinTest, CheckinWithAccountsEmpty);
+
   // Schedules a retry attempt with a backoff.
   void RetryWithBackoff();
 
diff --git a/gpu/command_buffer/client/BUILD.gn b/gpu/command_buffer/client/BUILD.gn
index 22bf9d6..2d9417a 100644
--- a/gpu/command_buffer/client/BUILD.gn
+++ b/gpu/command_buffer/client/BUILD.gn
@@ -90,11 +90,14 @@
   deps = [
     ":gles2_interface",
     "//gpu/command_buffer/common:common_sources",
-    "//gpu/ipc/common:surface_handle_type",
     "//ui/gfx:memory_buffer",
     "//ui/gfx/geometry",
   ]
 
+  if (!is_nacl) {
+    deps += [ "//gpu/ipc/common:surface_handle_type" ]
+  }
+
   # These files now rely on Skia which isn't allowed as a dependency in nacl builds.
   if (!is_nacl && !is_minimal_toolchain) {
     sources += [
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index ff968ddf..d412f379 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -193,11 +193,6 @@
   int depth;
 };
 
-bool AlwaysGetSizeFromSourceTexture() {
-  return base::FeatureList::IsEnabled(
-      features::kCmdDecoderAlwaysGetSizeFromSourceTexture);
-}
-
 // Check if all |ref| bits are set in |bits|.
 bool AllBitsSet(GLbitfield bits, GLbitfield ref) {
   DCHECK_NE(0u, ref);
@@ -17861,30 +17856,18 @@
 
   int source_width = 0;
   int source_height = 0;
-  gl::GLImage* image =
-      source_texture->GetLevelImage(source_target, source_level);
-  if (image && !AlwaysGetSizeFromSourceTexture()) {
-    gfx::Size size = image->GetSize();
-    source_width = size.width();
-    source_height = size.height();
-    if (source_width <= 0 || source_height <= 0) {
-      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid image size");
-      return;
-    }
-  } else {
-    if (!source_texture->GetLevelSize(source_target, source_level,
-                                      &source_width, &source_height, nullptr)) {
-      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
-                         "source texture has no data for level");
-      return;
-    }
+  if (!source_texture->GetLevelSize(source_target, source_level, &source_width,
+                                    &source_height, nullptr)) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
+                       "source texture has no data for level");
+    return;
+  }
 
-    // Check that this type of texture is allowed.
-    if (!texture_manager()->ValidForTextureTarget(
-            source_texture, source_level, source_width, source_height, 1)) {
-      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions");
-      return;
-    }
+  // Check that this type of texture is allowed.
+  if (!texture_manager()->ValidForTextureTarget(
+          source_texture, source_level, source_width, source_height, 1)) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions");
+    return;
   }
 
   if (dest_texture->IsImmutable()) {
@@ -18002,54 +17985,26 @@
   GLenum dest_binding_target = dest_texture->target();
   int source_width = 0;
   int source_height = 0;
-  gl::GLImage* image =
-      source_texture->GetLevelImage(source_target, source_level);
-  if (image && !AlwaysGetSizeFromSourceTexture()) {
-    gfx::Size size = image->GetSize();
-    source_width = size.width();
-    source_height = size.height();
-    if (source_width <= 0 || source_height <= 0) {
-      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid image size");
-      return;
-    }
+  if (!source_texture->GetLevelSize(source_target, source_level, &source_width,
+                                    &source_height, nullptr)) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
+                       "source texture has no data for level");
+    return;
+  }
 
-    // Ideally we should not need to check that the sub-texture copy rectangle
-    // is valid in two different ways, here and below. However currently there
-    // is no guarantee that a texture backed by a GLImage will have sensible
-    // level info. If this synchronization were to be enforced then this and
-    // other functions in this file could be cleaned up.
-    // See: https://crbug.com/586476
-    int32_t max_x;
-    int32_t max_y;
-    if (!base::CheckAdd(x, width).AssignIfValid(&max_x) ||
-        !base::CheckAdd(y, height).AssignIfValid(&max_y) || x < 0 || y < 0 ||
-        max_x > source_width || max_y > source_height) {
-      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
-                         "source texture bad dimensions");
-      return;
-    }
-  } else {
-    if (!source_texture->GetLevelSize(source_target, source_level,
-                                      &source_width, &source_height, nullptr)) {
-      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
-                         "source texture has no data for level");
-      return;
-    }
+  // Check that this type of texture is allowed.
+  if (!texture_manager()->ValidForTextureTarget(
+          source_texture, source_level, source_width, source_height, 1)) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
+                       "source texture bad dimensions");
+    return;
+  }
 
-    // Check that this type of texture is allowed.
-    if (!texture_manager()->ValidForTextureTarget(
-            source_texture, source_level, source_width, source_height, 1)) {
-      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
-                         "source texture bad dimensions");
-      return;
-    }
-
-    if (!source_texture->ValidForTexture(source_target, source_level, x, y, 0,
-                                         width, height, 1)) {
-      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
-                         "source texture bad dimensions.");
-      return;
-    }
+  if (!source_texture->ValidForTexture(source_target, source_level, x, y, 0,
+                                       width, height, 1)) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
+                       "source texture bad dimensions.");
+    return;
   }
 
   GLenum source_type = 0;
diff --git a/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
index c765c957..cc082b3b 100644
--- a/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
@@ -875,8 +875,24 @@
     uint32_t usage,
     std::string debug_label,
     gfx::GpuMemoryBufferHandle handle) {
-  NOTIMPLEMENTED_LOG_ONCE();
-  return nullptr;
+  CHECK_EQ(handle.type, gfx::ANDROID_HARDWARE_BUFFER);
+  if (!ValidateUsage(usage, size, format)) {
+    return nullptr;
+  }
+
+  auto estimated_size = format.MaybeEstimatedSizeInBytes(size);
+  if (!estimated_size) {
+    LOG(ERROR) << "Failed to calculate SharedImage size";
+    return nullptr;
+  }
+
+  auto backing = std::make_unique<AHardwareBufferImageBacking>(
+      mailbox, format, size, color_space, surface_origin, alpha_type, usage,
+      std::move(handle.android_hardware_buffer), estimated_size.value(), false,
+      base::ScopedFD(), dawn_procs_, use_passthrough_);
+
+  backing->SetCleared();
+  return backing;
 }
 
 std::unique_ptr<SharedImageBacking>
@@ -891,34 +907,14 @@
     SkAlphaType alpha_type,
     uint32_t usage,
     std::string debug_label) {
-  // TODO(vasilyt): support SHARED_MEMORY_BUFFER?
-  if (handle.type != gfx::ANDROID_HARDWARE_BUFFER) {
-    NOTIMPLEMENTED();
-    return nullptr;
-  }
   if (plane != gfx::BufferPlane::DEFAULT) {
     LOG(ERROR) << "Invalid plane " << gfx::BufferPlaneToString(plane);
     return nullptr;
   }
 
-  auto si_format = viz::GetSharedImageFormat(buffer_format);
-  if (!ValidateUsage(usage, size, si_format)) {
-    return nullptr;
-  }
-
-  auto estimated_size = si_format.MaybeEstimatedSizeInBytes(size);
-  if (!estimated_size) {
-    LOG(ERROR) << "Failed to calculate SharedImage size";
-    return nullptr;
-  }
-
-  auto backing = std::make_unique<AHardwareBufferImageBacking>(
-      mailbox, si_format, size, color_space, surface_origin, alpha_type, usage,
-      std::move(handle.android_hardware_buffer), estimated_size.value(), false,
-      base::ScopedFD(), dawn_procs_, use_passthrough_);
-
-  backing->SetCleared();
-  return backing;
+  return CreateSharedImage(mailbox, viz::GetSharedImageFormat(buffer_format),
+                           size, color_space, surface_origin, alpha_type, usage,
+                           debug_label, std::move(handle));
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
index 0ec7397..3f1e2e8 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
@@ -113,8 +113,15 @@
     uint32_t usage,
     std::string debug_label,
     gfx::GpuMemoryBufferHandle handle) {
-  NOTIMPLEMENTED_LOG_ONCE();
-  return nullptr;
+  auto backing = std::make_unique<AngleVulkanImageBacking>(
+      context_state_, mailbox, format, size, color_space, surface_origin,
+      alpha_type, usage);
+
+  if (!backing->InitializeWihGMB(std::move(handle))) {
+    return nullptr;
+  }
+
+  return backing;
 }
 
 std::unique_ptr<SharedImageBacking>
@@ -129,15 +136,9 @@
     SkAlphaType alpha_type,
     uint32_t usage,
     std::string debug_label) {
-  auto si_format = viz::GetSharedImageFormat(buffer_format);
-  auto backing = std::make_unique<AngleVulkanImageBacking>(
-      context_state_, mailbox, si_format, size, color_space, surface_origin,
-      alpha_type, usage);
-
-  if (!backing->InitializeWihGMB(std::move(handle)))
-    return nullptr;
-
-  return backing;
+  return CreateSharedImage(mailbox, viz::GetSharedImageFormat(buffer_format),
+                           size, color_space, surface_origin, alpha_type, usage,
+                           debug_label, std::move(handle));
 }
 
 bool AngleVulkanImageBackingFactory::IsGMBSupported(
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc b/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
index f77fe468..1fa3385 100644
--- a/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
@@ -245,25 +245,25 @@
     VulkanCommandPool* command_pool,
     const Mailbox& mailbox,
     gfx::GpuMemoryBufferHandle handle,
-    gfx::BufferFormat buffer_format,
+    viz::SharedImageFormat format,
     const gfx::Size& size,
     const gfx::ColorSpace& color_space,
     GrSurfaceOrigin surface_origin,
     SkAlphaType alpha_type,
     uint32_t usage) {
-  if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size, buffer_format)) {
+  if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size,
+                                                     ToBufferFormat(format))) {
     DLOG(ERROR) << "Invalid image size for format.";
     return nullptr;
   }
 
   auto* vulkan_implementation =
       context_state->vk_context_provider()->GetVulkanImplementation();
-  auto si_format = viz::GetSharedImageFormat(buffer_format);
   auto* device_queue = context_state->vk_context_provider()->GetDeviceQueue();
   DCHECK(vulkan_implementation->CanImportGpuMemoryBuffer(device_queue,
                                                          handle.type));
 
-  VkFormat vk_format = ToVkFormat(si_format);
+  VkFormat vk_format = ToVkFormat(format);
   auto image = vulkan_implementation->CreateImageFromGpuMemoryHandle(
       device_queue, std::move(handle), size, vk_format, color_space);
   if (!image) {
@@ -278,9 +278,9 @@
   textures.emplace_back(std::move(image));
 
   bool use_separate_gl_texture =
-      UseSeparateGLTexture(context_state.get(), si_format);
+      UseSeparateGLTexture(context_state.get(), format);
   auto backing = std::make_unique<ExternalVkImageBacking>(
-      base::PassKey<ExternalVkImageBacking>(), mailbox, si_format, size,
+      base::PassKey<ExternalVkImageBacking>(), mailbox, format, size,
       color_space, surface_origin, alpha_type, usage, estimated_size,
       std::move(context_state), std::move(textures), command_pool,
       use_separate_gl_texture);
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing.h b/gpu/command_buffer/service/shared_image/external_vk_image_backing.h
index d27ce75..01b312e 100644
--- a/gpu/command_buffer/service/shared_image/external_vk_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing.h
@@ -51,7 +51,7 @@
       VulkanCommandPool* command_pool,
       const Mailbox& mailbox,
       gfx::GpuMemoryBufferHandle handle,
-      gfx::BufferFormat buffer_format,
+      viz::SharedImageFormat format,
       const gfx::Size& size,
       const gfx::ColorSpace& color_space,
       GrSurfaceOrigin surface_origin,
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.cc
index 7eed4ad..8672609 100644
--- a/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.cc
@@ -6,6 +6,7 @@
 
 #include "build/build_config.h"
 #include "components/viz/common/gpu/vulkan_context_provider.h"
+#include "components/viz/common/resources/resource_format_utils.h"
 #include "components/viz/common/resources/shared_image_format.h"
 #include "gpu/command_buffer/common/shared_image_usage.h"
 #include "gpu/command_buffer/service/shared_image/external_vk_image_backing.h"
@@ -163,8 +164,10 @@
     uint32_t usage,
     std::string debug_label,
     gfx::GpuMemoryBufferHandle handle) {
-  NOTIMPLEMENTED_LOG_ONCE();
-  return nullptr;
+  CHECK(CanImportGpuMemoryBuffer(handle.type));
+  return ExternalVkImageBacking::CreateFromGMB(
+      context_state_, command_pool_.get(), mailbox, std::move(handle), format,
+      size, color_space, surface_origin, alpha_type, usage);
 }
 
 std::unique_ptr<SharedImageBacking>
@@ -179,14 +182,13 @@
     SkAlphaType alpha_type,
     uint32_t usage,
     std::string debug_label) {
-  DCHECK(CanImportGpuMemoryBuffer(handle.type));
   if (plane != gfx::BufferPlane::DEFAULT) {
     LOG(ERROR) << "Invalid plane";
     return nullptr;
   }
-  return ExternalVkImageBacking::CreateFromGMB(
-      context_state_, command_pool_.get(), mailbox, std::move(handle),
-      buffer_format, size, color_space, surface_origin, alpha_type, usage);
+  return CreateSharedImage(mailbox, viz::GetSharedImageFormat(buffer_format),
+                           size, color_space, surface_origin, alpha_type, usage,
+                           debug_label, std::move(handle));
 }
 
 bool ExternalVkImageBackingFactory::CanImportGpuMemoryBuffer(
diff --git a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc
index cb6391a..11c3f446 100644
--- a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc
@@ -8,6 +8,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "components/viz/common/resources/resource_format_utils.h"
 #include "gpu/command_buffer/common/shared_image_usage.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
 #include "gpu/command_buffer/service/shared_image/shared_memory_image_backing.h"
 #include "gpu/command_buffer/service/shared_memory_region_wrapper.h"
 #include "ui/gfx/gpu_memory_buffer.h"
@@ -61,8 +62,9 @@
     uint32_t usage,
     std::string debug_label,
     gfx::GpuMemoryBufferHandle handle) {
-  NOTIMPLEMENTED_LOG_ONCE();
-  return nullptr;
+  return CreateSharedImage(mailbox, std::move(handle), ToBufferFormat(format),
+                           gfx::BufferPlane::DEFAULT, size, color_space,
+                           surface_origin, alpha_type, usage, debug_label);
 }
 
 std::unique_ptr<SharedImageBacking>
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc
index 1a0a17d50..79156e4 100644
--- a/gpu/config/gpu_finch_features.cc
+++ b/gpu/config/gpu_finch_features.cc
@@ -389,13 +389,6 @@
              "PassthroughYuvRgbConversion",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-// When enabled, the validating command decoder always obtains the size to use
-// from the source texture when copying textures, rather than first checking if
-// there is a GLImage present and using its size if so.
-BASE_FEATURE(kCmdDecoderAlwaysGetSizeFromSourceTexture,
-             "CmdDecoderAlwaysGetSizeFromSourceTexture",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // When the application is in background, whether to perform immediate GPU
 // cleanup when executing deferred requests.
 BASE_FEATURE(kGpuCleanupInBackground,
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h
index 77d6fb26e..b23fa73 100644
--- a/gpu/config/gpu_finch_features.h
+++ b/gpu/config/gpu_finch_features.h
@@ -94,8 +94,6 @@
 
 GPU_EXPORT BASE_DECLARE_FEATURE(kPassthroughYuvRgbConversion);
 
-GPU_EXPORT BASE_DECLARE_FEATURE(kCmdDecoderAlwaysGetSizeFromSourceTexture);
-
 GPU_EXPORT BASE_DECLARE_FEATURE(kGpuCleanupInBackground);
 
 GPU_EXPORT bool UseGles2ForOopR();
diff --git a/infra/OWNERS b/infra/OWNERS
index a603432..e379153 100644
--- a/infra/OWNERS
+++ b/infra/OWNERS
@@ -10,7 +10,9 @@
 gbeaty@chromium.org
 guterman@google.com
 hypan@google.com
+keybo@google.com
 kimstephanie@google.com
+linxinan@chromium.org
 morawand@google.com
 sshrimp@google.com
 svenzheng@chromium.org
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index fb5cf5f1..713d6543 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -4489,6 +4489,7 @@
       ref_regexp_exclude: "refs/branch-heads/5615"
       ref_regexp_exclude: "refs/branch-heads/5672"
       ref_regexp_exclude: "refs/branch-heads/5735"
+      ref_regexp_exclude: "refs/branch-heads/5790"
     }
   }
   verifiers {
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 35cee6fe..f9bc3c5 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -296,6 +296,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -1259,6 +1263,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -2005,6 +2013,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -2491,6 +2503,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -2846,6 +2862,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -3449,6 +3469,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -3789,6 +3813,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -4234,6 +4262,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -4575,6 +4607,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -5124,6 +5160,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -5523,6 +5563,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -5928,6 +5972,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -6274,6 +6322,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -6727,6 +6779,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -7287,6 +7343,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -7777,6 +7837,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -8154,6 +8218,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -8519,6 +8587,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -9008,6 +9080,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -9828,6 +9904,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -10191,6 +10271,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -10587,6 +10671,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -10978,6 +11066,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -11608,6 +11700,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -11972,6 +12068,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -12382,6 +12482,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -12802,6 +12906,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -13242,6 +13350,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -13582,6 +13694,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -14067,6 +14183,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -14438,6 +14558,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -14813,6 +14937,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -15343,6 +15471,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -15713,6 +15845,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -16124,6 +16260,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -16499,6 +16639,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
@@ -16865,6 +17009,10 @@
         url: "/p/chromium-m114/g/main/console"
       }
       links {
+        text: "m115"
+        url: "/p/chromium-m115/g/main/console"
+      }
+      links {
         text: "trunk"
         url: "/p/chromium/g/main/console"
         alt: "Trunk (ToT) console"
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index fbe37cf7..f5de5bb 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -400,6 +400,7 @@
     principals: "project:chromium-m112"
     principals: "project:chromium-m113"
     principals: "project:chromium-m114"
+    principals: "project:chromium-m115"
     principals: "user:chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
     principals: "user:findit-for-me@appspot.gserviceaccount.com"
   }
@@ -452,6 +453,7 @@
     principals: "project:chromium-m112"
     principals: "project:chromium-m113"
     principals: "project:chromium-m114"
+    principals: "project:chromium-m115"
     principals: "user:chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com"
     principals: "user:infra-try-recipes-tester@chops-service-accounts.iam.gserviceaccount.com"
   }
diff --git a/infra/config/milestones.json b/infra/config/milestones.json
index cb89574..fb6b614 100644
--- a/infra/config/milestones.json
+++ b/infra/config/milestones.json
@@ -28,5 +28,10 @@
         "name": "m114",
         "project": "chromium-m114",
         "ref": "refs/branch-heads/5735"
+    },
+    "115": {
+        "name": "m115",
+        "project": "chromium-m115",
+        "ref": "refs/branch-heads/5790"
     }
 }
diff --git a/infra/inclusive_language_presubmit_exempt_dirs.txt b/infra/inclusive_language_presubmit_exempt_dirs.txt
index 716b6a1..720f3b47 100644
--- a/infra/inclusive_language_presubmit_exempt_dirs.txt
+++ b/infra/inclusive_language_presubmit_exempt_dirs.txt
@@ -293,7 +293,25 @@
 third_party/blink/perf_tests/parser/resources 81 2
 third_party/blink/perf_tests/sanitizer-api/resources 77 1
 third_party/blink/perf_tests/shadow_dom 1 1
-third_party/blink/perf_tests/speedometer 1 1
+third_party/blink/perf_tests/speedometer20 1 1
+third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app 1 1
+third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim 2 2
+third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib 1 1
+third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight 3 2
+third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery 2 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular 2 2
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular 36 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist 9 2
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/assets 8 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director 1 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/handlebars/dist 1 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/jquery/dist 8 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/js 2 2
+third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js 1 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist 2 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs 1 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director 6 1
+third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react 1 1
 third_party/blink/perf_tests/speedometer21 1 1
 third_party/blink/perf_tests/speedometer21/resources/flightjs-example-app 1 1
 third_party/blink/perf_tests/speedometer21/resources/flightjs-example-app/components/es5-shim 2 2
@@ -313,24 +331,6 @@
 third_party/blink/perf_tests/speedometer21/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs 1 1
 third_party/blink/perf_tests/speedometer21/resources/todomvc/labs/architecture-examples/react/bower_components/director 6 1
 third_party/blink/perf_tests/speedometer21/resources/todomvc/labs/architecture-examples/react/bower_components/react 1 1
-third_party/blink/perf_tests/speedometer/resources/flightjs-example-app 1 1
-third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim 2 2
-third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib 1 1
-third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight 3 2
-third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery 2 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular 2 2
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular 36 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist 9 2
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/assets 8 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director 1 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/handlebars/dist 1 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/jquery/dist 8 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/js 2 2
-third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js 1 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist 2 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs 1 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director 6 1
-third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react 1 1
 third_party/blink/public/common/fenced_frame 1 1
 third_party/blink/public/common/permissions_policy 1 1
 third_party/blink/public/common/storage_key 1 1
diff --git a/ios/build/chrome_build.gni b/ios/build/chrome_build.gni
index 53929b9..5e7abb5 100644
--- a/ios/build/chrome_build.gni
+++ b/ios/build/chrome_build.gni
@@ -32,7 +32,7 @@
   ios_enable_lockscreen_widget = true
 
   # Enable iOS shortcut widget in WidgetKit extension.
-  ios_enable_shortcuts_widget = true
+  ios_enable_shortcuts_widget = false
 
   # Label of the target providing implementation for AccountVerificationProvider.
   # Overridden when using the Google-internal repository to build Chrome on iOS.
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm
index 612d272..f7a3f2d 100644
--- a/ios/chrome/app/application_delegate/app_state.mm
+++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -614,6 +614,7 @@
   if (level >= SceneActivationLevelForegroundActive) {
     sceneState.presentingModalOverlay =
         (self.uiBlockerTarget != nil) && (self.uiBlockerTarget != sceneState);
+    [self.observers appState:self sceneDidBecomeActive:sceneState];
   }
   crash_keys::SetForegroundScenesCount([self foregroundScenes].count);
 }
diff --git a/ios/chrome/app/application_delegate/app_state_observer.h b/ios/chrome/app/application_delegate/app_state_observer.h
index 5c5ce50e..802976f 100644
--- a/ios/chrome/app/application_delegate/app_state_observer.h
+++ b/ios/chrome/app/application_delegate/app_state_observer.h
@@ -85,6 +85,11 @@
 - (void)appState:(AppState*)appState
     didTransitionFromInitStage:(InitStage)previousInitStage;
 
+// Called when Scene with activation level SceneActivationLevelForegroundActive
+// is available.
+- (void)appState:(AppState*)appState
+    sceneDidBecomeActive:(SceneState*)sceneState;
+
 @end
 
 #endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_APP_STATE_OBSERVER_H_
diff --git a/ios/chrome/browser/bookmarks/bookmark_ios_unit_test_support.h b/ios/chrome/browser/bookmarks/bookmark_ios_unit_test_support.h
index a424663..d4d9ca27 100644
--- a/ios/chrome/browser/bookmarks/bookmark_ios_unit_test_support.h
+++ b/ios/chrome/browser/bookmarks/bookmark_ios_unit_test_support.h
@@ -52,8 +52,8 @@
   IOSChromeScopedTestingLocalState local_state_;
   std::unique_ptr<Browser> browser_;
   std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
-  // Bookmark model for the profile storage.
-  bookmarks::BookmarkModel* profile_bookmark_model_;
+  // Bookmark model for the LocalOrSyncable storage.
+  bookmarks::BookmarkModel* local_or_syncable_bookmark_model_;
   // Bookmark model for the account storage.
   bookmarks::BookmarkModel* account_bookmark_model_;
   bookmarks::ManagedBookmarkService* managed_bookmark_service_;
diff --git a/ios/chrome/browser/bookmarks/bookmark_ios_unit_test_support.mm b/ios/chrome/browser/bookmarks/bookmark_ios_unit_test_support.mm
index 17f3463..f0517c2 100644
--- a/ios/chrome/browser/bookmarks/bookmark_ios_unit_test_support.mm
+++ b/ios/chrome/browser/bookmarks/bookmark_ios_unit_test_support.mm
@@ -49,10 +49,11 @@
       chrome_browser_state_.get(),
       std::make_unique<FakeAuthenticationServiceDelegate>());
 
-  profile_bookmark_model_ =
+  local_or_syncable_bookmark_model_ =
       ios::LocalOrSyncableBookmarkModelFactory::GetForBrowserState(
           chrome_browser_state_.get());
-  bookmarks::test::WaitForBookmarkModelToLoad(profile_bookmark_model_);
+  bookmarks::test::WaitForBookmarkModelToLoad(
+      local_or_syncable_bookmark_model_);
   account_bookmark_model_ =
       ios::AccountBookmarkModelFactory::GetForBrowserState(
           chrome_browser_state_.get());
@@ -92,8 +93,8 @@
 
 bookmarks::BookmarkModel* BookmarkIOSUnitTestSupport::GetBookmarkModelForNode(
     const BookmarkNode* node) {
-  if (node->HasAncestor(profile_bookmark_model_->root_node())) {
-    return profile_bookmark_model_;
+  if (node->HasAncestor(local_or_syncable_bookmark_model_->root_node())) {
+    return local_or_syncable_bookmark_model_;
   }
   DCHECK(account_bookmark_model_ &&
          node->HasAncestor(account_bookmark_model_->root_node()));
diff --git a/ios/chrome/browser/bookmarks/bookmark_model_bridge_observer_unittest.mm b/ios/chrome/browser/bookmarks/bookmark_model_bridge_observer_unittest.mm
index 195ad2f..7af0d34 100644
--- a/ios/chrome/browser/bookmarks/bookmark_model_bridge_observer_unittest.mm
+++ b/ios/chrome/browser/bookmarks/bookmark_model_bridge_observer_unittest.mm
@@ -113,15 +113,16 @@
 TEST_F(BookmarkModelBridgeObserverTest,
        NotifyBookmarkNodeChildrenChangedDespiteSelfDestruction) {
   @autoreleasepool {
-    const BookmarkNode* mobile_node = profile_bookmark_model_->mobile_node();
+    const BookmarkNode* mobile_node =
+        local_or_syncable_bookmark_model_->mobile_node();
     const BookmarkNode* folder = AddFolder(mobile_node, u"title");
 
     TestBookmarkModelBridgeOwner* owner = [[TestBookmarkModelBridgeOwner alloc]
-        initWithModel:profile_bookmark_model_
+        initWithModel:local_or_syncable_bookmark_model_
              observer:[[TestBookmarkModelBridgeObserver alloc] init]];
 
     // Deleting the folder should not cause a crash.
-    profile_bookmark_model_->Remove(
+    local_or_syncable_bookmark_model_->Remove(
         folder, bookmarks::metrics::BookmarkEditSource::kOther);
 
     EXPECT_TRUE([owner bookmarkNodeDeletedCalled]);
diff --git a/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.h b/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.h
index f86dc4b..d1e3544f 100644
--- a/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.h
+++ b/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.h
@@ -42,15 +42,16 @@
   UIBackgroundFetchResult HandleNotificationReception(
       NSDictionary<NSString*, id>* notification) override;
   NSArray<UNNotificationCategory*>* RegisterActionableNotifications() override;
-  void OnBrowserReady() override;
+  void OnSceneActiveForegroundBrowserReady() override;
 
  private:
   friend class ::CommercePushNotificationClientTest;
 
   commerce::ShoppingService* GetShoppingService();
   bookmarks::BookmarkModel* GetBookmarkModel();
-  // Returns the first active browser found
-  Browser* GetActiveBrowser();
+  // Returns the first active browser found with scene level
+  // SceneActivationLevelForegroundActive.
+  Browser* GetSceneLevelForegroundActiveBrowser();
 
   std::vector<const std::string> urls_delayed_for_loading_;
 
diff --git a/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.mm b/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.mm
index 7d89ae3..7a71a71 100644
--- a/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.mm
+++ b/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client.mm
@@ -89,11 +89,11 @@
                      options:UNNotificationCategoryOptionNone] ];
 }
 
-void CommercePushNotificationClient::OnBrowserReady() {
+void CommercePushNotificationClient::OnSceneActiveForegroundBrowserReady() {
   if (!urls_delayed_for_loading_.size()) {
     return;
   }
-  Browser* browser = GetActiveBrowser();
+  Browser* browser = GetSceneLevelForegroundActiveBrowser();
   CHECK(browser);
   for (const std::string& url : urls_delayed_for_loading_) {
     UrlLoadParams params = UrlLoadParams::InNewTab(GURL(url));
@@ -113,18 +113,12 @@
       GetLastUsedBrowserState());
 }
 
-Browser* CommercePushNotificationClient::GetActiveBrowser() {
+Browser*
+CommercePushNotificationClient::GetSceneLevelForegroundActiveBrowser() {
   BrowserList* browser_list =
       BrowserListFactory::GetForBrowserState(GetLastUsedBrowserState());
-  // Ideally we want a foregrounded active browser, but in the event we can't
-  // find one (e.g. notification was tapped when app was closed and app is
-  // currently opening), we fallback to the first active browser seen.
-  Browser* fallback_active_browser = nullptr;
   for (Browser* browser : browser_list->AllRegularBrowsers()) {
     if (!browser->IsInactive()) {
-      if (!fallback_active_browser) {
-        fallback_active_browser = browser;
-      }
       SceneStateBrowserAgent* scene_state_browser_agent =
           SceneStateBrowserAgent::FromBrowser(browser);
       if (scene_state_browser_agent &&
@@ -135,9 +129,6 @@
       }
     }
   }
-  if (fallback_active_browser) {
-    return fallback_active_browser;
-  }
   return nullptr;
 }
 
@@ -168,7 +159,7 @@
     // TODO(crbug.com/1403190) implement alternate Open URL handler which
     // attempts to find if a Tab with the URL already exists and switch
     // to that Tab.
-    Browser* browser = GetActiveBrowser();
+    Browser* browser = GetSceneLevelForegroundActiveBrowser();
     if (!browser) {
       urls_delayed_for_loading_.push_back(
           price_drop_notification.destination_url());
diff --git a/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client_unittest.mm b/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client_unittest.mm
index 3c400b75..a61f16c 100644
--- a/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client_unittest.mm
+++ b/ios/chrome/browser/commerce/push_notification/commerce_push_notification_client_unittest.mm
@@ -210,10 +210,13 @@
     return commerce_push_notification_client_.urls_delayed_for_loading_;
   }
 
-  void OnBrowserReady() { commerce_push_notification_client_.OnBrowserReady(); }
+  void OnSceneActiveForegroundBrowserReady() {
+    commerce_push_notification_client_.OnSceneActiveForegroundBrowserReady();
+  }
 
-  Browser* GetCommercePushClientActiveBrowser() {
-    return commerce_push_notification_client_.GetActiveBrowser();
+  Browser* GetSceneLevelForegroundActiveBrowser() {
+    return commerce_push_notification_client_
+        .GetSceneLevelForegroundActiveBrowser();
   }
 
  protected:
@@ -321,7 +324,7 @@
   CommercePushNotificationClient* commerce_push_notification_client =
       GetCommercePushNotificationClient();
   browser_list_->AddBrowser(GetBrowser());
-  commerce_push_notification_client->OnBrowserReady();
+  commerce_push_notification_client->OnSceneActiveForegroundBrowserReady();
   EXPECT_EQ(0u, GetUrlsDelayedForLoading().size());
 
   // Check PriceDropNotification Destination URL loaded.
@@ -334,7 +337,7 @@
 TEST_F(CommercePushNotificationClientTest,
        TestBackgroundBrowserNotUsedWhenForegroundAvailable) {
   browser_list_->AddBrowser(GetBackgroundBrowser());
-  Browser* browser = GetCommercePushClientActiveBrowser();
+  Browser* browser = GetSceneLevelForegroundActiveBrowser();
   // When active foregrounded and active backgrounded browser is availalbe,
   // should choose foregrounded browser.
   EXPECT_EQ(SceneActivationLevelForegroundActive,
@@ -348,10 +351,6 @@
   browser_list_->RemoveBrowser(GetBrowser());
   // Add backgrounded browser
   browser_list_->AddBrowser(GetBackgroundBrowser());
-  Browser* browser = GetCommercePushClientActiveBrowser();
-  // Only option is backgronuded browser
-  EXPECT_EQ(SceneActivationLevelBackground,
-            SceneStateBrowserAgent::FromBrowser(browser)
-                ->GetSceneState()
-                .activationLevel);
+  // Background browser not used.
+  EXPECT_EQ(nullptr, GetSceneLevelForegroundActiveBrowser());
 }
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index acf8ff1..90494a4f 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -1434,6 +1434,9 @@
      flag_descriptions::kEnableFollowManagementInstantReloadDescription,
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kEnableFollowManagementInstantReload)},
+    {"enable-follow-ui-update", flag_descriptions::kEnableFollowUIUpdateName,
+     flag_descriptions::kEnableFollowUIUpdateDescription, flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(kEnableFollowUIUpdate)},
     {"mixed-content-autoupgrade-ios",
      flag_descriptions::kMixedContentAutoupgradeName,
      flag_descriptions::kMixedContentAutoupgradeDescription, flags_ui::kOsIos,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 42655af..c2f334c 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -364,6 +364,10 @@
 const char kEnableFollowManagementInstantReloadDescription[] =
     "Enable follow management page instant reloading when being opened.";
 
+const char kEnableFollowUIUpdateName[] = "Enable the Follow UI Update";
+const char kEnableFollowUIUpdateDescription[] =
+    "Enable Follow UI Update for the Feed.";
+
 const char kPasswordsGroupingName[] =
     "Enable password grouping for the Password Manager";
 const char kPasswordsGroupingDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index fb3c89b..3aeb28f 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -277,6 +277,10 @@
 extern const char kEnableFollowManagementInstantReloadName[];
 extern const char kEnableFollowManagementInstantReloadDescription[];
 
+// Title and description for the flag to enable the Follow UI Updates.
+extern const char kEnableFollowUIUpdateName[];
+extern const char kEnableFollowUIUpdateDescription[];
+
 // Title and description for the flag to enable kEditPasswordsInSettings flag on
 // iOS.
 extern const char kEditPasswordsInSettingsName[];
diff --git a/ios/chrome/browser/ntp/features.h b/ios/chrome/browser/ntp/features.h
index 2da56fe..2af2fa8 100644
--- a/ios/chrome/browser/ntp/features.h
+++ b/ios/chrome/browser/ntp/features.h
@@ -56,6 +56,9 @@
 // Feature flag to disable Discover-controlled foregrounding refreshes.
 BASE_DECLARE_FEATURE(kFeedDisableHotStartRefresh);
 
+// Feature flag to enable the Follow UI update.
+BASE_DECLARE_FEATURE(kEnableFollowUIUpdate);
+
 // Feature param under `kEnableFeedBackgroundRefresh` to also enable background
 // refresh for the Following feed.
 extern const char kEnableFollowingFeedBackgroundRefresh[];
@@ -241,4 +244,7 @@
 // Whether Discover-controlled foregrounding refreshes are disabled.
 bool IsFeedHotStartRefreshDisabled();
 
+// YES when Follow UI Update is enabled.
+bool IsFollowUIUpdateEnabled();
+
 #endif  // IOS_CHROME_BROWSER_NTP_FEATURES_H_
diff --git a/ios/chrome/browser/ntp/features.mm b/ios/chrome/browser/ntp/features.mm
index 1d2485f..9c15964e 100644
--- a/ios/chrome/browser/ntp/features.mm
+++ b/ios/chrome/browser/ntp/features.mm
@@ -84,6 +84,10 @@
              "FeedDisableHotStartRefresh",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+BASE_FEATURE(kEnableFollowUIUpdate,
+             "EnableFollowUIUpdate",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 // Key for NSUserDefaults containing a bool indicating whether the next run
 // should enable feed background refresh capability. This is used because
 // registering for background refreshes must happen early in app initialization
@@ -353,3 +357,7 @@
 bool IsFeedHotStartRefreshDisabled() {
   return base::FeatureList::IsEnabled(kFeedDisableHotStartRefresh);
 }
+
+bool IsFollowUIUpdateEnabled() {
+  return base::FeatureList::IsEnabled(kEnableFollowUIUpdate);
+}
diff --git a/ios/chrome/browser/optimization_guide/optimization_guide_push_notification_client_unittest.mm b/ios/chrome/browser/optimization_guide/optimization_guide_push_notification_client_unittest.mm
index 503177f..c8dc435dc 100644
--- a/ios/chrome/browser/optimization_guide/optimization_guide_push_notification_client_unittest.mm
+++ b/ios/chrome/browser/optimization_guide/optimization_guide_push_notification_client_unittest.mm
@@ -59,7 +59,7 @@
   }
   void HandleNotificationInteraction(
       UNNotificationResponse* notification) override {}
-  void OnBrowserReady() override {}
+  void OnSceneActiveForegroundBrowserReady() override {}
 };
 
 class OptimizationGuidePushNotificationClientTest : public PlatformTest {
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
index e019ca2e..86892eb 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
@@ -139,6 +139,7 @@
   scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
   password_manager::PasswordRequirementsService*
   GetPasswordRequirementsService() override;
+  void UpdateFormManagers() override;
   bool IsIsolationForPasswordSitesEnabled() const override;
   bool IsNewTabPage() const override;
   password_manager::FieldInfoManager* GetFieldInfoManager() const override;
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
index d18f15eb..b2b1b13 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
@@ -319,6 +319,10 @@
       bridge_.browserState, ServiceAccessType::EXPLICIT_ACCESS);
 }
 
+void IOSChromePasswordManagerClient::UpdateFormManagers() {
+  bridge_.passwordManager->UpdateFormManagers();
+}
+
 bool IOSChromePasswordManagerClient::IsIsolationForPasswordSitesEnabled()
     const {
   return false;
diff --git a/ios/chrome/browser/push_notification/push_notification_client.h b/ios/chrome/browser/push_notification/push_notification_client.h
index d522f995..98fa4a60 100644
--- a/ios/chrome/browser/push_notification/push_notification_client.h
+++ b/ios/chrome/browser/push_notification/push_notification_client.h
@@ -40,8 +40,13 @@
   virtual NSArray<UNNotificationCategory*>*
   RegisterActionableNotifications() = 0;
 
-  // Signals to the client that a browser is ready.
-  virtual void OnBrowserReady() = 0;
+  // Signals to the client that a browser with scene level
+  // SceneActivationLevelForegroundActive is ready. Without this
+  // URL opening code driven by push notifications may not be able to
+  // access a browser appropriate for opening a URL (active & scene
+  // level SceneActivationLevelForegroundActive) resulting in the URL
+  // not being opened.
+  virtual void OnSceneActiveForegroundBrowserReady() = 0;
 
   // Returns the feature's `client_id_`.
   PushNotificationClientId GetClientId();
diff --git a/ios/chrome/browser/push_notification/push_notification_client_manager.h b/ios/chrome/browser/push_notification/push_notification_client_manager.h
index 786d154..91e6fb11 100644
--- a/ios/chrome/browser/push_notification/push_notification_client_manager.h
+++ b/ios/chrome/browser/push_notification/push_notification_client_manager.h
@@ -71,8 +71,13 @@
   static std::string PushNotificationClientIdToString(
       PushNotificationClientId client_id);
 
-  // Signals to client manager that a browser is ready.
-  void OnBrowserReady();
+  // Signals to client manager that a browser with scene level
+  // SceneActivationLevelForegroundActive is ready. Without this
+  // URL opening code driven by push notifications may not be able to
+  // access a browser appropriate for opening a URL (active & scene
+  // level SceneActivationLevelForegroundActive) resulting in the URL
+  // not being opened.
+  void OnSceneActiveForegroundBrowserReady();
 
  private:
   using ClientMap = std::unordered_map<PushNotificationClientId,
diff --git a/ios/chrome/browser/push_notification/push_notification_client_manager.mm b/ios/chrome/browser/push_notification/push_notification_client_manager.mm
index de0cbb2..2125863 100644
--- a/ios/chrome/browser/push_notification/push_notification_client_manager.mm
+++ b/ios/chrome/browser/push_notification/push_notification_client_manager.mm
@@ -90,9 +90,9 @@
   return {PushNotificationClientId::kCommerce};
 }
 
-void PushNotificationClientManager::OnBrowserReady() {
+void PushNotificationClientManager::OnSceneActiveForegroundBrowserReady() {
   for (auto& client : clients_) {
-    client.second->OnBrowserReady();
+    client.second->OnSceneActiveForegroundBrowserReady();
   }
 }
 
diff --git a/ios/chrome/browser/push_notification/push_notification_client_manager_unittest.mm b/ios/chrome/browser/push_notification/push_notification_client_manager_unittest.mm
index 5e7563467a..1e5814755 100644
--- a/ios/chrome/browser/push_notification/push_notification_client_manager_unittest.mm
+++ b/ios/chrome/browser/push_notification/push_notification_client_manager_unittest.mm
@@ -125,6 +125,6 @@
 TEST_F(PushNotificationClientManagerTest, BrowserReady) {
   GenerateClients(manager, 1);
   EXPECT_FALSE(GetClient(manager, 0)->IsBrowserReady());
-  manager->OnBrowserReady();
+  manager->OnSceneActiveForegroundBrowserReady();
   EXPECT_TRUE(GetClient(manager, 0)->IsBrowserReady());
 }
diff --git a/ios/chrome/browser/push_notification/push_notification_delegate.mm b/ios/chrome/browser/push_notification/push_notification_delegate.mm
index d135167..33bd0477 100644
--- a/ios/chrome/browser/push_notification/push_notification_delegate.mm
+++ b/ios/chrome/browser/push_notification/push_notification_delegate.mm
@@ -182,9 +182,8 @@
 }
 
 #pragma mark - AppStateObserver
-
 - (void)appState:(AppState*)appState
-    didTransitionFromInitStage:(InitStage)previousInitStage {
+    sceneDidBecomeActive:(SceneState*)sceneState {
   if (appState.initStage < InitStageFinal) {
     return;
   }
@@ -193,8 +192,7 @@
           ->GetPushNotificationService()
           ->GetPushNotificationClientManager();
   DCHECK(clientManager);
-  clientManager->OnBrowserReady();
-  [appState removeObserver:self];
+  clientManager->OnSceneActiveForegroundBrowserReady();
 }
 
 @end
diff --git a/ios/chrome/browser/push_notification/test_push_notification_client.h b/ios/chrome/browser/push_notification/test_push_notification_client.h
index c48cb50..57fd069 100644
--- a/ios/chrome/browser/push_notification/test_push_notification_client.h
+++ b/ios/chrome/browser/push_notification/test_push_notification_client.h
@@ -23,7 +23,7 @@
   bool HasNotificationReceivedInteraction();
   // Sets the client's UIBackgroundFetchResult to given FetchResult.
   void SetBackgroundFetchResult(UIBackgroundFetchResult result);
-  void OnBrowserReady() override;
+  void OnSceneActiveForegroundBrowserReady() override;
   bool IsBrowserReady();
 
  private:
diff --git a/ios/chrome/browser/push_notification/test_push_notification_client.mm b/ios/chrome/browser/push_notification/test_push_notification_client.mm
index b8de98a..783f18e 100644
--- a/ios/chrome/browser/push_notification/test_push_notification_client.mm
+++ b/ios/chrome/browser/push_notification/test_push_notification_client.mm
@@ -40,7 +40,7 @@
   fetch_result_ = result;
 }
 
-void TestPushNotificationClient::OnBrowserReady() {
+void TestPushNotificationClient::OnSceneActiveForegroundBrowserReady() {
   is_browser_ready_ = true;
 }
 
diff --git a/ios/chrome/browser/shared/public/features/features.mm b/ios/chrome/browser/shared/public/features/features.mm
index f1cda14..e37a517 100644
--- a/ios/chrome/browser/shared/public/features/features.mm
+++ b/ios/chrome/browser/shared/public/features/features.mm
@@ -188,7 +188,7 @@
 
 BASE_FEATURE(kMultilineFadeTruncatingLabel,
              "MultilineFadeTruncatingLabel",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 BASE_FEATURE(kNotificationSettingsMenuItem,
              "NotificationSettingsMenuItem",
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h b/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h
index f86efef..71b1235 100644
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h
+++ b/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h
@@ -13,8 +13,6 @@
 // Class that configures a SigninPromoView instance.
 @interface SigninPromoViewConfigurator : NSObject
 
-- (instancetype)init NS_UNAVAILABLE;
-
 // Initializes the instance.
 // If `viewMode` is SigninPromoViewModeNoAccounts, then `userEmail`,
 // `userGivenName` and `userImage` have to be nil.
@@ -31,6 +29,11 @@
                              hasCloseButton:(BOOL)hasCloseButton
                            hasSignInSpinner:(BOOL)hasSignInSpinner
     NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+
+// Overrides the primary button title in signin promo when there are no
+// accounts. If unset/`nil` the default text is used.
+@property(nonatomic, copy) NSString* primaryButtonTitleNoAccountsModeOverride;
 
 // Configure `signinPromoView` with the given `promoViewStyle` style.
 - (void)configureSigninPromoView:(SigninPromoView*)signinPromoView
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.mm b/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.mm
index ec913504..6f43862f 100644
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.mm
+++ b/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.mm
@@ -113,7 +113,10 @@
     case SigninPromoViewModeNoAccounts: {
       DCHECK(!name);
       DCHECK(!self.userImage);
-      NSString* signInString = GetNSString(IDS_IOS_SYNC_PROMO_TURN_ON_SYNC);
+      NSString* signInString =
+          self.primaryButtonTitleNoAccountsModeOverride
+              ? self.primaryButtonTitleNoAccountsModeOverride
+              : GetNSString(IDS_IOS_SYNC_PROMO_TURN_ON_SYNC);
       [signinPromoView configurePrimaryButtonWithTitle:signInString];
       break;
     }
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
index ff782369..53bd94f0 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -682,13 +682,19 @@
                      hasCloseButton:hasCloseButton
                    hasSignInSpinner:self.signinInProgress];
   }
-  return [[SigninPromoViewConfigurator alloc]
-      initWithSigninPromoViewMode:SigninPromoViewModeNoAccounts
-                        userEmail:nil
-                    userGivenName:nil
-                        userImage:nil
-                   hasCloseButton:hasCloseButton
-                 hasSignInSpinner:self.signinInProgress];
+  SigninPromoViewConfigurator* configurator =
+      [[SigninPromoViewConfigurator alloc]
+          initWithSigninPromoViewMode:SigninPromoViewModeNoAccounts
+                            userEmail:nil
+                        userGivenName:nil
+                            userImage:nil
+                       hasCloseButton:hasCloseButton
+                     hasSignInSpinner:self.signinInProgress];
+  if (self.signInOnly) {
+    configurator.primaryButtonTitleNoAccountsModeOverride =
+        l10n_util::GetNSString(IDS_IOS_CONSISTENCY_PROMO_SIGN_IN);
+  }
+  return configurator;
 }
 
 - (void)signinPromoViewIsVisible {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_mediator_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_mediator_unittest.mm
index 006edead..589fc8c 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_mediator_unittest.mm
@@ -81,7 +81,7 @@
     sync_setup_service_ = std::make_unique<FakeSyncSetupService>(sync_service_);
 
     mediator_ = [[BookmarkMediator alloc]
-        initWithWithProfileBookmarkModel:profile_bookmark_model_
+        initWithWithProfileBookmarkModel:local_or_syncable_bookmark_model_
                     accountBookmarkModel:nullptr
                                    prefs:chrome_browser_state_->GetPrefs()
                    authenticationService:authentication_service_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_path_cache_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_path_cache_unittest.mm
index 8fb2e48..8d54b3b7 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_path_cache_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_path_cache_unittest.mm
@@ -32,7 +32,8 @@
 
 TEST_F(BookmarkPathCacheTest, TestPathCache) {
   // Try to store and retrieve a cache.
-  const BookmarkNode* mobile_node = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobile_node =
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* f1 = AddFolder(mobile_node, u"f1");
   int64_t folder_id = f1->id();
   int topmost_row = 23;
@@ -44,7 +45,8 @@
   int result_topmost_row;
   [BookmarkPathCache
       getBookmarkTopMostRowCacheWithPrefService:&prefs_
-                                          model:profile_bookmark_model_
+                                          model:
+                                              local_or_syncable_bookmark_model_
                                        folderId:&result_folder_id
                                      topMostRow:&result_topmost_row];
   EXPECT_EQ(folder_id, result_folder_id);
@@ -53,7 +55,8 @@
 
 TEST_F(BookmarkPathCacheTest, TestPathCacheWhenFolderDeleted) {
   // Try to store and retrieve a cache after the cached path is deleted.
-  const BookmarkNode* mobile_node = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobile_node =
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* f1 = AddFolder(mobile_node, u"f1");
   int64_t folder_id = f1->id();
   int topmost_row = 23;
@@ -62,14 +65,15 @@
                                                  topMostRow:topmost_row];
 
   // Delete the folder.
-  profile_bookmark_model_->Remove(
+  local_or_syncable_bookmark_model_->Remove(
       f1, bookmarks::metrics::BookmarkEditSource::kOther);
 
   int64_t unused_folder_id;
   int unused_topmost_row;
   BOOL result = [BookmarkPathCache
       getBookmarkTopMostRowCacheWithPrefService:&prefs_
-                                          model:profile_bookmark_model_
+                                          model:
+                                              local_or_syncable_bookmark_model_
                                        folderId:&unused_folder_id
                                      topMostRow:&unused_topmost_row];
   ASSERT_FALSE(result);
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
index bd8c57e..30901d77 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
@@ -168,7 +168,8 @@
     const GURL& url,
     const bookmarks::BookmarkNode* folder,
     int position,
-    bookmarks::BookmarkModel* bookmark_model,
+    bookmarks::BookmarkModel* local_or_syncable_model,
+    bookmarks::BookmarkModel* account_model,
     ChromeBrowserState* browser_state);
 
 // Updates a bookmark node position, and returns a snackbar with an undo action.
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
index 0f25b923..828d8ff 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
@@ -362,7 +362,8 @@
     const GURL& url,
     const bookmarks::BookmarkNode* folder,
     int position,
-    bookmarks::BookmarkModel* bookmark_model,
+    bookmarks::BookmarkModel* local_or_syncable_model,
+    bookmarks::BookmarkModel* account_model,
     ChromeBrowserState* browser_state) {
   std::u16string titleString = base::SysNSStringToUTF16(title);
 
@@ -371,9 +372,11 @@
   [wrapper startGroupingActions];
 
   base::RecordAction(base::UserMetricsAction("BookmarkAdded"));
-  const bookmarks::BookmarkNode* node = bookmark_model->AddNewURL(
+  bookmarks::BookmarkModel* folder_model =
+      GetBookmarkModelForNode(folder, local_or_syncable_model, account_model);
+  const bookmarks::BookmarkNode* node = folder_model->AddNewURL(
       folder, folder->children().size(), titleString, url);
-  bookmark_model->Move(node, folder, position);
+  folder_model->Move(node, folder, position);
 
   [wrapper stopGroupingActions];
   [wrapper resetUndoManagerChanged];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
index d1289cee5..069fbf7 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
@@ -70,7 +70,8 @@
     to_move.insert(f2b);
     to_move.insert(f2);
 
-    bookmark_utils_ios::MoveBookmarks(to_move, profile_bookmark_model_,
+    bookmark_utils_ios::MoveBookmarks(to_move,
+                                      local_or_syncable_bookmark_model_,
                                       account_bookmark_model_, f1);
     EXPECT_THAT(GetBookmarkTitles(parent_folder->children()),
                 ::testing::UnorderedElementsAre(u"f1", u"b"));
@@ -83,7 +84,8 @@
 };
 
 TEST_P(BookmarkIOSUtilsUnitTest, CreateOrUpdateNoop) {
-  const BookmarkNode* mobile_node = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobile_node =
+      local_or_syncable_bookmark_model_->mobile_node();
   std::u16string title = u"title";
   const BookmarkNode* node = AddBookmark(mobile_node, title);
 
@@ -91,19 +93,20 @@
   // This call is a no-op, , so `CreateOrUpdateBookmark` should return `false`.
   EXPECT_FALSE(bookmark_utils_ios::CreateOrUpdateBookmark(
       node, base::SysUTF16ToNSString(title), url_copy, mobile_node,
-      profile_bookmark_model_, account_bookmark_model_));
+      local_or_syncable_bookmark_model_, account_bookmark_model_));
   EXPECT_EQ(node->GetTitle(), title);
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, CreateOrUpdateWithinModel) {
-  const BookmarkNode* mobile_node = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobile_node =
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* node = AddBookmark(mobile_node, u"a");
   const BookmarkNode* folder = AddFolder(mobile_node, u"f1");
 
   NSString* new_title = @"b";
   GURL new_url("http://example.com");
   EXPECT_TRUE(bookmark_utils_ios::CreateOrUpdateBookmark(
-      node, new_title, new_url, folder, profile_bookmark_model_,
+      node, new_title, new_url, folder, local_or_syncable_bookmark_model_,
       account_bookmark_model_));
 
   ASSERT_THAT(mobile_node->children(),
@@ -121,7 +124,7 @@
     GTEST_SKIP() << "Need account storage to move bookmarks between storages";
   }
   const BookmarkNode* local_or_syncable_mobile_node =
-      profile_bookmark_model_->mobile_node();
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* node = AddBookmark(local_or_syncable_mobile_node, u"a");
   const BookmarkNode* account_mobile_node =
       account_bookmark_model_->mobile_node();
@@ -129,8 +132,8 @@
   NSString* new_title = @"b";
   GURL new_url("http://example.com");
   EXPECT_TRUE(bookmark_utils_ios::CreateOrUpdateBookmark(
-      node, new_title, new_url, account_mobile_node, profile_bookmark_model_,
-      account_bookmark_model_));
+      node, new_title, new_url, account_mobile_node,
+      local_or_syncable_bookmark_model_, account_bookmark_model_));
 
   EXPECT_THAT(local_or_syncable_mobile_node->children(), testing::IsEmpty());
   ASSERT_THAT(account_mobile_node->children(), testing::SizeIs(1));
@@ -140,7 +143,8 @@
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, DeleteNodes) {
-  const BookmarkNode* mobileNode = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobileNode =
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* f1 = AddFolder(mobileNode, u"f1");
   const BookmarkNode* a = AddBookmark(mobileNode, u"a");
   const BookmarkNode* b = AddBookmark(mobileNode, u"b");
@@ -157,7 +161,8 @@
   toDelete.insert(f2b);
   toDelete.insert(f2);
 
-  bookmark_utils_ios::DeleteBookmarks(toDelete, profile_bookmark_model_);
+  bookmark_utils_ios::DeleteBookmarks(toDelete,
+                                      local_or_syncable_bookmark_model_);
 
   EXPECT_EQ(2u, mobileNode->children().size());
   const BookmarkNode* child0 = mobileNode->children()[0].get();
@@ -170,7 +175,7 @@
 
 TEST_P(BookmarkIOSUtilsUnitTest, MoveNodesInLocalOrSyncableModel) {
   const BookmarkNode* local_or_syncable_mobile_node =
-      profile_bookmark_model_->mobile_node();
+      local_or_syncable_bookmark_model_->mobile_node();
   ASSERT_NO_FATAL_FAILURE(TestMovingBookmarks(local_or_syncable_mobile_node));
 }
 
@@ -188,7 +193,7 @@
     GTEST_SKIP() << "Need account storage to move bookmarks between storages";
   }
   const BookmarkNode* local_or_syncable_mobile_node =
-      profile_bookmark_model_->mobile_node();
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* f1 = AddFolder(local_or_syncable_mobile_node, u"f1");
   AddBookmark(local_or_syncable_mobile_node, u"a");
   const BookmarkNode* b = AddBookmark(local_or_syncable_mobile_node, u"b");
@@ -207,7 +212,7 @@
   to_move.insert(b);    // Cross-storage move, the parent is not moved.
   to_move.insert(c);    // Same-storage move.
 
-  bookmark_utils_ios::MoveBookmarks(to_move, profile_bookmark_model_,
+  bookmark_utils_ios::MoveBookmarks(to_move, local_or_syncable_bookmark_model_,
                                     account_bookmark_model_, f2);
 
   EXPECT_THAT(GetBookmarkTitles(local_or_syncable_mobile_node->children()),
@@ -227,10 +232,11 @@
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, TestCreateBookmarkPath) {
-  const BookmarkNode* mobileNode = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobileNode =
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* f1 = AddFolder(mobileNode, u"f1");
-  NSArray<NSNumber*>* path =
-      bookmark_utils_ios::CreateBookmarkPath(profile_bookmark_model_, f1->id());
+  NSArray<NSNumber*>* path = bookmark_utils_ios::CreateBookmarkPath(
+      local_or_syncable_bookmark_model_, f1->id());
   NSMutableArray<NSNumber*>* expectedPath = [NSMutableArray array];
   [expectedPath addObject:@0];
   [expectedPath addObject:[NSNumber numberWithLongLong:mobileNode->id()]];
@@ -239,13 +245,14 @@
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, TestCreateNilBookmarkPath) {
-  NSArray<NSNumber*>* path =
-      bookmark_utils_ios::CreateBookmarkPath(profile_bookmark_model_, 999);
+  NSArray<NSNumber*>* path = bookmark_utils_ios::CreateBookmarkPath(
+      local_or_syncable_bookmark_model_, 999);
   EXPECT_TRUE(path == nil);
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, TestVisibleNonDescendantNodes) {
-  const BookmarkNode* mobileNode = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobileNode =
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* music = AddFolder(mobileNode, u"music");
 
   const BookmarkNode* pop = AddFolder(music, u"pop");
@@ -265,7 +272,7 @@
   const BookmarkNode* camel = AddFolder(animals, u"camel");
   AddFolder(camel, u"al paca");
 
-  AddFolder(profile_bookmark_model_->other_node(), u"buildings");
+  AddFolder(local_or_syncable_bookmark_model_->other_node(), u"buildings");
 
   std::set<const BookmarkNode*> obstructions;
   // Editing a folder and a bookmark.
@@ -273,8 +280,8 @@
   obstructions.insert(lindsey);
 
   bookmark_utils_ios::NodeVector result =
-      bookmark_utils_ios::VisibleNonDescendantNodes(obstructions,
-                                                    profile_bookmark_model_);
+      bookmark_utils_ios::VisibleNonDescendantNodes(
+          obstructions, local_or_syncable_bookmark_model_);
   ASSERT_EQ(13u, result.size());
 
   EXPECT_EQ(result[0]->GetTitle(), u"Mobile Bookmarks");
@@ -300,7 +307,8 @@
   EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1));
 
   // Empty vs vector with one element: [] - [1].
-  const BookmarkNode* mobileNode = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobileNode =
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* bookmark1 = AddBookmark(mobileNode, u"1");
   vector2.push_back(bookmark1);
   EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2));
@@ -368,7 +376,8 @@
             bookmark_utils_ios::MissingNodesIndices(vector1, vector2).size());
 
   // [] - [1].
-  const BookmarkNode* mobileNode = profile_bookmark_model_->mobile_node();
+  const BookmarkNode* mobileNode =
+      local_or_syncable_bookmark_model_->mobile_node();
   const BookmarkNode* bookmark1 = AddBookmark(mobileNode, u"1");
   vector2.push_back(bookmark1);
   std::vector<bookmark_utils_ios::NodeVector::size_type> missingNodesIndices =
@@ -458,29 +467,29 @@
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, IsBookmarkedNoMatches) {
-  AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+  AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
               GURL("http://example.com/a"));
   if (IsAccountStorageEnabled()) {
     AddBookmark(account_bookmark_model_->mobile_node(), u"b",
                 GURL("http://example.com/b"));
   }
 
-  EXPECT_FALSE(bookmark_utils_ios::IsBookmarked(GURL("http://example.com/c"),
-                                                profile_bookmark_model_,
-                                                account_bookmark_model_));
+  EXPECT_FALSE(bookmark_utils_ios::IsBookmarked(
+      GURL("http://example.com/c"), local_or_syncable_bookmark_model_,
+      account_bookmark_model_));
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, IsBookmarkedLocalMatch) {
-  AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+  AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
               GURL("http://example.com/a"));
   if (IsAccountStorageEnabled()) {
     AddBookmark(account_bookmark_model_->mobile_node(), u"b",
                 GURL("http://example.com/b"));
   }
 
-  EXPECT_TRUE(bookmark_utils_ios::IsBookmarked(GURL("http://example.com/a"),
-                                               profile_bookmark_model_,
-                                               account_bookmark_model_));
+  EXPECT_TRUE(bookmark_utils_ios::IsBookmarked(
+      GURL("http://example.com/a"), local_or_syncable_bookmark_model_,
+      account_bookmark_model_));
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, IsBookmarkedAccountMatch) {
@@ -488,14 +497,14 @@
     GTEST_SKIP() << "Need account storage to test matches in that storage";
   }
 
-  AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+  AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
               GURL("http://example.com/a"));
   AddBookmark(account_bookmark_model_->mobile_node(), u"b",
               GURL("http://example.com/b"));
 
-  EXPECT_TRUE(bookmark_utils_ios::IsBookmarked(GURL("http://example.com/b"),
-                                               profile_bookmark_model_,
-                                               account_bookmark_model_));
+  EXPECT_TRUE(bookmark_utils_ios::IsBookmarked(
+      GURL("http://example.com/b"), local_or_syncable_bookmark_model_,
+      account_bookmark_model_));
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, IsBookmarkedBothStoragesMatch) {
@@ -503,18 +512,18 @@
     GTEST_SKIP() << "Need account storage to test matches in both storages";
   }
 
-  AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+  AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
               GURL("http://example.com/a"));
   AddBookmark(account_bookmark_model_->mobile_node(), u"b",
               GURL("http://example.com/a"));
 
-  EXPECT_TRUE(bookmark_utils_ios::IsBookmarked(GURL("http://example.com/a"),
-                                               profile_bookmark_model_,
-                                               account_bookmark_model_));
+  EXPECT_TRUE(bookmark_utils_ios::IsBookmarked(
+      GURL("http://example.com/a"), local_or_syncable_bookmark_model_,
+      account_bookmark_model_));
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, GetMostRecentlyAddedNoMatchingBookmarks) {
-  AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+  AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
               GURL("http://example.com/a"));
   if (IsAccountStorageEnabled()) {
     AddBookmark(account_bookmark_model_->mobile_node(), u"b",
@@ -523,14 +532,14 @@
 
   const BookmarkNode* result =
       bookmark_utils_ios::GetMostRecentlyAddedUserNodeForURL(
-          GURL("http://example.com/c"), profile_bookmark_model_,
+          GURL("http://example.com/c"), local_or_syncable_bookmark_model_,
           account_bookmark_model_);
   EXPECT_EQ(result, nullptr);
 }
 
 TEST_P(BookmarkIOSUtilsUnitTest, GetMostRecentlyAddedMatchingLocalBookmark) {
   const BookmarkNode* local_bookmark =
-      AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+      AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
                   GURL("http://example.com/a"));
   if (IsAccountStorageEnabled()) {
     AddBookmark(account_bookmark_model_->mobile_node(), u"b",
@@ -539,7 +548,7 @@
 
   const BookmarkNode* result =
       bookmark_utils_ios::GetMostRecentlyAddedUserNodeForURL(
-          GURL("http://example.com/a"), profile_bookmark_model_,
+          GURL("http://example.com/a"), local_or_syncable_bookmark_model_,
           account_bookmark_model_);
   EXPECT_EQ(result, local_bookmark);
 }
@@ -549,7 +558,7 @@
     GTEST_SKIP() << "Need account storage to test matches in that storage";
   }
 
-  AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+  AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
               GURL("http://example.com/a"));
   const BookmarkNode* account_bookmark =
       AddBookmark(account_bookmark_model_->mobile_node(), u"b",
@@ -557,7 +566,7 @@
 
   const BookmarkNode* result =
       bookmark_utils_ios::GetMostRecentlyAddedUserNodeForURL(
-          GURL("http://example.com/b"), profile_bookmark_model_,
+          GURL("http://example.com/b"), local_or_syncable_bookmark_model_,
           account_bookmark_model_);
   EXPECT_EQ(result, account_bookmark);
 }
@@ -569,7 +578,7 @@
   }
 
   const BookmarkNode* local_bookmark =
-      AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+      AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
                   GURL("http://example.com/a"));
   const BookmarkNode* account_bookmark =
       AddBookmark(account_bookmark_model_->mobile_node(), u"b",
@@ -581,12 +590,12 @@
   // Simulate local bookmark being added after the account one.
   base::Time added_time_local_bookmark =
       added_time_account_bookmark + base::Seconds(1);
-  profile_bookmark_model_->SetDateAdded(local_bookmark,
-                                        added_time_local_bookmark);
+  local_or_syncable_bookmark_model_->SetDateAdded(local_bookmark,
+                                                  added_time_local_bookmark);
 
   const BookmarkNode* result =
       bookmark_utils_ios::GetMostRecentlyAddedUserNodeForURL(
-          GURL("http://example.com/a"), profile_bookmark_model_,
+          GURL("http://example.com/a"), local_or_syncable_bookmark_model_,
           account_bookmark_model_);
   // Local bookmark is more recent, so it should be returned.
   EXPECT_EQ(result, local_bookmark);
@@ -599,15 +608,15 @@
   }
 
   const BookmarkNode* local_bookmark =
-      AddBookmark(profile_bookmark_model_->mobile_node(), u"a",
+      AddBookmark(local_or_syncable_bookmark_model_->mobile_node(), u"a",
                   GURL("http://example.com/a"));
   const BookmarkNode* account_bookmark =
       AddBookmark(account_bookmark_model_->mobile_node(), u"b",
                   GURL("http://example.com/a"));
 
   base::Time added_time_local_bookmark = base::Time::Now();
-  profile_bookmark_model_->SetDateAdded(local_bookmark,
-                                        added_time_local_bookmark);
+  local_or_syncable_bookmark_model_->SetDateAdded(local_bookmark,
+                                                  added_time_local_bookmark);
   // Simulate account bookmark being added after the local one.
   base::Time added_time_account_bookmark =
       added_time_local_bookmark + base::Seconds(1);
@@ -616,7 +625,7 @@
 
   const BookmarkNode* result =
       bookmark_utils_ios::GetMostRecentlyAddedUserNodeForURL(
-          GURL("http://example.com/a"), profile_bookmark_model_,
+          GURL("http://example.com/a"), local_or_syncable_bookmark_model_,
           account_bookmark_model_);
   // Account bookmark is more recent, so it should be returned.
   EXPECT_EQ(result, account_bookmark);
diff --git a/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller_unittest.mm b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller_unittest.mm
index 5ffe209..28cc893 100644
--- a/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller_unittest.mm
@@ -55,10 +55,10 @@
       [[BookmarksEditorViewController alloc] initWithBrowser:browser_.get()];
 
   const bookmarks::BookmarkNode* mobile_node =
-      profile_bookmark_model_->mobile_node();
+      local_or_syncable_bookmark_model_->mobile_node();
   const bookmarks::BookmarkNode* bookmark = AddBookmark(mobile_node, u"foo");
   BookmarksEditorMediator* mediator = [[BookmarksEditorMediator alloc]
-      initWithProfileBookmarkModel:profile_bookmark_model_
+      initWithProfileBookmarkModel:local_or_syncable_bookmark_model_
               accountBookmarkModel:nullptr
                       bookmarkNode:bookmark
                              prefs:nullptr
diff --git a/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_view_controller.mm
index 5d993b42..5d5d9f5f 100644
--- a/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_view_controller.mm
@@ -2591,7 +2591,7 @@
           bookmark_utils_ios::CreateBookmarkAtPositionWithUndoToast(
               base::SysUTF8ToNSString(URL.spec()), URL,
               self.displayedFolderNode, index, _profileBookmarkModel.get(),
-              self.browserState)];
+              _accountBookmarkModel.get(), self.browserState)];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_view_controller_unittest.mm b/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_view_controller_unittest.mm
index 2412040..eb69a2a7 100644
--- a/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_view_controller_unittest.mm
@@ -67,7 +67,7 @@
     controller.snackbarCommandsHandler = mockSnackbarCommandHandler;
 
     const bookmarks::BookmarkNode* mobileNode =
-        profile_bookmark_model_->mobile_node();
+        local_or_syncable_bookmark_model_->mobile_node();
     AddBookmark(mobileNode, u"foo");
     controller.displayedFolderNode = mobileNode;
     // sections: Bookmarks, root profile, root account, message.
@@ -124,9 +124,9 @@
     controller.snackbarCommandsHandler = mockSnackbarCommandHandler;
 
     const bookmarks::BookmarkNode* rootNode =
-        profile_bookmark_model_->root_node();
+        local_or_syncable_bookmark_model_->root_node();
     const bookmarks::BookmarkNode* mobileNode =
-        profile_bookmark_model_->mobile_node();
+        local_or_syncable_bookmark_model_->mobile_node();
     AddBookmark(mobileNode, u"foo");  // Ensure there are bookmarks
     controller.displayedFolderNode = rootNode;
     // sections: Promo, Bookmarks, root profile, root account, message.
@@ -187,7 +187,8 @@
     controller.applicationCommandsHandler = mockApplicationCommandHandler;
     controller.snackbarCommandsHandler = mockSnackbarCommandHandler;
 
-    controller.displayedFolderNode = profile_bookmark_model_->mobile_node();
+    controller.displayedFolderNode =
+        local_or_syncable_bookmark_model_->mobile_node();
     base::UserActionTester user_action_tester;
     std::string user_action = "MobileKeyCommandClose";
     ASSERT_EQ(user_action_tester.GetActionCount(user_action), 0);
diff --git a/ios/chrome/browser/ui/bookmarks/home/bookmarks_promo_egtest.mm b/ios/chrome/browser/ui/bookmarks/home/bookmarks_promo_egtest.mm
index 3665e2f..381786f5 100644
--- a/ios/chrome/browser/ui/bookmarks/home/bookmarks_promo_egtest.mm
+++ b/ios/chrome/browser/ui/bookmarks/home/bookmarks_promo_egtest.mm
@@ -110,8 +110,12 @@
   [SigninEarlGreyUI
       verifySigninPromoVisibleWithMode:SigninPromoViewModeNoAccounts];
   NSString* body = l10n_util::GetNSString(IDS_IOS_SIGNIN_PROMO_BOOKMARKS);
+  NSString* primaryButtonText =
+      l10n_util::GetNSString(IDS_IOS_CONSISTENCY_PROMO_SIGN_IN);
   [[EarlGrey selectElementWithMatcher:grey_text(body)]
       assertWithMatcher:grey_sufficientlyVisible()];
+  [[EarlGrey selectElementWithMatcher:grey_text(primaryButtonText)]
+      assertWithMatcher:grey_sufficientlyVisible()];
 }
 
 // Tests that the promo view is only seen at root level and not in any of the
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm b/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm
index f1e5e6d7..87d0544 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm
@@ -136,20 +136,38 @@
 }
 
 - (CGSize)intrinsicContentSize {
+  // When the Most Visited Tiles module is not in the Magic Stack in a wider
+  // screen, the module is wider to match the wider Magic Stack ScrollView.
+  if (_type == ContentSuggestionsModuleType::kMostVisited &&
+      !ShouldPutMostVisitedSitesInMagicStack() &&
+      self.traitCollection.horizontalSizeClass ==
+          UIUserInterfaceSizeClassRegular) {
+    return CGSizeMake(kMagicStackWideWidth, self.bounds.size.height);
+  }
   return CGSizeMake(
       [MagicStackModuleContainer
           moduleWidthForHorizontalTraitCollection:self.traitCollection],
       self.bounds.size.height);
 }
 
+#pragma mark - UITraitEnvironment
+
+- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
+  [super traitCollectionDidChange:previousTraitCollection];
+  if (previousTraitCollection.horizontalSizeClass !=
+          self.traitCollection.horizontalSizeClass &&
+      _type == ContentSuggestionsModuleType::kMostVisited &&
+      !ShouldPutMostVisitedSitesInMagicStack()) {
+    _contentViewWidthAnchor.constant = [self contentViewWidth];
+  }
+}
+
 #pragma mark - Helpers
 
 // Returns the expected width of the contentView subview.
 - (CGFloat)contentViewWidth {
   NSDirectionalEdgeInsets insets = [self contentMargins];
-  return [MagicStackModuleContainer
-             moduleWidthForHorizontalTraitCollection:self.traitCollection] -
-         insets.leading - insets.trailing;
+  return [self intrinsicContentSize].width - insets.leading - insets.trailing;
 }
 
 @end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h
index 38697b8..ca3866f33 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h
@@ -38,6 +38,10 @@
 // Represents the Magic Stack ScrollView.
 extern NSString* const kMagicStackScrollViewAccessibilityIdentifier;
 
+// Represents the width of the Magic Stack ScrollView for the unique wide
+// layout.
+extern const CGFloat kMagicStackWideWidth;
+
 // The bottom margin below the Most Visited section.
 extern const CGFloat kMostVisitedBottomMargin;
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.mm
index 2bc07fd..8acfd0b 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.mm
@@ -24,6 +24,8 @@
 NSString* const kMagicStackScrollViewAccessibilityIdentifier =
     @"MagicStackScrollViewAccessibilityIdentifier";
 
+const CGFloat kMagicStackWideWidth = 430;
+
 const CGFloat kMostVisitedBottomMargin = 13;
 
 const int kTileAblationImpressionThresholdMinutes = 5;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index c9c599d..43c71df 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -698,8 +698,15 @@
   [super traitCollectionDidChange:previousTraitCollection];
   if (previousTraitCollection.horizontalSizeClass !=
       self.traitCollection.horizontalSizeClass) {
-    _magicStackScrollViewWidthAnchor.constant = [MagicStackModuleContainer
-        moduleWidthForHorizontalTraitCollection:self.traitCollection];
+    if (self.traitCollection.horizontalSizeClass ==
+        UIUserInterfaceSizeClassRegular) {
+      _magicStackScrollView.clipsToBounds = YES;
+      _magicStackScrollViewWidthAnchor.constant = kMagicStackWideWidth;
+    } else {
+      _magicStackScrollView.clipsToBounds = NO;
+      _magicStackScrollViewWidthAnchor.constant = [MagicStackModuleContainer
+          moduleWidthForHorizontalTraitCollection:self.traitCollection];
+    }
   }
 }
 
@@ -822,11 +829,11 @@
 }
 
 - (void)createMagicStack {
-  CGFloat width = [MagicStackModuleContainer
-      moduleWidthForHorizontalTraitCollection:self.traitCollection];
   _magicStackScrollView = [[UIScrollView alloc] init];
   [_magicStackScrollView setShowsHorizontalScrollIndicator:NO];
-  _magicStackScrollView.clipsToBounds = NO;
+  _magicStackScrollView.clipsToBounds =
+      self.traitCollection.horizontalSizeClass ==
+      UIUserInterfaceSizeClassRegular;
   _magicStackScrollView.delegate = self;
   _magicStackScrollView.accessibilityIdentifier =
       kMagicStackScrollViewAccessibilityIdentifier;
@@ -904,6 +911,14 @@
   // Define width of ScrollView. Instrinsic content height of the
   // StackView within the ScrollView will define the height of the
   // ScrollView.
+  CGFloat width = [MagicStackModuleContainer
+      moduleWidthForHorizontalTraitCollection:self.traitCollection];
+  // Magic Stack has a wider width for wider screens so that clipToBounds can be
+  // YES with a peeking module still visible.
+  if (self.traitCollection.horizontalSizeClass ==
+      UIUserInterfaceSizeClassRegular) {
+    width = kMagicStackWideWidth;
+  }
   _magicStackScrollViewWidthAnchor =
       [_magicStackScrollView.widthAnchor constraintEqualToConstant:width];
   [NSLayoutConstraint activateConstraints:@[
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h
index 43d1b599..69ca250 100644
--- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h
+++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h
@@ -31,6 +31,9 @@
 // The max amount of cards in the Discover Feed.
 extern const int kMaxCardsInFeed;
 
+// The number of days for the Activity Buckets calculations.
+extern const int kRangeForActivityBucketsInDays;
+
 // Stores the time when the user visits an article on the feed.
 extern NSString* const kArticleVisitTimestampKey;
 // Stores the time elapsed on the feed when the user leaves.
@@ -47,6 +50,12 @@
 extern NSString* const kLastDayTimeInFeedReportedKey;
 // Stores the time spent on the feed for a day.
 extern NSString* const kTimeSpentInFeedAggregateKey;
+// Stores the last time the activity bucket was reported.
+extern NSString* const kActivityBucketLastReportedDateKey;
+// Stores the last 28 days of activity bucket reported days.
+extern NSString* const kActivityBucketLastReportedDateArrayKey;
+// Stores the latest activity bucket the user was on.
+extern NSString* const kActivityBucketKey;
 
 #pragma mark - Enums
 
@@ -208,6 +217,21 @@
   kMaxValue = kSortedByLatest,
 };
 
+// TODO(crbug.com/1447234): Clean up the kError enum.
+// The values for the Feed Activity Buckets metric.
+enum class FeedActivityBucket {
+  // No activity bucket for users active 0/28 days.
+  kNoActivity = 0,
+  // Low activity bucket for users active 1-7/28 days.
+  kLowActivity = 1,
+  // Medium activity bucket for users active 8-15/28 days.
+  kMediumActivity = 2,
+  // High activity bucket for users active 16+/28 days.
+  kHighActivity = 3,
+  // Highest enumerator. Recommended by Histogram metrics best practices.
+  kMaxValue = kHighActivity,
+};
+
 #pragma mark - Histograms
 
 // Histogram name for the Time Spent in Feed.
@@ -223,6 +247,9 @@
 extern const char kFollowingFeedEngagementTypeHistogram[];
 extern const char kAllFeedsEngagementTypeHistogram[];
 
+// Histogram name for the feed activity bucket metric.
+extern const char kAllFeedsActivityBucketsHistogram[];
+
 // Histogram name for a Discover feed card shown at index.
 extern const char kDiscoverFeedCardShownAtIndex[];
 
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm
index 2eb9d73..e4ecd9e 100644
--- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm
+++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm
@@ -13,6 +13,7 @@
 const int kNonShortClickSeconds = 10;
 const int kMinutesBetweenSessions = 5;
 const int kMaxCardsInFeed = 50;
+const int kRangeForActivityBucketsInDays = 28;
 
 NSString* const kArticleVisitTimestampKey = @"ShortClickInteractionTimestamp";
 NSString* const kLongFeedVisitTimeAggregateKey =
@@ -30,6 +31,11 @@
     @"LastInteractionTimeForGoodVisitsFollowing";
 NSString* const kLastDayTimeInFeedReportedKey = @"LastDayTimeInFeedReported";
 NSString* const kTimeSpentInFeedAggregateKey = @"TimeSpentInFeedAggregate";
+NSString* const kActivityBucketLastReportedDateKey =
+    @"ActivityBucketLastReportedDate";
+NSString* const kActivityBucketLastReportedDateArrayKey =
+    @"ActivityBucketLastReportedDateArray";
+NSString* const kActivityBucketKey = @"FeedActivityBucket";
 
 #pragma mark - Histograms
 
@@ -49,6 +55,8 @@
     "NewTabPage.ContentSuggestions.Shown";
 const char kFollowingFeedCardShownAtIndex[] =
     "ContentSuggestions.Feed.WebFeed.Shown";
+const char kAllFeedsActivityBucketsHistogram[] =
+    "ContentSuggestions.Feed.AllFeeds.Activity";
 const char kDiscoverFeedNoticeCardFulfilled[] =
     "ContentSuggestions.Feed.NoticeCardFulfilled2";
 const char kDiscoverFeedArticlesFetchNetworkDurationSuccess[] =
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm
index 2baf10d..fd3eb4c 100644
--- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm
+++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm
@@ -47,6 +47,10 @@
 @property(nonatomic, assign) BOOL goodVisitReportedDiscover;
 @property(nonatomic, assign) BOOL goodVisitReportedFollowing;
 
+// Tracking property to avoid duplicate recordings of the Activity Buckets
+// metric.
+@property(nonatomic, assign) NSDate* activityBucketLastReportedDate;
+
 // Tracks whether user has engaged with the latest refreshed content. The term
 // "engaged" is defined by its usage in this file. For example, it may be
 // similar to `engagedSimpleReportedDiscover`.
@@ -194,6 +198,7 @@
     // Total time spent in feed metrics.
     self.timeSpentInFeed =
         base::Seconds([defaults doubleForKey:kTimeSpentInFeedAggregateKey]);
+    [self computeActivityBuckets];
     [self recordTimeSpentInFeedIfDayIsDone];
 
     self.previousTimeInFeedForGoodVisitSession =
@@ -887,6 +892,117 @@
   }
 }
 
+// Logs engagement daily for the Activity Buckets Calculation.
+- (void)logDailyActivity {
+  NSDate* now = [NSDate date];
+  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+
+  // Check if the array is initialized.
+  NSMutableArray<NSDate*>* lastReportedArray = [[defaults
+      arrayForKey:kActivityBucketLastReportedDateArrayKey] mutableCopy];
+  if (!lastReportedArray) {
+    // Initialized before (could be empty).
+    lastReportedArray = [NSMutableArray new];
+  }
+
+  // Adds a daily entry to the `lastReportedArray` array
+  // only once when the user engages.
+  if ([now timeIntervalSinceDate:[lastReportedArray lastObject]] >=
+          (24 * 60 * 60) ||
+      lastReportedArray.count == 0) {
+    [lastReportedArray addObject:now];
+    [defaults setObject:lastReportedArray
+                 forKey:kActivityBucketLastReportedDateArrayKey];
+  }
+}
+
+// Calculates the amount of dates the user has been active for the past 28 days.
+- (void)computeActivityBuckets {
+  NSDate* now = [NSDate date];
+  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+
+  NSDate* lastActivityBucketReported = base::mac::ObjCCast<NSDate>(
+      [defaults objectForKey:kActivityBucketLastReportedDateKey]);
+  // If the `lastActivityBucketReported` does not exist, set it to now to
+  // prevent the first day from logging a metric.
+  if (!lastActivityBucketReported) {
+    lastActivityBucketReported = now;
+    [defaults setObject:lastActivityBucketReported
+                 forKey:kActivityBucketLastReportedDateKey];
+  }
+
+  // Check if the last time the activity was reported is more than 24 hrs ago,
+  // and return for performance.
+  if ([now timeIntervalSinceDate:lastActivityBucketReported] < (24 * 60 * 60)) {
+    return;
+  }
+
+  // Retrieve activity bucket from storage.
+  FeedActivityBucket activityBucket =
+      (FeedActivityBucket)[defaults integerForKey:kActivityBucketKey];
+
+  // Calculate activity buckets.
+  // Check if the array is initialized.
+  NSMutableArray<NSDate*>* lastReportedArray = [[defaults
+      arrayForKey:kActivityBucketLastReportedDateArrayKey] mutableCopy];
+  if (!lastReportedArray) {
+    // Initialized before (could be empty).
+    lastReportedArray = [NSMutableArray new];
+  }
+
+  // Check for dates > 28 days and remove older items.
+  NSMutableIndexSet* toDelete = [[NSMutableIndexSet alloc] init];
+  for (NSUInteger i = 0; i < lastReportedArray.count; i++) {
+    if ([now timeIntervalSinceDate:[lastReportedArray objectAtIndex:i]] /
+            (24 * 60 * 60) >
+        kRangeForActivityBucketsInDays) {
+      [toDelete addIndex:i];
+    } else {
+      break;
+    }
+  }
+
+  // The count should never be < 1 for `lastReportedArray` when toDelete > 0 to
+  // prevent a crash / out of bounds errors.
+  if (toDelete.count > 0) {
+    CHECK(lastReportedArray.count >= 1);
+    [lastReportedArray removeObjectsAtIndexes:toDelete];
+  }
+  [defaults setObject:lastReportedArray
+               forKey:kActivityBucketLastReportedDateArrayKey];
+
+  // Check how many items in array.
+  NSUInteger datesActive = lastReportedArray.count;
+  switch (datesActive) {
+    case 0:
+      activityBucket = FeedActivityBucket::kNoActivity;
+      break;
+    case 1 ... 7:
+      activityBucket = FeedActivityBucket::kLowActivity;
+      break;
+    case 8 ... 15:
+      activityBucket = FeedActivityBucket::kMediumActivity;
+      break;
+    case 16 ... 28:
+      activityBucket = FeedActivityBucket::kHighActivity;
+      break;
+    default:
+      // This should never be reached, as dates should never be > 28 days.
+      CHECK(NO);
+      break;
+  }
+  [defaults setInteger:(int)activityBucket forKey:kActivityBucketKey];
+
+  // Activity Buckets Daily Run.
+  [self recordActivityBuckets:activityBucket];
+  [defaults setObject:now forKey:kActivityBucketLastReportedDateKey];
+}
+
+// Records the engagement buckets.
+- (void)recordActivityBuckets:(FeedActivityBucket)activityBucket {
+  UMA_HISTOGRAM_ENUMERATION(kAllFeedsActivityBucketsHistogram, activityBucket);
+}
+
 // Records Feed engagement.
 - (void)recordEngagement:(int)scrollDistance interacted:(BOOL)interacted {
   scrollDistance = abs(scrollDistance);
@@ -1055,6 +1171,9 @@
     NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
     [defaults setBool:YES forKey:kEngagedWithFeedKey];
 
+    // Log engagement for Activity Buckets.
+    [self logDailyActivity];
+
     UMA_HISTOGRAM_ENUMERATION(kAllFeedsEngagementTypeHistogram,
                               FeedEngagementType::kFeedEngaged);
   }
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc b/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
index 4d972fa..ef9b586 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
+++ b/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
@@ -22,7 +22,7 @@
 
 BASE_FEATURE(kOmniboxMultilineSearchSuggest,
              "OmniboxMultilineSearchSuggest",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Tail suggest is triggered server side.
 BASE_FEATURE(kOmniboxTailSuggest,
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn b/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn
index 0a8503c4..296f6bc 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn
@@ -81,6 +81,7 @@
     "//ios/chrome/browser/passwords:eg_test_support+eg2",
     "//ios/chrome/browser/signin:fake_system_identity",
     "//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
+    "//ios/chrome/browser/ui/settings/password:password_constants",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
     "//ios/testing/earl_grey:eg_test_support+eg2",
     "//net",
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_egtest.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_egtest.mm
index e1b17c0..b53c7fb 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_egtest.mm
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_egtest.mm
@@ -11,9 +11,11 @@
 #import "ios/chrome/browser/signin/fake_system_identity.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h"
 #import "ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_app_interface.h"
+#import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h"
 #import "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/earl_grey/chrome_actions.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
@@ -41,6 +43,11 @@
   return [waitForKeyboard waitWithTimeout:kWaitForActionTimeout.InSecondsF()];
 }
 
+id<GREYMatcher> ButtonWithAccessibilityID(NSString* id) {
+  return grey_allOf(grey_accessibilityID(id),
+                    grey_accessibilityTrait(UIAccessibilityTraitButton), nil);
+}
+
 }  // namespace
 
 @interface PasswordSuggestionBottomSheetEGTest : ChromeTestCase
@@ -73,6 +80,8 @@
   AppLaunchConfiguration config;
   config.features_enabled.push_back(
       password_manager::features::kIOSPasswordBottomSheet);
+  config.features_enabled.push_back(
+      password_manager::features::kPasswordsGrouping);
   return config;
 }
 
@@ -85,6 +94,32 @@
   [ChromeEarlGrey waitForWebStateContainingText:"Login form."];
 }
 
+// Return the edit button from the navigation bar.
+id<GREYMatcher> NavigationBarEditButton() {
+  return grey_allOf(chrome_test_util::ButtonWithAccessibilityLabelId(
+                        IDS_IOS_NAVIGATION_BAR_EDIT_BUTTON),
+                    grey_not(chrome_test_util::TabGridEditButton()),
+                    grey_userInteractionEnabled(), nil);
+}
+
+// Matcher for the Delete button at with accessibility identifier containing
+// `username` and `password` in Password Details view.
+id<GREYMatcher> DeleteButtonForUsernameAndPassword(NSString* username,
+                                                   NSString* password) {
+  return grey_allOf(
+      grey_accessibilityID([NSString
+          stringWithFormat:@"%@%@%@", kDeleteButtonForPasswordDetailsId,
+                           username, password]),
+      grey_interactable(), nullptr);
+}
+
+// Matcher for the Delete button in Confirmation Alert for password deletion.
+id<GREYMatcher> DeleteConfirmationButton() {
+  return grey_allOf(chrome_test_util::ButtonWithAccessibilityLabel(
+                        l10n_util::GetNSString(IDS_IOS_DELETE_ACTION_TITLE)),
+                    grey_interactable(), nullptr);
+}
+
 #pragma mark - Tests
 
 - (void)testOpenPasswordBottomSheetUsePassword {
@@ -137,4 +172,189 @@
   WaitForKeyboardToAppear();
 }
 
+- (void)testOpenPasswordBottomSheetOpenPasswordManager {
+  [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]
+                                enableSync:NO];
+  NSURL* URL =
+      net::NSURLWithGURL(self.testServer->GetURL("/simple_login_form.html"));
+  [PasswordSuggestionBottomSheetAppInterface setUpMockReauthenticationModule];
+  [PasswordSuggestionBottomSheetAppInterface
+      mockReauthenticationModuleExpectedResult:ReauthenticationResult::
+                                                   kSuccess];
+  [PasswordManagerAppInterface storeCredentialWithUsername:@"user"
+                                                  password:@"password"
+                                                       URL:URL];
+  [PasswordManagerAppInterface storeCredentialWithUsername:@"user2"
+                                                  password:@"password2"
+                                                       URL:URL];
+  int credentialsCount = [PasswordManagerAppInterface storedCredentialsCount];
+  GREYAssertEqual(2, credentialsCount, @"Wrong number of stored credentials.");
+
+  [self loadLoginPage];
+
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElementWithId(kFormPassword)];
+
+  [ChromeEarlGrey
+      waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user")];
+
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user")]
+      performAction:grey_tap()];
+
+  [ChromeEarlGrey
+      waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user2")];
+
+  // Long press to open context menu.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user2")]
+      performAction:grey_longPress()];
+
+  [ChromeEarlGreyUI waitForAppToIdle];
+
+  [[EarlGrey
+      selectElementWithMatcher:
+          grey_allOf(chrome_test_util::ButtonWithAccessibilityLabel(
+                         l10n_util::GetNSString(
+                             IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER)),
+                     grey_interactable(), nullptr)] performAction:grey_tap()];
+
+  [ChromeEarlGreyUI waitForAppToIdle];
+
+  NSString* origin =
+      [NSString stringWithFormat:@"http://%@:%@", [URL host], [URL port]];
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(
+                                   ButtonWithAccessibilityID([NSString
+                                       stringWithFormat:@"%@, 2 accounts",
+                                                        origin]),
+                                   grey_sufficientlyVisible(), nil)]
+      assertWithMatcher:grey_notNil()];
+}
+
+- (void)testOpenPasswordBottomSheetOpenPasswordDetails {
+  [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]
+                                enableSync:NO];
+  NSURL* URL =
+      net::NSURLWithGURL(self.testServer->GetURL("/simple_login_form.html"));
+  [PasswordSuggestionBottomSheetAppInterface setUpMockReauthenticationModule];
+  [PasswordSuggestionBottomSheetAppInterface
+      mockReauthenticationModuleExpectedResult:ReauthenticationResult::
+                                                   kSuccess];
+  [PasswordManagerAppInterface storeCredentialWithUsername:@"user"
+                                                  password:@"password"
+                                                       URL:URL];
+  [PasswordManagerAppInterface storeCredentialWithUsername:@"user2"
+                                                  password:@"password2"
+                                                       URL:URL];
+  int credentialsCount = [PasswordManagerAppInterface storedCredentialsCount];
+  GREYAssertEqual(2, credentialsCount, @"Wrong number of stored credentials.");
+
+  [self loadLoginPage];
+
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElementWithId(kFormPassword)];
+
+  [ChromeEarlGrey
+      waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user")];
+
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user")]
+      performAction:grey_tap()];
+
+  [ChromeEarlGrey
+      waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user2")];
+
+  // Long press to open context menu.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user2")]
+      performAction:grey_longPress()];
+
+  [ChromeEarlGreyUI waitForAppToIdle];
+
+  [[EarlGrey
+      selectElementWithMatcher:
+          grey_allOf(chrome_test_util::ButtonWithAccessibilityLabel(
+                         l10n_util::GetNSString(
+                             IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS)),
+                     grey_interactable(), nullptr)] performAction:grey_tap()];
+
+  [ChromeEarlGreyUI waitForAppToIdle];
+
+  [[EarlGrey
+      selectElementWithMatcher:chrome_test_util::TextFieldForCellWithLabelId(
+                                   IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME)]
+      assertWithMatcher:grey_textFieldValue(@"user2")];
+}
+
+- (void)testOpenPasswordBottomSheetDeletePassword {
+  [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]
+                                enableSync:NO];
+  NSURL* URL =
+      net::NSURLWithGURL(self.testServer->GetURL("/simple_login_form.html"));
+  [PasswordSuggestionBottomSheetAppInterface setUpMockReauthenticationModule];
+  [PasswordSuggestionBottomSheetAppInterface
+      mockReauthenticationModuleExpectedResult:ReauthenticationResult::
+                                                   kSuccess];
+  [PasswordManagerAppInterface storeCredentialWithUsername:@"user"
+                                                  password:@"password"
+                                                       URL:URL];
+  [PasswordManagerAppInterface storeCredentialWithUsername:@"user2"
+                                                  password:@"password2"
+                                                       URL:URL];
+  int credentialsCount = [PasswordManagerAppInterface storedCredentialsCount];
+  GREYAssertEqual(2, credentialsCount, @"Wrong number of stored credentials.");
+
+  [self loadLoginPage];
+
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElementWithId(kFormPassword)];
+
+  [ChromeEarlGrey
+      waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user")];
+
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user")]
+      performAction:grey_tap()];
+
+  [ChromeEarlGrey
+      waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user2")];
+
+  // Long press to open context menu.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user2")]
+      performAction:grey_longPress()];
+
+  [ChromeEarlGreyUI waitForAppToIdle];
+
+  [[EarlGrey
+      selectElementWithMatcher:
+          grey_allOf(chrome_test_util::ButtonWithAccessibilityLabel(
+                         l10n_util::GetNSString(
+                             IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS)),
+                     grey_interactable(), nullptr)] performAction:grey_tap()];
+
+  [ChromeEarlGreyUI waitForAppToIdle];
+
+  [[EarlGrey selectElementWithMatcher:NavigationBarEditButton()]
+      performAction:grey_tap()];
+
+  [[EarlGrey selectElementWithMatcher:DeleteButtonForUsernameAndPassword(
+                                          @"user2", @"password2")]
+      performAction:grey_tap()];
+
+  [[EarlGrey selectElementWithMatcher:DeleteConfirmationButton()]
+      performAction:grey_tap()];
+
+  // Wait until the alert and the detail view are dismissed.
+  [ChromeEarlGreyUI waitForAppToIdle];
+
+  // Verify that user2 is not available anymore.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElementWithId(kFormPassword)];
+
+  [ChromeEarlGrey
+      waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user")];
+
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user")]
+      performAction:grey_tap()];
+
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user2")]
+      assertWithMatcher:grey_nil()];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm
index ae0a3ffc..5fd4020 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm
@@ -154,7 +154,7 @@
           initWithProfilePasswordStore:_profilePasswordStore
                   accountPasswordStore:_accountPasswordStore
                               delegate:self
-                                   URL:_URL];
+                                   URL:url::Origin::Create(_URL).GetURL()];
     }
   }
   return self;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
index 459f357..9874ded 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
@@ -10,6 +10,7 @@
 #import "base/mac/foundation_util.h"
 #import "base/memory/scoped_refptr.h"
 #import "base/strings/sys_string_conversions.h"
+#import "components/password_manager/core/browser/password_manager_client.h"
 #import "components/password_manager/core/browser/ui/affiliated_group.h"
 #import "components/password_manager/core/browser/ui/credential_ui_entry.h"
 #import "components/password_manager/core/common/password_manager_features.h"
@@ -40,6 +41,7 @@
 #import "ios/chrome/browser/ui/settings/utils/password_utils.h"
 #import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
 #import "ios/chrome/grit/ios_strings.h"
+#import "ios/web/public/web_state.h"
 #import "ui/base/l10n/l10n_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -391,4 +393,14 @@
   [self.alertCoordinator start];
 }
 
+- (void)updateFormManagers {
+  web::WebState* activeWebState =
+      self.browser->GetWebStateList()->GetActiveWebState();
+  DCHECK(activeWebState);
+  password_manager::PasswordManagerClient* passwordManagerClient =
+      PasswordTabHelper::FromWebState(activeWebState)
+          ->GetPasswordManagerClient();
+  passwordManagerClient->UpdateFormManagers();
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
index ee7cbc4c..baff074 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
@@ -262,6 +262,10 @@
   // be multiple credentials; nor username/password since the values changed).
   base::Erase(_credentials, *it);
   [self providePasswordsToConsumer];
+
+  // Update form managers so the list of password suggestions shown to the user
+  // is the correct one.
+  [_delegate updateFormManagers];
 }
 
 - (void)moveCredentialToAccountStore:(PasswordDetails*)password {
@@ -371,6 +375,10 @@
 
       // Update the credential in the credentials vector.
       *it = std::move(updated_credential);
+
+      // Update form managers so the list of password suggestions shown to the
+      // user is the correct one.
+      [_delegate updateFormManagers];
       return;
     }
   }
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator_delegate.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator_delegate.h
index 0eaf935..b410a560 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator_delegate.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator_delegate.h
@@ -11,6 +11,10 @@
 // Called when the user wants to dismiss a compromised credential warning.
 - (void)showDismissWarningDialogWithPasswordDetails:(PasswordDetails*)password;
 
+// Called when a credential has been updated or deleted. This will refresh the
+// password suggestions list.
+- (void)updateFormManagers;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_MEDIATOR_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm
index 113eb94..7c7d4ad 100644
--- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm
@@ -48,6 +48,23 @@
       enableCompromisedDescription:NO];
 }
 
+// Creates a second test password issue.
+PasswordIssue* CreateTestPasswordIssue2() {
+  auto form = password_manager::PasswordForm();
+  form.url = GURL("http://www.example2.com/accounts/LoginAuth");
+  form.action = GURL("http://www.example2.com/accounts/Login");
+  form.username_element = u"Email";
+  form.username_value = u"test@egmail.com";
+  form.password_element = u"Passwd";
+  form.password_value = u"test";
+  form.submit_element = u"signIn";
+  form.signon_realm = "http://www.example2.com/";
+  form.scheme = password_manager::PasswordForm::Scheme::kHtml;
+  return [[PasswordIssue alloc]
+                initWithCredential:password_manager::CredentialUIEntry(form)
+      enableCompromisedDescription:NO];
+}
+
 // Text for testing the header of the page.
 NSString* GetHeaderText() {
   return l10n_util::GetNSString(IDS_IOS_WEAK_PASSWORD_ISSUES_DESCRIPTION);
@@ -123,21 +140,21 @@
 
   // Adds password issue to the view controller.
   void AddPasswordIssue() {
-    SetIssuesAndDismissedWarningsButtonText(@[ CreateTestPasswordIssue() ]);
+    SetIssuesAndDismissedWarningsButtonText(
+        @[ [[PasswordIssueGroup alloc]
+            initWithHeaderText:nil
+                passwordIssues:@[ CreateTestPasswordIssue() ]] ],
+        nil);
   }
 
   // Passes the given PasswordIssues and text for dismissed warnings button to
   // the view controller.
   void SetIssuesAndDismissedWarningsButtonText(
-      NSArray<PasswordIssue*>* password_issues,
+      NSArray<PasswordIssueGroup*>* password_issue_groups,
       NSString* dismissed_warnings_button_text = nil) {
-    PasswordIssueGroup* issue_group =
-        [[PasswordIssueGroup alloc] initWithHeaderText:nil
-                                        passwordIssues:password_issues];
-
     PasswordIssuesTableViewController* passwords_controller =
         static_cast<PasswordIssuesTableViewController*>(controller());
-    [passwords_controller setPasswordIssues:@[ issue_group ]
+    [passwords_controller setPasswordIssues:password_issue_groups
                 dismissedWarningsButtonText:dismissed_warnings_button_text];
   }
 
@@ -150,17 +167,23 @@
   }
 
   // Verifies that a header with the given text and url is in the model.
-  void CheckHeader(NSString* expected_text, CrURL* expected_url) {
+  void CheckHeader(NSString* expected_text,
+                   CrURL* expected_url = nil,
+                   int section = 0) {
     PasswordIssuesTableViewController* passwords_controller =
         GetPasswordIssuesController();
     TableViewModel* model = passwords_controller.tableViewModel;
 
     TableViewLinkHeaderFooterItem* header =
         base::mac::ObjCCastStrict<TableViewLinkHeaderFooterItem>(
-            [model headerForSectionIndex:0]);
+            [model headerForSectionIndex:section]);
 
     EXPECT_NSEQ(header.text, expected_text);
-    EXPECT_NSEQ(header.urls, @[ expected_url ]);
+    if (expected_url != nil) {
+      EXPECT_NSEQ(header.urls, @[ expected_url ]);
+    } else {
+      EXPECT_FALSE(header.urls.count);
+    }
   }
 
   FakePasswordIssuesPresenter* presenter() { return presenter_; }
@@ -232,6 +255,74 @@
   CheckTextCellTextWithId(IDS_IOS_CHANGE_COMPROMISED_PASSWORD, 0, 1);
 }
 
+// Test verifies password issue groups are displayed correctly when
+// kIOSPasswordCheckup feature is enabled.
+TEST_F(PasswordIssuesTableViewControllerTest,
+       TestPasswordIssueGroupWithKIOSPasswordCheckup) {
+  // Enable Password Checkup feature.
+  base::test::ScopedFeatureList feature_list(
+      password_manager::features::kIOSPasswordCheckup);
+
+  CreateController();
+
+  // Add two groups with headers and two issues each.
+  NSString* first_header_text = @"Group Header 1";
+  NSString* second_header_text = @"Group Header 2";
+  SetIssuesAndDismissedWarningsButtonText(
+      @[
+        [[PasswordIssueGroup alloc]
+            initWithHeaderText:first_header_text
+                passwordIssues:@[
+                  CreateTestPasswordIssue(), CreateTestPasswordIssue2()
+                ]],
+        [[PasswordIssueGroup alloc]
+            initWithHeaderText:second_header_text
+                passwordIssues:@[
+                  CreateTestPasswordIssue(), CreateTestPasswordIssue2()
+                ]]
+      ],
+      nil);
+
+  // Model should have one section for each issue.
+  EXPECT_EQ(4, NumberOfSections());
+
+  // Verify first issue group.
+
+  // Verify header on top of first issue.
+  CheckHeader(/*expected_text=*/first_header_text, /*url=*/nil, /*section=*/0);
+
+  // Verify first issue.
+  EXPECT_EQ(2, NumberOfItemsInSection(0));
+  CheckURLCellTitleAndDetailText(@"example.com", @"test@egmail.com", 0, 0);
+  CheckTextCellTextWithId(IDS_IOS_CHANGE_COMPROMISED_PASSWORD, 0, 1);
+
+  // Verify no header on top of second issue.
+  CheckHeader(/*expected_text=*/nil, /*url=*/nil, /*section=*/1);
+
+  // Verify second issue.
+  EXPECT_EQ(2, NumberOfItemsInSection(1));
+  CheckURLCellTitleAndDetailText(@"example2.com", @"test@egmail.com", 1, 0);
+  CheckTextCellTextWithId(IDS_IOS_CHANGE_COMPROMISED_PASSWORD, 1, 1);
+
+  // Verify second issue group.
+
+  // Verify header on top of first issue.
+  CheckHeader(/*expected_text=*/second_header_text, /*url=*/nil, /*section=*/2);
+
+  // Verify first issue.
+  EXPECT_EQ(2, NumberOfItemsInSection(3));
+  CheckURLCellTitleAndDetailText(@"example.com", @"test@egmail.com", 2, 0);
+  CheckTextCellTextWithId(IDS_IOS_CHANGE_COMPROMISED_PASSWORD, 2, 1);
+
+  // Verify no header on top of second issue.
+  CheckHeader(/*expected_text=*/nil, /*url=*/nil, /*section=*/3);
+
+  // Verify second issue.
+  EXPECT_EQ(2, NumberOfItemsInSection(3));
+  CheckURLCellTitleAndDetailText(@"example2.com", @"test@egmail.com", 3, 0);
+  CheckTextCellTextWithId(IDS_IOS_CHANGE_COMPROMISED_PASSWORD, 3, 1);
+}
+
 // Test verifies tapping item triggers function in presenter.
 TEST_F(PasswordIssuesTableViewControllerTest, TestPasswordIssueSelection) {
   CreateController();
@@ -254,8 +345,11 @@
       password_manager::features::kIOSPasswordCheckup);
 
   CreateController();
-  SetIssuesAndDismissedWarningsButtonText(@[ CreateTestPasswordIssue() ],
-                                          @"Dismiss Warnings (1)");
+  SetIssuesAndDismissedWarningsButtonText(
+      @[ [[PasswordIssueGroup alloc]
+          initWithHeaderText:nil
+              passwordIssues:@[ CreateTestPasswordIssue() ]] ],
+      @"Dismiss Warnings (1)");
 
   PasswordIssuesTableViewController* passwords_controller =
       GetPasswordIssuesController();
@@ -272,7 +366,10 @@
       password_manager::features::kIOSPasswordCheckup);
 
   PasswordIssue* password_issue = CreateTestPasswordIssue();
-  SetIssuesAndDismissedWarningsButtonText(@[ password_issue ]);
+  SetIssuesAndDismissedWarningsButtonText(
+      @[ [[PasswordIssueGroup alloc] initWithHeaderText:nil
+                                         passwordIssues:@[ password_issue ]] ],
+      nil);
 
   PasswordIssuesTableViewController* passwords_controller =
       static_cast<PasswordIssuesTableViewController*>(controller());
diff --git a/ios/chrome/browser/ui/sharing/activity_services/activities/bookmark_activity_unittest.mm b/ios/chrome/browser/ui/sharing/activity_services/activities/bookmark_activity_unittest.mm
index 5f88750..0f03cd4 100644
--- a/ios/chrome/browser/ui/sharing/activity_services/activities/bookmark_activity_unittest.mm
+++ b/ios/chrome/browser/ui/sharing/activity_services/activities/bookmark_activity_unittest.mm
@@ -54,11 +54,12 @@
 
   // Creates a BookmarkActivity instance with the given `URL`.
   BookmarkActivity* CreateActivity(const GURL& URL) {
-    return [[BookmarkActivity alloc] initWithURL:URL
-                                           title:kTestTitle
-                                   bookmarkModel:profile_bookmark_model_
-                                         handler:mocked_handler_
-                                     prefService:&testing_pref_service_];
+    return
+        [[BookmarkActivity alloc] initWithURL:URL
+                                        title:kTestTitle
+                                bookmarkModel:local_or_syncable_bookmark_model_
+                                      handler:mocked_handler_
+                                  prefService:&testing_pref_service_];
   }
 
   TestingPrefServiceSimple testing_pref_service_;
@@ -104,9 +105,9 @@
 // Tests that the title of the activity is edit when URL is already bookmarked.
 TEST_F(BookmarkActivityTest, ActivityTitle_EditBookmark) {
   // Add a bookmark.
-  const bookmarks::BookmarkNode* bookmark =
-      AddBookmark(profile_bookmark_model_->mobile_node(), u"activity_test");
-  ASSERT_TRUE(profile_bookmark_model_->IsBookmarked(bookmark->url()));
+  const bookmarks::BookmarkNode* bookmark = AddBookmark(
+      local_or_syncable_bookmark_model_->mobile_node(), u"activity_test");
+  ASSERT_TRUE(local_or_syncable_bookmark_model_->IsBookmarked(bookmark->url()));
 
   BookmarkActivity* activity = CreateActivity(bookmark->url());
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button.swift b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button.swift
index 67d0676..b189ad27 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button.swift
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button.swift
@@ -19,13 +19,13 @@
     @Published var count: Int?
   }
   @ObservedObject var state: State
-  @Environment(\.sizeCategory) var sizeCategory
+  @Environment(\.dynamicTypeSize) var typeSize
 
   var body: some View {
     Button {
       state.action?()
     } label: {
-      if sizeCategory < .accessibilityMedium {
+      if typeSize < .accessibility1 {
         regularLayout()
       } else {
         xxlLayout()
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
index e5a02c8..1e367637 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -2534,7 +2534,8 @@
 
 // Tests that once an account is signed in, the syncing spinner is eventually
 // dismissed: https://crbug.com/1422634.
-- (void)testSyncSpinnerDismissedInRecentlyClosedTabs {
+// TODO(crbug.com/1448618): Disabled due to causing lots of flake.
+- (void)DISABLED_testSyncSpinnerDismissedInRecentlyClosedTabs {
   // Sign-in with fake identity.
   FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
   [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity];
diff --git a/ios/chrome/browser/web/chrome_web_client.h b/ios/chrome/browser/web/chrome_web_client.h
index 9e545ab..e0bace8 100644
--- a/ios/chrome/browser/web/chrome_web_client.h
+++ b/ios/chrome/browser/web/chrome_web_client.h
@@ -27,7 +27,6 @@
   void AddAdditionalSchemes(Schemes* schemes) const override;
   std::string GetApplicationLocale() const override;
   bool IsAppSpecificURL(const GURL& url) const override;
-  std::u16string GetPluginNotSupportedText() const override;
   std::string GetUserAgent(web::UserAgentType type) const override;
   std::u16string GetLocalizedString(int message_id) const override;
   base::StringPiece GetDataResource(
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm
index ab98bf5c..4e878b9 100644
--- a/ios/chrome/browser/web/chrome_web_client.mm
+++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -229,10 +229,6 @@
   return url.SchemeIs(kChromeUIScheme);
 }
 
-std::u16string ChromeWebClient::GetPluginNotSupportedText() const {
-  return l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_SUPPORTED);
-}
-
 std::string ChromeWebClient::GetUserAgent(web::UserAgentType type) const {
   // The user agent should not be requested for app-specific URLs.
   DCHECK_NE(type, web::UserAgentType::NONE);
diff --git a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm
index 49f28b8..13c76f9d 100644
--- a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm
+++ b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm
@@ -431,7 +431,7 @@
   UINavigationBar* navigationBar = [[UINavigationBar alloc] init];
   navigationBar.translucent = NO;
   [navigationBar setShadowImage:[[UIImage alloc] init]];
-  [navigationBar setBarTintColor:[UIColor colorNamed:kBackgroundColor]];
+  [navigationBar setBarTintColor:[UIColor colorNamed:kPrimaryBackgroundColor]];
 
   UINavigationItem* navigationItem = [[UINavigationItem alloc] init];
   if (self.helpButtonAvailable) {
@@ -456,7 +456,6 @@
 
   if (self.titleView) {
     navigationItem.titleView = self.titleView;
-    [navigationBar setBarTintColor:self.titleView.backgroundColor];
   }
 
   if (self.showDismissBarButton) {
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
index 2175acae..5b2347e7 100644
--- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-94dcce9630b62058a4f0d6395931264adab533c2
\ No newline at end of file
+1cc4f1475ae2714b4417a3b9fbda565740755232
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
index fc4683c..cb37d86 100644
--- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-da49d5abf1169045367ab8769fd69d1771944445
\ No newline at end of file
+adafdbd5755e77b97920cf2a9bd347d99f45182f
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index 9a99b3cb..d6ce3f14 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-8124d6432cfce3b9a7fbe8dabe9d74ac19bd39b2
\ No newline at end of file
+b8edad814df8a333dffca8f6a38e7bf445cb0158
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index c8d0ffe..82e0799 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-ca4b84c8cfc9eae626b869dacd4947ee5cbe86d3
\ No newline at end of file
+11bc2313c2e4cce54226df1868ac216e9e550aa5
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index ffb6f14..a927a0f 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-0043de7ef8767ac65f9f6f486130b82413dd64a5
\ No newline at end of file
+926c1fc94ad6690a0fc5f8726cce3c3e01d19275
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 36fd489..945a6e8 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-0ddac668e0d258847a83aa611928d05d1beac469
\ No newline at end of file
+5a50c2597db802b14a4912e3902817c4c47dc212
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
index bf88844b5..846c5dd9 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-752ecd0fa2f6b91fd0a5b92cc52acab0e0b0266f
\ No newline at end of file
+f08926d3512b73c057dbb2ed8781cc89c785ca70
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
index 0c70a4b..d24e8f0 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-2c6309d578d6d504654a6d4d341a6374cf8b3878
\ No newline at end of file
+7aefe22a04ff95c8e0e421de2dd8be8d79de81e7
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index 882bcf4c..e072a66b 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-259736712c02131a7c1d651cca2bf6394515c9c9
\ No newline at end of file
+a0d33d28e563fa38d0ce04d4ea6aadc5c6f14b8a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 0a73c9e..f07e327 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-81b0c8ba5a660273ac0743a2507fa5c0ae81b51e
\ No newline at end of file
+996505d7ecb24195c59aecccb145e375059c821f
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index f8955c3c..8868497 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-b75b845ef3b324bb6374ac7668499b242424f801
\ No newline at end of file
+fd53dce36fc5b19386944bfeebf4185223597977
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 764d961..721e606 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-1bdf3507bc9c5f1a9dc5695a3a814c6763a0d2d0
\ No newline at end of file
+55118ee910cf1b2e7011080e77a4faf1ece74251
\ No newline at end of file
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index 8163f89..63fca538 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -32,9 +32,7 @@
     ":core",
     ":message_js",
     ":navigation_resources",
-    ":plugin_placeholder_js",
     ":resources",
-    ":share_workaround_js",
     ":threads",
     "//base",
     "//components/leveldb_proto",
@@ -622,7 +620,6 @@
     "navigation/history_state_operations_inttest.mm",
     "navigation/meta_tag_inttest.mm",
     "navigation/window_location_inttest.mm",
-    "plugin_placeholder_inttest.mm",
     "public/test/http_server_inttest.mm",
     "test/run_all_unittests.cc",
     "url_loader_inttest.mm",
@@ -640,20 +637,6 @@
   assert_no_deps = ios_assert_no_deps
 }
 
-optimize_js("plugin_placeholder_js") {
-  visibility = [ ":web" ]
-
-  primary_script = "web_state/js/resources/plugin_placeholder.js"
-  sources = [ "web_state/js/resources/plugin_placeholder.js" ]
-}
-
-optimize_js("share_workaround_js") {
-  visibility = [ ":web" ]
-
-  primary_script = "web_state/js/resources/share_workaround.js"
-  sources = [ "web_state/js/resources/share_workaround.js" ]
-}
-
 optimize_js("common_js") {
   visibility = [ ":web" ]
 
diff --git a/ios/web/js_messaging/java_script_feature_unittest.mm b/ios/web/js_messaging/java_script_feature_unittest.mm
index 435e69f..5fb9232 100644
--- a/ios/web/js_messaging/java_script_feature_unittest.mm
+++ b/ios/web/js_messaging/java_script_feature_unittest.mm
@@ -121,45 +121,6 @@
               feature_scripts[0].GetScriptString());
 }
 
-// Tests creating a JavaScriptFeature with replacements dictionary.
-TEST_F(JavaScriptFeatureTest, CreateFeatureWithPlaceholder) {
-  auto document_end_injection_time =
-      web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentEnd;
-  auto target_frames_all =
-      web::JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames;
-
-  NSString* placeholder = @"$(PLUGIN_NOT_SUPPORTED_TEXT)";
-  NSString* replacement = @"TEST_PLACEHOLDER_VALUE";
-
-  const web::JavaScriptFeature::FeatureScript feature_script =
-      web::JavaScriptFeature::FeatureScript::CreateWithFilename(
-          "plugin_placeholder", document_end_injection_time, target_frames_all,
-          web::JavaScriptFeature::FeatureScript::ReinjectionBehavior::
-              kReinjectOnDocumentRecreation,
-          base::BindRepeating(^NSDictionary<NSString*, NSString*>*() {
-            return @{placeholder : replacement};
-          }));
-
-  auto any_content_world = web::ContentWorld::kIsolatedWorld;
-  web::JavaScriptFeature feature(any_content_world, {feature_script});
-
-  EXPECT_EQ(any_content_world, feature.GetSupportedContentWorld());
-  EXPECT_EQ(0ul, feature.GetDependentFeatures().size());
-  auto feature_scripts = feature.GetScripts();
-  ASSERT_EQ(1ul, feature_scripts.size());
-  NSString* original_script = web::GetPageScript(@"plugin_placeholder");
-  NSString* final_script = feature_scripts[0].GetScriptString();
-
-  EXPECT_NSEQ(feature_script.GetScriptString(), final_script);
-  NSRange placeholder_range = [original_script rangeOfString:placeholder
-                                                     options:NSLiteralSearch];
-  EXPECT_TRUE(placeholder_range.location != NSNotFound);
-  EXPECT_FALSE([final_script containsString:placeholder]);
-  NSRange replacement_range = [final_script rangeOfString:replacement
-                                                  options:NSLiteralSearch];
-  EXPECT_EQ(placeholder_range.location, replacement_range.location);
-}
-
 // Tests creating a JavaScriptFeature which relies on a dependent feature.
 TEST_F(JavaScriptFeatureTest, CreateFeatureWithDependentFeature) {
   auto document_start_injection_time =
diff --git a/ios/web/js_messaging/java_script_feature_util_impl.mm b/ios/web/js_messaging/java_script_feature_util_impl.mm
index 5febd44..116f451 100644
--- a/ios/web/js_messaging/java_script_feature_util_impl.mm
+++ b/ios/web/js_messaging/java_script_feature_util_impl.mm
@@ -38,32 +38,10 @@
 const char kBaseScriptName[] = "gcrweb";
 const char kCommonScriptName[] = "common";
 const char kMessageScriptName[] = "message";
-const char kPluginPlaceholderScriptName[] = "plugin_placeholder";
-const char kShareWorkaroundScriptName[] = "share_workaround";
 
 const char kMainFrameDescription[] = "Main frame";
 const char kIframeDescription[] = "Iframe";
 
-// Returns the dictionary for placeholder replacements.
-NSDictionary<NSString*, NSString*>* PlaceholderReplacements() {
-  // The replacement value is computed dynamically each time this function is
-  // evaluated as the WebClient may change (in case of tests) or the returned
-  // value may change over time (nothing prevent a WebClient from doing that).
-  NSString* replacement =
-      base::SysUTF16ToNSString(GetWebClient()->GetPluginNotSupportedText());
-
-  // Escape the \ and ' characters in replacement. This is not done using the
-  // GetQuotedJSONString() function as it converts UTF-16 to UTF-8 which can
-  // cause problems when injecting script depending on the page enconding.
-  // See https://crbug.com/302741/.
-  replacement = [replacement stringByReplacingOccurrencesOfString:@"\\"
-                                                       withString:@"\\\\"];
-  replacement = [replacement stringByReplacingOccurrencesOfString:@"'"
-                                                       withString:@"\'"];
-
-  return @{@"$(PLUGIN_NOT_SUPPORTED_TEXT)" : replacement};
-}
-
 FaviconJavaScriptFeature* GetFaviconJavaScriptFeature() {
   // Static storage is ok for `favicon_feature` as it holds no state.
   static base::NoDestructor<FaviconJavaScriptFeature> favicon_feature;
@@ -92,35 +70,6 @@
   return window_error_feature.get();
 }
 
-JavaScriptFeature* GetPluginPlaceholderJavaScriptFeature() {
-  // Static storage is ok for `plugin_placeholder_feature` as it holds no state.
-  static base::NoDestructor<JavaScriptFeature> plugin_placeholder_feature(
-      ContentWorld::kIsolatedWorld,
-      std::vector<const JavaScriptFeature::FeatureScript>(
-          {JavaScriptFeature::FeatureScript::CreateWithFilename(
-              kPluginPlaceholderScriptName,
-              JavaScriptFeature::FeatureScript::InjectionTime::kDocumentEnd,
-              JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames,
-              JavaScriptFeature::FeatureScript::ReinjectionBehavior::
-                  kReinjectOnDocumentRecreation,
-              base::BindRepeating(&PlaceholderReplacements))}));
-  return plugin_placeholder_feature.get();
-}
-
-JavaScriptFeature* GetShareWorkaroundJavaScriptFeature() {
-  // Static storage is ok for `share_workaround_feature` as it holds no state.
-  static base::NoDestructor<JavaScriptFeature> share_workaround_feature(
-      ContentWorld::kPageContentWorld,
-      std::vector<const JavaScriptFeature::FeatureScript>(
-          {JavaScriptFeature::FeatureScript::CreateWithFilename(
-              kShareWorkaroundScriptName,
-              JavaScriptFeature::FeatureScript::InjectionTime::kDocumentStart,
-              JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames,
-              JavaScriptFeature::FeatureScript::ReinjectionBehavior::
-                  kInjectOncePerWindow)}));
-  return share_workaround_feature.get();
-}
-
 }  // namespace
 
 namespace java_script_features {
@@ -136,7 +85,6 @@
       FindInPageJavaScriptFeature::GetInstance(),
       GetFaviconJavaScriptFeature(),
       GetScrollHelperJavaScriptFeature(),
-      GetShareWorkaroundJavaScriptFeature(),
       GetWindowErrorJavaScriptFeature(),
       NavigationJavaScriptFeature::GetInstance(),
       SessionRestoreJavaScriptFeature::FromBrowserState(browser_state),
@@ -148,13 +96,6 @@
   features.insert(features.end(), frames_manager_features.begin(),
                   frames_manager_features.end());
 
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (!base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    features.push_back(GetPluginPlaceholderJavaScriptFeature());
-  }
-
   if (web::WebPageAnnotationsEnabled()) {
     features.push_back(AnnotationsJavaScriptFeature::GetInstance());
   }
diff --git a/ios/web/plugin_placeholder_inttest.mm b/ios/web/plugin_placeholder_inttest.mm
deleted file mode 100644
index 587e85f..0000000
--- a/ios/web/plugin_placeholder_inttest.mm
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "base/functional/bind.h"
-#import "base/ios/ios_util.h"
-#import "base/strings/stringprintf.h"
-#import "base/strings/utf_string_conversions.h"
-#import "ios/testing/embedded_test_server_handlers.h"
-#import "ios/web/js_messaging/java_script_feature_util_impl.h"
-#import "ios/web/public/test/fakes/fake_web_client.h"
-#import "ios/web/public/test/navigation_test_util.h"
-#import "ios/web/public/test/web_test_with_web_state.h"
-#import "ios/web/public/test/web_view_content_test_util.h"
-#import "net/test/embedded_test_server/embedded_test_server.h"
-#import "net/test/embedded_test_server/http_request.h"
-#import "net/test/embedded_test_server/http_response.h"
-#import "testing/gtest/include/gtest/gtest.h"
-#import "url/gurl.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-const char kPluginNotSupportedText[] =
-    "hahaha, your plugin is not supported :D";
-const char16_t kPluginNotSupportedText16[] =
-    u"hahaha, your plugin is not supported :D";
-}
-
-namespace web {
-
-// Tests that web page shows a placeholder for unsupported plugins.
-class PluginPlaceholderTest : public WebTestWithWebState {
- protected:
-  PluginPlaceholderTest()
-      : WebTestWithWebState(std::make_unique<FakeWebClient>()) {
-    FakeWebClient* web_client = static_cast<FakeWebClient*>(GetWebClient());
-    web_client->SetPluginNotSupportedText(kPluginNotSupportedText16);
-  }
-
-  // Sets up `server_` with `html` as response content.
-  [[nodiscard]] bool SetUpServer(const std::string& html) {
-    server_.RegisterDefaultHandler(
-        base::BindRepeating(&testing::HandlePageWithHtml, html));
-    return server_.Start();
-  }
-
-  net::test_server::EmbeddedTestServer server_;
-};
-
-// Tests that a large <applet> with text fallback is untouched.
-TEST_F(PluginPlaceholderTest, AppletFallback) {
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    return;
-  }
-
-  const char kPageDescription[] = "Applet, text fallback";
-  const char kFallbackText[] = "Java? On iOS? C'mon.";
-  const std::string page =
-      base::StringPrintf("<html><body width='800' height='600'>"
-                         "<p>%s</p>"
-                         "<applet code='Some.class' width='550' height='550'>"
-                         "  <p>%s</p>"
-                         "</applet>"
-                         "</body></html>",
-                         kPageDescription, kFallbackText);
-  ASSERT_TRUE(SetUpServer(page));
-  test::LoadUrl(web_state(), server_.GetURL("/"));
-  ASSERT_TRUE(WaitUntilLoaded());
-
-  // Verify that placeholder image is not displayed.
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPageDescription));
-  EXPECT_TRUE(test::WaitForWebViewContainingText(web_state(), kFallbackText));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
-      web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
-                                                    kPluginNotSupportedText));
-}
-
-// Tests placeholder for a large <applet> with no fallback.
-TEST_F(PluginPlaceholderTest, AppletOnly) {
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    return;
-  }
-
-  const char kPageDescription[] = "Applet, no fallback";
-  const std::string page =
-      base::StringPrintf("<html><body width='800' height='600'>"
-                         "<p>%s</p>"
-                         "<applet code='Some.class' width='550' height='550'>"
-                         "</applet>"
-                         "</body></html>",
-                         kPageDescription);
-  ASSERT_TRUE(SetUpServer(page));
-  test::LoadUrl(web_state(), server_.GetURL("/"));
-  ASSERT_TRUE(WaitUntilLoaded());
-
-  // Verify that plugin object is replaced with placeholder image.
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPageDescription));
-  EXPECT_TRUE(test::WaitForWebViewContainingElement(
-      web_state(),
-      [ElementSelector selectorWithCSSSelector:"img[src*='data']"]));
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPluginNotSupportedText));
-}
-
-// Tests placeholder for a large <object> with a flash embed fallback.
-TEST_F(PluginPlaceholderTest, ObjectFlashEmbedFallback) {
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    return;
-  }
-
-  const char kPageDescription[] = "Object, embed fallback";
-  const std::string page = base::StringPrintf(
-      "<html><body width='800' height='600'>"
-      "<p>%s</p>"
-      "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
-      "    codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
-      "flash/swflash.cab#version=6,0,0,0' width='550' height='550'>"
-      "  <param name='movie' value='some.swf'>"
-      "  <embed src='some.swf' type='application/x-shockwave-flash' "
-      "width='550' height='550'>"
-      "</object>"
-      "</body></html>",
-      kPageDescription);
-  ASSERT_TRUE(SetUpServer(page));
-  test::LoadUrl(web_state(), server_.GetURL("/"));
-  ASSERT_TRUE(WaitUntilLoaded());
-
-  // Verify that plugin object is replaced with placeholder image.
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPageDescription));
-  EXPECT_TRUE(test::WaitForWebViewContainingElement(
-      web_state(),
-      [ElementSelector selectorWithCSSSelector:"img[src*='data']"]));
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPluginNotSupportedText));
-}
-
-// Tests that a large <object> with an embed fallback of unspecified type is
-// untouched.
-TEST_F(PluginPlaceholderTest, ObjectUndefinedEmbedFallback) {
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    return;
-  }
-
-  const char kPageDescription[] = "Object, embed fallback";
-  const std::string page = base::StringPrintf(
-      "<html><body width='800' height='600'>"
-      "<p>%s</p>"
-      "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
-      "    codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
-      "flash/swflash.cab#version=6,0,0,0' width='550' height='550'>"
-      "  <param name='movie' value='some.swf'>"
-      "  <embed src='some.swf' width='550' height='550'>"
-      "</object>"
-      "</body></html>",
-      kPageDescription);
-  ASSERT_TRUE(SetUpServer(page));
-  test::LoadUrl(web_state(), server_.GetURL("/"));
-  ASSERT_TRUE(WaitUntilLoaded());
-
-  // Verify that placeholder image is not displayed.
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPageDescription));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
-      web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
-                                                    kPluginNotSupportedText));
-}
-
-// Tests that a large <object> with text fallback is untouched.
-TEST_F(PluginPlaceholderTest, ObjectFallback) {
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    return;
-  }
-
-  const char kPageDescription[] = "Object, text fallback";
-  const char kFallbackText[] = "You don't have Flash. Tough luck!";
-  const std::string page = base::StringPrintf(
-      "<html><body width='800' height='600'>"
-      "<p>%s</p>"
-      "<object type='application/x-shockwave-flash' data='some.sfw'"
-      "    width='550' height='550'>"
-      "  <param name='movie' value='some.swf'>"
-      "  <p>%s</p>"
-      "</object>"
-      "</body></html>",
-      kPageDescription, kFallbackText);
-  ASSERT_TRUE(SetUpServer(page));
-  test::LoadUrl(web_state(), server_.GetURL("/"));
-  ASSERT_TRUE(WaitUntilLoaded());
-
-  // Verify that placeholder image is not displayed.
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPageDescription));
-  EXPECT_TRUE(test::WaitForWebViewContainingText(web_state(), kFallbackText));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
-      web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
-                                                    kPluginNotSupportedText));
-}
-
-// Tests placeholder for a large <object> with no fallback.
-TEST_F(PluginPlaceholderTest, ObjectOnly) {
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    return;
-  }
-
-  const char kPageDescription[] = "Object, no fallback";
-  const std::string page = base::StringPrintf(
-      "<html><body width='800' height='600'>"
-      "<p>%s</p>"
-      "<object type='application/x-shockwave-flash' data='some.swf'"
-      "    width='550' height='550'>"
-      "</object>"
-      "</body></html>",
-      kPageDescription);
-  ASSERT_TRUE(SetUpServer(page));
-  test::LoadUrl(web_state(), server_.GetURL("/"));
-  ASSERT_TRUE(WaitUntilLoaded());
-
-  // Verify that plugin object is replaced with placeholder image.
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPageDescription));
-  EXPECT_TRUE(test::WaitForWebViewContainingElement(
-      web_state(),
-      [ElementSelector selectorWithCSSSelector:"img[src*='data']"]));
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPluginNotSupportedText));
-}
-
-// Tests that a large png <object> is untouched.
-TEST_F(PluginPlaceholderTest, PNGObject) {
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    return;
-  }
-
-  const char kPageDescription[] = "PNG object";
-  const std::string page = base::StringPrintf(
-      "<html><body width='800' height='600'>"
-      "<p>%s</p>"
-      "<object data='foo.png' type='image/png' width='550' height='550'>"
-      "</object>"
-      "</body></html>",
-      kPageDescription);
-  ASSERT_TRUE(SetUpServer(page));
-  test::LoadUrl(web_state(), server_.GetURL("/"));
-  ASSERT_TRUE(WaitUntilLoaded());
-
-  // Verify that placeholder image is not displayed.
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPageDescription));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
-      web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
-                                                    kPluginNotSupportedText));
-}
-
-// Test that non-major plugins (e.g., top/side ads) don't get placeholders.
-TEST_F(PluginPlaceholderTest, SmallFlash) {
-  // Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
-  // completely removed.
-  // TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
-  if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
-    return;
-  }
-
-  const char kPageDescription[] = "Flash ads";
-  const std::string page = base::StringPrintf(
-      "<html><body width='800' height='600'>"
-      "<p>%s</p>"
-      // 160x600 "skyscraper"
-      "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
-      "    codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
-      "flash/swflash.cab#version=6,0,0,0' width='160' height='600'>"
-      "  <param name='movie' value='some.swf'>"
-      "  <embed src='some.swf' width='160' height='600'>"
-      "</object>"
-      // 468x60 "full banner"
-      "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
-      "    codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
-      "flash/swflash.cab#version=6,0,0,0' width='468' height='60'>"
-      "  <param name='movie' value='some.swf'>"
-      "  <embed src='some.swf' width='468' height='60'>"
-      "</object>"
-      // 728x90 "leaderboard"
-      "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
-      "    codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
-      "flash/swflash.cab#version=6,0,0,0' width='728' height='90'>"
-      "  <param name='movie' value='some.swf'>"
-      "  <embed src='some.swf' width='728' height='90'>"
-      "</object>"
-      "</body></html>",
-      kPageDescription);
-  ASSERT_TRUE(SetUpServer(page));
-  test::LoadUrl(web_state(), server_.GetURL("/"));
-  ASSERT_TRUE(WaitUntilLoaded());
-
-  // Verify that placeholder image is not displayed.
-  EXPECT_TRUE(
-      test::WaitForWebViewContainingText(web_state(), kPageDescription));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
-      web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
-  EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
-                                                    kPluginNotSupportedText));
-}
-
-}  // namespace web
diff --git a/ios/web/public/test/fakes/fake_web_client.h b/ios/web/public/test/fakes/fake_web_client.h
index c8a93188..dfe4034 100644
--- a/ios/web/public/test/fakes/fake_web_client.h
+++ b/ios/web/public/test/fakes/fake_web_client.h
@@ -33,10 +33,6 @@
 
   std::string GetUserAgent(UserAgentType type) const override;
 
-  // Returns `plugin_not_supported_text_` as the text to be displayed for an
-  // unsupported plugin.
-  std::u16string GetPluginNotSupportedText() const override;
-
   base::RefCountedMemory* GetDataResourceBytes(int id) const override;
 
   std::vector<JavaScriptFeature*> GetJavaScriptFeatures(
diff --git a/ios/web/public/test/fakes/fake_web_client.mm b/ios/web/public/test/fakes/fake_web_client.mm
index 9df1b5b..cca98a9 100644
--- a/ios/web/public/test/fakes/fake_web_client.mm
+++ b/ios/web/public/test/fakes/fake_web_client.mm
@@ -34,10 +34,6 @@
   return url.SchemeIs(kTestWebUIScheme) || url.SchemeIs(kTestAppSpecificScheme);
 }
 
-std::u16string FakeWebClient::GetPluginNotSupportedText() const {
-  return plugin_not_supported_text_;
-}
-
 std::string FakeWebClient::GetUserAgent(UserAgentType type) const {
   if (type == UserAgentType::DESKTOP)
     return "Chromium/66.0.3333.0 CFNetwork/893.14 Darwin/16.7.0 Desktop";
diff --git a/ios/web/public/web_client.h b/ios/web/public/web_client.h
index 46db4f2..77d8a1f 100644
--- a/ios/web/public/web_client.h
+++ b/ios/web/public/web_client.h
@@ -85,9 +85,6 @@
   // browser would return true for "chrome://about" URL.
   virtual bool IsAppSpecificURL(const GURL& url) const;
 
-  // Returns text to be displayed for an unsupported plugin.
-  virtual std::u16string GetPluginNotSupportedText() const;
-
   // Returns the user agent string for the specified type.
   virtual std::string GetUserAgent(UserAgentType type) const;
 
diff --git a/ios/web/web_client.mm b/ios/web/web_client.mm
index 634ea5f..98eba05e1 100644
--- a/ios/web/web_client.mm
+++ b/ios/web/web_client.mm
@@ -45,10 +45,6 @@
   return false;
 }
 
-std::u16string WebClient::GetPluginNotSupportedText() const {
-  return std::u16string();
-}
-
 std::string WebClient::GetUserAgent(UserAgentType type) const {
   return std::string();
 }
diff --git a/ios/web/web_state/js/resources/plugin_placeholder.js b/ios/web/web_state/js/resources/plugin_placeholder.js
deleted file mode 100644
index 931129b..0000000
--- a/ios/web/web_state/js/resources/plugin_placeholder.js
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file adheres to closure-compiler conventions in order to enable
-// compilation with ADVANCED_OPTIMIZATIONS. See http://goo.gl/FwOgy
-//
-// Inserts placeholders into the DOM on top of unsupported plugins.
-
-/**
- * Checks whether an <object> node is plugin content (as <object> can also be
- * used to embed images).
- * @param {HTMLElement} node The <object> node to check.
- * @return {boolean} Whether the node appears to be a plugin.
- * @private
- */
-var objectNodeIsPlugin = function(node) {
-  return node.hasAttribute('classid') ||
-      (node.hasAttribute('type') && node.type.indexOf('image/') != 0);
-};
-
-/**
- * Checks whether a node has fallback content, which will be displayed in
- * browsers which do not support the required plugin to display the node's
- * content.
- * @param {HTMLElement} node The node to check.
- * @return {boolean} Whether the node has any fallback content.
- * @private
- */
-var nodeHasFallbackContent = function(node) {
-  if (node.textContent.trim().length > 0) {
-    return true;
-  }
-
-  var childrenCount = node.children.length;
-  for (var i = 0; i < childrenCount; i++) {
-    var childNode = /** @type {!HTMLElement} */ (node.children[i]);
-    // Do not consider <param> elements which affect the contents of the
-    // parent object node as fallback content.
-    if (childNode.tagName !== 'PARAM') {
-      return true;
-    }
-  }
-
-  return false;
-};
-
-/**
- * Finds the child embed element of node, if one exists.
- * @param {HTMLElement} node The node to check.
- * @return {HTMLElement} The embed fallback node, if one exists.
- * @private
- */
-var getChildEmbedElement = function(node) {
-  var childrenCount = node.children.length;
-  if (childrenCount == 0) {
-    return null;
-  }
-  for (var i = 0; i < childrenCount; i++) {
-    var childNode = /** @type {!HTMLElement} */ (node.children[i]);
-    if (childNode.tagName === 'EMBED') {
-      return childNode;
-    }
-  }
-  return null;
-};
-
-/**
- * Checks if an embed node explicitly defines the content type to be flash.
- * @param {HTMLElement} node The node to check.
- * @return {boolean} Whether the node is known to be flash content.
- * @private
- */
-var embedNodeIsKnownFlashContent = function(node) {
-  return node.hasAttribute('type') &&
-      (node.type.indexOf('application/x-shockwave-flash') == 0 ||
-       node.type.indexOf('application/vnd.adobe.flash-movie') == 0);
-};
-
-/**
- * Checks whether a plugin is supported. A supported plugin must have fallback
- * content and that fallback content must not be known flash content.
- * @param {HTMLElement} node The node to check.
- * @return {boolean} Whether the node is supported.
- * @private
- */
-var pluginNodeIsSupported = function(node) {
-  if (!nodeHasFallbackContent(node)) {
-    return false;
-  }
-
-  var embedChildNode = getChildEmbedElement(node);
-  if (embedChildNode && embedNodeIsKnownFlashContent(embedChildNode)) {
-    return false;
-  }
-
-  return true;
-};
-
-/**
- * Returns a list of plugin elements in the document that have either no
- * fallback content or have fallback content that is explicitly defined as
- * flash. For nested plugins, only the innermost plugin element is returned.
- * @return {!Array<!HTMLElement>} A list of plugin elements.
- * @private
- */
-var findPluginNodesWithoutFallback = function() {
-  var i, pluginNodes = [];
-  var objects = document.getElementsByTagName('object');
-  var objectCount = objects.length;
-  for (i = 0; i < objectCount; i++) {
-    var object = /** @type {!HTMLElement} */ (objects[i]);
-    if (objectNodeIsPlugin(object) && !pluginNodeIsSupported(object)) {
-      pluginNodes.push(object);
-    }
-  }
-  var applets = document.getElementsByTagName('applet');
-  var appletsCount = applets.length;
-  for (i = 0; i < appletsCount; i++) {
-    var applet = /** @type {!HTMLElement} */ (applets[i]);
-    if (!pluginNodeIsSupported(applet)) {
-      pluginNodes.push(applet);
-    }
-  }
-  return pluginNodes;
-};
-
-/* Data-URL version of plugin_blocked_android.png. Served this way rather
- * than with an intercepted URL to avoid messing up https pages.
- */
-var imageData =
-    'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAAD' +
-    'aklEQVR4Xn2Wz2tcVRTHP/e+O28mMxONJKlF4kIkP4luXFgQuuxCBaG41IWrLupOXLur+A' +
-    'e4cmV3LiS6qujSLgq2CIKQUqS2YnWsRkzGSTIz7zyHw+EdchnkcOd+7+OeT84578tMwmet' +
-    'O1fkar1RRNAgUJuqbeEn/0RUcdS6UX7w0X54/93qw4V+m0IReBiizhAYpG52kfrO86+F9/' +
-    'YXNnukHOTpc5SHgpiOu1cT623FBELeGvgTXfppOAjN3dCKm7GIkWiY4LsBnqBPpGqAgN/z' +
-    'CDMMBsCWX+pwibd5hzdZZmLNOsxDm8VAzIkt1hX5NLucqgrZm3RlIC/XscKTNlAQpvncMi' +
-    'tAnEM33D4nqgbcosBSPT3DRTJ3+Cx+4UfV3/CQniMQQ5g2WMJkoGKHNodUCBDpsYEQ2KGm' +
-    'JBKIFPT4nYckB9ueaPxRscamWczco3qXLcR9wx4ndBsziqFSjaOCAWLm4kj0xhhSMVFli4' +
-    'opyYuLlJ7s+/xTE6IgcVBthUuW6goHZDiA5IeCAnFEhkKVxxQh+pnoqSeMCEw4Uvt5kEHP' +
-    'c8IyF3iJ5De1NYSAMOYvOtxgwBqv0wcE5rR4gcQGq9Sc5wt7bq2JtfYtI0Ys8mCmLhFg7q' +
-    'w6XKRStUHJiMJmpC8vglqypAOU/MwRiw7KYGKqxZSKqE/iTKrQAwGxv5oU4ZbzGHCTf1QN' +
-    'OTXbQhJ/gbxKjy85IPECHQSQ3EFUfM0+93iZgluM6LuzDUTJOXpc5jcWeDb3DjQrsMhj9t' +
-    'TdPcAq8mtjjunyFEtN8ohfOWaVZR88Qd2WKK15a5zoRY8ZmRaNIZ/yCZ/P1u0zY+9TASjc' +
-    'q04YMzBhqAAUBXf5iWcITGdql3aTtpIZVnxGYvSxj1VPXUB0EtHnxBoT6iwgeXEwQfwC69' +
-    'xmROAcr5DwESxa3XLGW9G9AgPGVKahzzb/UvEcq81PwCl/MyDMrUgxQeMH7tNniQW6nPKA' +
-    'e5TU3KUFjPmTRxyofUsFeFVQqyENBHDAYyodJhR0CFrnfaYECgvAjdogEwZCVySQaJ8Zeq' +
-    'AL874rsy+2ofT1ev5fkSdmihwF0jpOra/kskTHkGMckkG9Gg7Xvw9XtifXOy/GEgCr7H/r' +
-    'yepFOFy5fu1agI9XH71RbRWRrDmHOhrfLYrx9ndv3Wz98R+P7LgG2uyMvgAAAABJRU5Erk' +
-    'Jggg==';
-
-/**
- * Returns the first <embed> child of the given node, if any.
- * @param {Node} node The node to check.
- * @return {HTMLElement} The first <embed> child, or null.
- * @private
- */
-var getEmbedChild = function(node) {
-  if (node.hasChildNodes()) {
-    for (var i = 0; i < node.childNodes.length; i++) {
-      if (node.childNodes[i].nodeName === 'EMBED') {
-        return /** @type {HTMLElement} */ (node.childNodes[i]);
-      }
-    }
-  }
-  return null;
-};
-
-/**
- * Returns the size for the given plugin element. For the common
- * pattern of an IE-specific <object> wrapping an all-other-browsers <embed>,
- * the object doesn't have real style info (most notably size), so this uses
- * the embed in that case.
- * @param {HTMLElement} plugin The <object> node to check.
- * @return {Object} The size (width and height) for the plugin element.
- * @private
- */
-var getPluginSize = function(plugin) {
-  var style;
-  // For the common pattern of an IE-specific <object> wrapping an
-  // all-other-browsers <embed>, the object doesn't have real style info
-  // (most notably size), so this uses the embed in that case.
-  var embedChild = getEmbedChild(plugin);
-  if (embedChild) {
-    style = window.getComputedStyle(embedChild);
-  } else {
-    style = window.getComputedStyle(plugin);
-  }
-
-  var width = parseFloat(style.width);
-  var height = parseFloat(style.height);
-  if (plugin.tagName === 'APPLET') {
-    // Size computation doesn't always work correctly with applets in
-    // UIWebView, so use the attributes as fallbacks.
-    if (isNaN(width)) {
-      width = parseFloat(plugin.width);
-    }
-    if (isNaN(height)) {
-      height = parseFloat(plugin.height);
-    }
-  }
-
-  return {'width': width, 'height': height};
-};
-
-/**
- * Checks whether an element is "significant". Whether a plugin is
- * "significant" is a heuristic that attempts to determine if it's a critical
- * visual element for the page (i.e., not invisible, or an incidental ad).
- * @param {HTMLElement} plugin The <object> node to check.
- * @return {boolean} Whether the node is significant.
- * @private
- */
-var isSignificantPlugin = function(plugin) {
-  var windowWidth = window.innerWidth;
-  var windowHeight = window.innerHeight;
-  var pluginSize = getPluginSize(plugin);
-  var pluginWidth = parseFloat(pluginSize.width);
-  var pluginHeight = parseFloat(pluginSize.height);
-  // A plugin must be at least |significantFraction| of one dimension of the
-  // page, and a minimum size in the other dimension (to weed out banners and
-  // tall side ads).
-  var minSize = Math.min(200, windowWidth / 2, windowHeight / 2);
-  var significantFraction = 0.5;
-  return (pluginWidth > windowWidth * significantFraction &&
-          pluginHeight > minSize) ||
-      (pluginHeight > windowHeight * significantFraction &&
-       pluginWidth > minSize);
-};
-
-/**
- * Walks the list of detected plugin elements, adding a placeholder to any
- * that are "significant" (see above).
- * @param {string} message The message to show in the placeholder.
- * @param {!Array<!HTMLElement>} plugins A list of plugin elements.
- * @private
- */
-var addPluginPlaceholders = function(message, plugins) {
-  var i;
-  for (i = 0; i < plugins.length; i++) {
-    var plugin = plugins[i];
-    if (!isSignificantPlugin(plugin)) {
-      continue;
-    }
-
-    var pluginSize = getPluginSize(plugin);
-    var widthStyle = pluginSize.width + 'px';
-    var heightStyle = pluginSize.height + 'px';
-
-    // The outer wrapper is a div with relative positioning, as an anchor for
-    // an inner absolute-position element, whose height is based on whether or
-    // not there's an embed. If there is, then it's zero height, to avoid
-    // affecting the layout of the (presumably-full-size) <embed> fallback. If
-    // not, it's full-height to ensure the placeholder takes up the right
-    // amount of space in the page layout. Width is full-width either way, to
-    // avoid being affected by container alignment.
-    var placeholder = document.createElement('div');
-    placeholder.style.width = widthStyle;
-    if (getEmbedChild(plugin)) {
-      placeholder.style.height = '0';
-    } else {
-      placeholder.style.height = heightStyle;
-    }
-    placeholder.style.position = 'relative';
-
-    // Inside is a full-plugin-size solid box.
-    var placeholderBox = document.createElement('div');
-    placeholderBox.style.position = 'absolute';
-    placeholderBox.style.boxSizing = 'border-box';
-    placeholderBox.style.width = widthStyle;
-    placeholderBox.style.height = heightStyle;
-    placeholderBox.style.border = '1px solid black';
-    placeholderBox.style.backgroundColor = '#808080';
-    placeholder.appendChild(placeholderBox);
-
-    // Inside that is the plugin placeholder image, centered.
-    var pluginImg = document.createElement('img');
-    var imageSize = 36;
-    pluginImg.width = imageSize;
-    pluginImg.height = imageSize;
-    pluginImg.style.position = 'absolute';
-    // Center vertically and horizontally.
-    var halfSize = imageSize / 2;
-    pluginImg.style.top = '50%';
-    pluginImg.style.marginTop = '-' + halfSize + 'px';
-    pluginImg.style.left = '50%';
-    pluginImg.style.marginLeft = '-' + halfSize + 'px';
-    pluginImg.src = imageData;
-    placeholderBox.appendChild(pluginImg);
-
-    // And below that, the message.
-    var label = document.createElement('p');
-    label.style.width = widthStyle;
-    label.style.height = '1.5em';
-    label.style.position = 'absolute';
-    // Position below the image.
-    label.style.top = '50%';
-    label.style.marginTop = imageSize + 'px';
-    // Center horizontally.
-    label.style.textAlign = 'center';
-    label.textContent = message;
-    placeholderBox.appendChild(label);
-
-    plugin.insertBefore(placeholder, plugin.firstChild);
-  }
-};
-
-// Add placeholders for plugin content.
-var plugins = findPluginNodesWithoutFallback();
-if (plugins.length > 0) {
-  // $(PLUGIN_NOT_SUPPORTED_TEXT) is replaced with the appropriate string prior
-  // to injection.
-  addPluginPlaceholders('$(PLUGIN_NOT_SUPPORTED_TEXT)', plugins);
-}
diff --git a/ios/web/web_state/js/resources/share_workaround.js b/ios/web/web_state/js/resources/share_workaround.js
deleted file mode 100644
index c16788e..0000000
--- a/ios/web/web_state/js/resources/share_workaround.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Workaround for preventing the leaking of local file contents.
- * See crbug.com/1122059.
- */
-
-/** Beginning of anonymous object */
-(function() {
-
-/** @private */
-// Store originals to prevent calling a modified version later.
-const originalNavigatorShare_ = Navigator.prototype.share;
-// Navigator.share is only supported in secure contexts, do not create function
-// if it does not exist.
-if (!originalNavigatorShare_) {
-  return;
-}
-
-const originalNavigator_ = navigator;
-const originalReflectApply_ = Reflect.apply;
-const originalObjectDefineProperty_ = Object.defineProperty;
-
-/**
- * Wraps navigator.share() to prevent sharing URLs with "file:" scheme.
- * NOTE: This code is sensitive and easy to break. See comments in
- * crbug.com/1122059 and review comments in crrev.com/c/2378274.
- * TODO:(crbug.com/1123689): Remove this workaround once WebKit fix is released.
- */
-Navigator.prototype.share = function(data) {
-  // Copy values to a new Object to prevent functions returning different
-  // data from data.url. crbug.com/1122059#c23
-  const validatedData = {};
-  if (data.hasOwnProperty('files')) {
-    originalObjectDefineProperty_(validatedData, 'files',
-        { value: data.files, configurable: false, writable: false })
-  }
-  if (data.hasOwnProperty('text')) {
-    originalObjectDefineProperty_(validatedData, 'text',
-        { value: data.text, configurable: false, writable: false })
-  }
-  if (data.hasOwnProperty('title')) {
-    originalObjectDefineProperty_(validatedData, 'title',
-        { value: data.title, configurable: false, writable: false })
-  }
-
-  let url = undefined;
-  if (data.hasOwnProperty('url')) {
-    url = data['url']?.toString();
-
-    let proceed = false;
-    if (url === undefined) {
-      // Allow url key to be set without value.
-      proceed = true;
-    } else {
-      // file: URLs are not allowed.
-      if (url.length >= 5 &&
-          (url[0] == 'f' || url[0] == 'F') &&
-          (url[1] == 'i' || url[1] == 'I') &&
-          (url[2] == 'l' || url[2] == 'L') &&
-          (url[3] == 'e' || url[3] == 'E') &&
-          url[4] == ':') {
-        proceed = false;
-      } else {
-        proceed = true;
-      }
-    }
-
-    if (!proceed) {
-      throw new Error("Sharing is not supported for this type of url.");
-    }
-  }
-
-  originalObjectDefineProperty_(validatedData, 'url',
-      { value: url, configurable: false, writable: false })
-
-  return originalReflectApply_(originalNavigatorShare_,
-                               originalNavigator_,
-                               [validatedData]);
-};
-
-}());  // End of anonymous object
diff --git a/ios/web_view/internal/web_view_web_client.h b/ios/web_view/internal/web_view_web_client.h
index e81118e8..d7ed9a0 100644
--- a/ios/web_view/internal/web_view_web_client.h
+++ b/ios/web_view/internal/web_view_web_client.h
@@ -34,7 +34,6 @@
       web::BrowserState* browser_state) const override;
   NSString* GetDocumentStartScriptForMainFrame(
       web::BrowserState* browser_state) const override;
-  std::u16string GetPluginNotSupportedText() const override;
   void PrepareErrorPage(web::WebState* web_state,
                         const GURL& url,
                         NSError* error,
diff --git a/ios/web_view/internal/web_view_web_client.mm b/ios/web_view/internal/web_view_web_client.mm
index 6192925f..6070e6e 100644
--- a/ios/web_view/internal/web_view_web_client.mm
+++ b/ios/web_view/internal/web_view_web_client.mm
@@ -115,10 +115,6 @@
   return provider.GetScript();
 }
 
-std::u16string WebViewWebClient::GetPluginNotSupportedText() const {
-  return l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_SUPPORTED);
-}
-
 void WebViewWebClient::PrepareErrorPage(
     web::WebState* web_state,
     const GURL& url,
diff --git a/media/audio/win/audio_low_latency_input_win.cc b/media/audio/win/audio_low_latency_input_win.cc
index dbc97918..215a93e4 100644
--- a/media/audio/win/audio_low_latency_input_win.cc
+++ b/media/audio/win/audio_low_latency_input_win.cc
@@ -56,6 +56,11 @@
 
 constexpr uint32_t KSAUDIO_SPEAKER_UNSUPPORTED = 0;
 
+// Max allowed absolute difference between a QPC-based timestamp and a default
+// base::TimeTicks::Now() timestamp before switching to fake audio timestamps.
+constexpr base::TimeDelta kMaxAbsTimeDiffBeforeSwithingToFakeTimestamps =
+    base::Milliseconds(500);
+
 // Converts a COM error into a human-readable string.
 std::string ErrorToString(HRESULT hresult) {
   return CoreAudioUtil::ErrorToString(hresult);
@@ -414,13 +419,6 @@
     }
   }
 
-  use_fake_audio_capture_timestamps_ =
-      base::FeatureList::IsEnabled(media::kUseFakeAudioCaptureTimestamps);
-  if (use_fake_audio_capture_timestamps_) {
-    SendLogMessage("%s => (WARNING: capture timestamps will be fake)",
-                   __func__);
-  }
-
   // Obtain an IAudioClient interface which enables us to create and initialize
   // an audio stream between an audio application and the audio engine.
   hr = endpoint_device_->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr,
@@ -866,6 +864,30 @@
       return;
     }
 
+    // Check if QPC-based timestamps provided by IAudioCaptureClient::GetBuffer
+    // can be used for audio timestamps or not. If not, base::TimeTicks::Now()
+    // will be used instead to generate the timestamps (called "fake" here). In
+    // the majority of cases, fake timestamps will not be utilized and the
+    // difference in `delta_time` below will be about the same size as the
+    // native buffer size (e.g. 10 msec).
+    // http://crbug.com/1439283 for details why this check is needed.
+    if (!use_fake_audio_capture_timestamps_.has_value()) {
+      base::TimeDelta delta_time =
+          base::TimeTicks::Now() -
+          base::TimeTicks::FromQPCValue(capture_time_100ns);
+      use_fake_audio_capture_timestamps_ =
+          (delta_time.magnitude() >
+           kMaxAbsTimeDiffBeforeSwithingToFakeTimestamps);
+      if (use_fake_audio_capture_timestamps_) {
+        SendLogMessage("%s => (WARNING: capture timestamps will be fake)",
+                       __func__);
+      }
+      TRACE_EVENT_INSTANT1("audio", "Audio Timestamps",
+                           TRACE_EVENT_SCOPE_THREAD,
+                           "use_fake_audio_capture_timestamps",
+                           use_fake_audio_capture_timestamps_.value());
+    }
+
     // The data in the packet is not correlated with the previous packet's
     // device position; this is possibly due to a stream state transition or
     // timing glitch. Note that, usage of this flag was added after the existing
diff --git a/media/audio/win/audio_low_latency_input_win.h b/media/audio/win/audio_low_latency_input_win.h
index 0573f84f..9eeaf13 100644
--- a/media/audio/win/audio_low_latency_input_win.h
+++ b/media/audio/win/audio_low_latency_input_win.h
@@ -361,12 +361,11 @@
   // raw (minimal) audio processing mode. Will be empty in most cases.
   std::vector<ABI::Windows::Media::Effects::AudioEffectType> raw_effect_types_;
 
-  // Will be enabled if "--use-fake-audio-capture-timestamps" has been added to
-  // the command line. This mode can be used in situations where the default
-  // capture timestamps are known to be invalid (e.g. for virtual devices) and
-  // must be emulated with local timeticks to ensure a monotonic timestamp
-  // sequence. See crbug.com/1315231 for more details.
-  bool use_fake_audio_capture_timestamps_ = false;
+  // Set to true if the absolute difference between a QPC timestamp converted
+  // into a TimeTick value and a default base::TimeTicks::Now() is larger than
+  // 500 msec. A true return value should trigger usage of "fake" audio
+  // timestamps instead of default which are QPC based.
+  absl::optional<bool> use_fake_audio_capture_timestamps_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 };
diff --git a/media/base/audio_bus.cc b/media/base/audio_bus.cc
index 5213c5db..8be8ade 100644
--- a/media/base/audio_bus.cc
+++ b/media/base/audio_bus.cc
@@ -101,7 +101,7 @@
     : channel_data_(channels), frames_(0), is_wrapper_(true) {
   CHECK_GT(channels, 0);
   for (size_t i = 0; i < channel_data_.size(); ++i)
-    channel_data_[i] = NULL;
+    channel_data_[i] = nullptr;
 }
 
 AudioBus::~AudioBus() {
diff --git a/media/base/encryption_pattern.cc b/media/base/encryption_pattern.cc
index 515b449..79c4071 100644
--- a/media/base/encryption_pattern.cc
+++ b/media/base/encryption_pattern.cc
@@ -28,4 +28,10 @@
   return !operator==(other);
 }
 
+std::ostream& operator<<(std::ostream& os,
+                         const EncryptionPattern& encryption_pattern) {
+  return os << "{" << encryption_pattern.crypt_byte_block() << ", "
+            << encryption_pattern.skip_byte_block() << "}";
+}
+
 }  // namespace media
diff --git a/media/base/encryption_pattern.h b/media/base/encryption_pattern.h
index 6a2c3e9..bd5d117e 100644
--- a/media/base/encryption_pattern.h
+++ b/media/base/encryption_pattern.h
@@ -6,6 +6,7 @@
 #define MEDIA_BASE_ENCRYPTION_PATTERN_H_
 
 #include <stdint.h>
+#include <ostream>
 
 #include "media/base/media_export.h"
 
@@ -45,6 +46,11 @@
   uint32_t skip_byte_block_ = 0;   // Count of the unencrypted blocks.
 };
 
+// For logging use only.
+MEDIA_EXPORT std::ostream& operator<<(
+    std::ostream& os,
+    const EncryptionPattern& encryption_pattern);
+
 }  // namespace media
 
 #endif  // MEDIA_BASE_ENCRYPTION_PATTERN_H_
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 6000ffc..046a7da 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -1175,12 +1175,6 @@
 const base::Feature MEDIA_EXPORT kWasapiRawAudioCapture{
     "WASAPIRawAudioCapture", base::FEATURE_ENABLED_BY_DEFAULT};
 
-// Emulates audio capture timestamps instead of using timestamps from the actual
-// audio device.
-// See crbug.com/1315231 for more details.
-const base::Feature MEDIA_EXPORT kUseFakeAudioCaptureTimestamps{
-    "UseFakeAudioCaptureTimestamps", base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Enable VP9 kSVC decoding with HW decoder for webrtc use case on Windows.
 BASE_FEATURE(kD3D11Vp9kSVCHWDecoding,
              "D3D11Vp9kSVCHWDecoding",
@@ -1259,14 +1253,20 @@
 // lacros-chrome through the crosapi.
 const base::Feature MEDIA_EXPORT kExposeOutOfProcessVideoDecodingToLacros{
     "ExposeOutOfProcessVideoDecodingToLacros",
-    base::FEATURE_DISABLED_BY_DEFAULT};
+    base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
 // Spawn utility processes to perform hardware decode acceleration instead of
 // using the GPU process.
 const base::Feature MEDIA_EXPORT kUseOutOfProcessVideoDecoding{
-    "UseOutOfProcessVideoDecoding", base::FEATURE_DISABLED_BY_DEFAULT};
+  "UseOutOfProcessVideoDecoding",
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+      base::FEATURE_ENABLED_BY_DEFAULT
+#else
+      base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
 #endif  // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index ecf3c6d..4995ab1 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -372,7 +372,6 @@
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kMediaFoundationClearPlayback);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kAllowMediaFoundationFrameServerMode);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kWasapiRawAudioCapture);
-MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseFakeAudioCaptureTimestamps);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kD3D11Vp9kSVCHWDecoding);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kDXVAVideoDecoding);
 
diff --git a/media/base/text_renderer_unittest.cc b/media/base/text_renderer_unittest.cc
index f326c16..cbceae73 100644
--- a/media/base/text_renderer_unittest.cc
+++ b/media/base/text_renderer_unittest.cc
@@ -170,7 +170,7 @@
     }
   }
 
-  void OnDestroyTextTrack(unsigned idx) { text_tracks_[idx] = NULL; }
+  void OnDestroyTextTrack(unsigned idx) { text_tracks_[idx] = nullptr; }
 
   void Play() { text_renderer_->StartPlaying(); }
 
diff --git a/media/filters/win/media_foundation_utils.cc b/media/filters/win/media_foundation_utils.cc
index 4565a76..a26d3a1 100644
--- a/media/filters/win/media_foundation_utils.cc
+++ b/media/filters/win/media_foundation_utils.cc
@@ -124,6 +124,38 @@
   } else if (decrypt_config.encryption_scheme() == EncryptionScheme::kCbcs) {
     mf_protection_scheme = MFSampleEncryptionProtectionScheme::
         MF_SAMPLE_ENCRYPTION_PROTECTION_SCHEME_AES_CBC;
+
+    if (decrypt_config.HasPattern()) {
+      DVLOG(3) << __func__ << ": encryption_pattern="
+               << decrypt_config.encryption_pattern().value();
+
+      // Invalid if crypt == 0 and skip >= 0.
+      CHECK(!(decrypt_config.encryption_pattern()->crypt_byte_block() == 0 &&
+              decrypt_config.encryption_pattern()->skip_byte_block() > 0));
+
+      // Crypt and skip byte blocks for the sample-based protection pattern need
+      // be set if the protection scheme is `cbcs`. No need to set for 10:0,
+      // 1:0, or 0:0 patterns since Media Foundation Media Engine treats them as
+      // `cbc1` always but it won't reset IV between subsamples (which means IV
+      // to be restored to the constant IV after each subsample). Trying to set
+      // crypt to non-zero and skip to 0 will cause an error:
+      // - If either of these attributes are not present or have a value of 0,
+      // the sample is `cbc1`. See
+      // https://learn.microsoft.com/en-us/windows/win32/medfound/mfsampleextension-encryption-cryptbyteblock
+      // and
+      // https://learn.microsoft.com/en-us/windows/win32/medfound/mfsampleextension-encryption-skipbyteblock
+      // - If `cBlocksStripeEncrypted` is 0, `cBlocksStripeClear` must be also
+      // 0. See
+      // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/d3d10umddi/ns-d3d10umddi-d3dwddm2_4ddi_video_decoder_buffer_desc
+      if (decrypt_config.encryption_pattern()->skip_byte_block() > 0) {
+        RETURN_IF_FAILED(mf_sample->SetUINT32(
+            MFSampleExtension_Encryption_CryptByteBlock,
+            decrypt_config.encryption_pattern()->crypt_byte_block()));
+        RETURN_IF_FAILED(mf_sample->SetUINT32(
+            MFSampleExtension_Encryption_SkipByteBlock,
+            decrypt_config.encryption_pattern()->skip_byte_block()));
+      }
+    }
   } else {
     NOTREACHED() << "Unexpected encryption scheme";
     return MF_E_UNEXPECTED;
@@ -344,7 +376,7 @@
     RETURN_IF_FAILED(mf_sample->SetUINT32(MFSampleExtension_CleanPoint, 1));
   }
 
-  DVLOG(3) << __func__ << "buffer->duration()=" << buffer->duration()
+  DVLOG(3) << __func__ << ": buffer->duration()=" << buffer->duration()
            << ", buffer->timestamp()=" << buffer->timestamp();
   MFTIME sample_duration = TimeDeltaToMfTime(buffer->duration());
   RETURN_IF_FAILED(mf_sample->SetSampleDuration(sample_duration));
@@ -442,7 +474,7 @@
       uint32_t subsample_count =
           subsample_mappings_size / sizeof(MediaFoundationSubsampleEntry);
       for (uint32_t i = 0; i < subsample_count; ++i) {
-        DVLOG(3) << __func__ << "subsample_mappings[" << i
+        DVLOG(3) << __func__ << ": subsample_mappings[" << i
                  << "].clear_bytes=" << subsample_mappings[i].clear_bytes
                  << ", cipher_bytes=" << subsample_mappings[i].cipher_bytes;
         subsamples.emplace_back(subsample_mappings[i].clear_bytes,
@@ -454,7 +486,7 @@
   // Key ID
   const auto key_id_string = GetStringFromGUID(key_id);
   const auto iv_string = std::string(iv.get(), iv.get() + iv_length);
-  DVLOG(3) << __func__ << "key_id_string=" << key_id_string
+  DVLOG(3) << __func__ << ": key_id_string=" << key_id_string
            << ", iv_string=" << iv_string
            << ", iv_string.size()=" << iv_string.size();
 
@@ -462,8 +494,24 @@
     *decrypt_config =
         DecryptConfig::CreateCencConfig(key_id_string, iv_string, subsamples);
   } else {
+    EncryptionPattern encryption_pattern;
+
+    // Try to get crypt and skip byte blocks for pattern encryption. Use the
+    // values only if both `MFSampleExtension_Encryption_CryptByteBlock` and
+    // `MFSampleExtension_Encryption_SkipByteBlock` are present. Otherwise,
+    // assume both are zeros.
+    UINT32 crypt_byte_block = 0;
+    UINT32 skip_byte_block = 0;
+    if (SUCCEEDED(mf_sample->GetUINT32(
+            MFSampleExtension_Encryption_CryptByteBlock, &crypt_byte_block)) &&
+        SUCCEEDED(mf_sample->GetUINT32(
+            MFSampleExtension_Encryption_SkipByteBlock, &skip_byte_block))) {
+      encryption_pattern = EncryptionPattern(crypt_byte_block, skip_byte_block);
+    }
+
+    DVLOG(3) << __func__ << ": encryption_pattern=" << encryption_pattern;
     *decrypt_config = DecryptConfig::CreateCbcsConfig(
-        key_id_string, iv_string, subsamples, EncryptionPattern());
+        key_id_string, iv_string, subsamples, encryption_pattern);
   }
 
   return S_OK;
diff --git a/media/gpu/chromeos/oop_video_decoder.cc b/media/gpu/chromeos/oop_video_decoder.cc
index 1afc2df..5fd2381 100644
--- a/media/gpu/chromeos/oop_video_decoder.cc
+++ b/media/gpu/chromeos/oop_video_decoder.cc
@@ -182,14 +182,23 @@
     return *decoder_type_;
   }
 
+  uint32_t GetInterfaceVersion() {
+    base::AutoLock lock(lock_);
+    // The justification for this CHECK() is similar as the one in
+    // GetDecoderType().
+    CHECK(interface_version_.has_value());
+    return *interface_version_;
+  }
+
   void NotifySupportKnown(
       mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder,
       base::OnceCallback<
           void(mojo::PendingRemote<stable::mojom::StableVideoDecoder>)> cb) {
     base::ReleasableAutoLock lock(&lock_);
-    if (configs_) {
-      // The supported configurations are already known. We can call |cb|
-      // immediately.
+    if ((configs_ && interface_version_) || disconnected_) {
+      // Both the supported configurations and the interface version are already
+      // known (or a disconnection has occurred, in which case |configs_| should
+      // be an empty list). We can call |cb| immediately.
       //
       // We release the lock in case the |waiting_callback|.cb wants to re-enter
       // OOPVideoDecoderSupportedConfigsManager by reaching
@@ -199,23 +208,26 @@
       return;
     } else if (!waiting_callbacks_.empty()) {
       // There is a query in progress. We need to queue |cb| to call it later
-      // when the supported configurations are known.
+      // when the supported configurations and interface version are known.
       waiting_callbacks_.emplace(
           std::move(oop_video_decoder), std::move(cb),
           base::SequencedTaskRunner::GetCurrentDefault());
       return;
     }
 
-    // The supported configurations are not known. We need to use
-    // |oop_video_decoder| to query them.
+    // At this point both the |configs_| and the |interface_version_| are
+    // unknown. We need to use |oop_video_decoder| to query them.
     //
     // Note: base::Unretained(this) is safe because the
     // OOPVideoDecoderSupportedConfigsManager never gets destroyed.
+    CHECK(!configs_.has_value() && !interface_version_.has_value());
     oop_video_decoder_.Bind(std::move(oop_video_decoder));
     oop_video_decoder_.set_disconnect_handler(base::BindOnce(
-        &OOPVideoDecoderSupportedConfigsManager::OnGetSupportedConfigs,
-        base::Unretained(this), SupportedVideoDecoderConfigs(),
-        VideoDecoderType::kUnknown));
+        &OOPVideoDecoderSupportedConfigsManager::OnDecoderDisconnected,
+        base::Unretained(this)));
+    oop_video_decoder_.QueryVersion(base::BindOnce(
+        &OOPVideoDecoderSupportedConfigsManager::OnGetInterfaceVersion,
+        base::Unretained(this)));
     oop_video_decoder_->GetSupportedConfigs(base::BindOnce(
         &OOPVideoDecoderSupportedConfigsManager::OnGetSupportedConfigs,
         base::Unretained(this)));
@@ -235,11 +247,29 @@
   OOPVideoDecoderSupportedConfigsManager() = default;
   ~OOPVideoDecoderSupportedConfigsManager() = default;
 
+  void OnDecoderDisconnected() {
+    base::AutoLock lock(lock_);
+    configs_ = {};
+    decoder_type_ = absl::nullopt;
+    interface_version_ = absl::nullopt;
+    disconnected_ = true;
+    MaybeNotifyWaitingCallbacks();
+  }
+
+  void OnGetInterfaceVersion(uint32_t interface_version) {
+    base::AutoLock lock(lock_);
+    DCHECK(!interface_version_);
+    CHECK(!disconnected_);
+    interface_version_ = interface_version;
+    MaybeNotifyWaitingCallbacks();
+  }
+
   void OnGetSupportedConfigs(const SupportedVideoDecoderConfigs& configs,
                              VideoDecoderType decoder_type) {
     base::AutoLock lock(lock_);
     DCHECK(!configs_);
     DCHECK(!decoder_type_);
+    CHECK(!disconnected_);
 
     if (decoder_type == VideoDecoderType::kVda ||
         decoder_type == VideoDecoderType::kVaapi ||
@@ -251,6 +281,22 @@
       configs_ = {};
     }
 
+    MaybeNotifyWaitingCallbacks();
+  }
+
+  void MaybeNotifyWaitingCallbacks() EXCLUSIVE_LOCKS_REQUIRED(lock_) {
+    if (!disconnected_ &&
+        (!configs_.has_value() || !interface_version_.has_value())) {
+      // We're still connected but still waiting on either the supported
+      // configurations or the interface version.
+      return;
+    }
+
+    // Here we either a) know both the supported configurations and the
+    // interface version; or b) have disconnected. In the latter case,
+    // |configs_| should be an empty list.
+    CHECK(!disconnected_ || (configs_.has_value() && configs_->empty()));
+
     while (!waiting_callbacks_.empty()) {
       WaitingCallbackContext waiting_callback =
           std::move(waiting_callbacks_.front());
@@ -279,13 +325,17 @@
 
   // The first PendingRemote that NotifySupportKnown() is called with is bound
   // to |oop_video_decoder_| and we use it to query the supported configurations
-  // of the out-of-process video decoder. |oop_video_decoder_| will get unbound
-  // once the supported configurations are known.
+  // and the interface version of the out-of-process video decoder.
+  // |oop_video_decoder_| will get unbound once both of those things are known.
   mojo::Remote<stable::mojom::StableVideoDecoder> oop_video_decoder_;
 
-  // The cached supported video decoder configurations and decoder type.
+  bool disconnected_ GUARDED_BY(lock_) = false;
+
+  // The cached supported video decoder configurations, decoder type, and
+  // interface version.
   absl::optional<SupportedVideoDecoderConfigs> configs_ GUARDED_BY(lock_);
   absl::optional<VideoDecoderType> decoder_type_ GUARDED_BY(lock_);
+  absl::optional<uint32_t> interface_version_ GUARDED_BY(lock_);
 
   // This tracks everything that's needed to call a callback passed to
   // NotifySupportKnown() that had to be queued because there was a query in
@@ -466,12 +516,6 @@
       // base::Unretained() is safe because |this| owns the mojo::Receiver.
       stable_cdm_context_receiver_->set_disconnect_handler(
           base::BindOnce(&OOPVideoDecoder::Stop, base::Unretained(this)));
-#if BUILDFLAG(USE_VAAPI)
-      // We need to signal that for AMD we will do transcryption on the GPU
-      // side. Then on the other end we just make transcryption a no-op.
-      needs_transcryption_ = (VaapiWrapper::GetImplementationType() ==
-                              VAImplementation::kMesaGallium);
-#endif  // BUILDFLAG(USE_VAAPI)
     }
 #else
     std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode);
@@ -481,6 +525,9 @@
 
   initialized_for_protected_content_ = config.is_encrypted();
 
+  // This will be updated in OnInitializeDone() as needed.
+  needs_transcryption_ = false;
+
   init_cb_ = std::move(init_cb);
   output_cb_ = output_cb;
   waiting_cb_ = waiting_cb;
@@ -494,7 +541,8 @@
 void OOPVideoDecoder::OnInitializeDone(const DecoderStatus& status,
                                        bool needs_bitstream_conversion,
                                        int32_t max_decode_requests,
-                                       VideoDecoderType decoder_type) {
+                                       VideoDecoderType decoder_type,
+                                       bool needs_transcryption) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   CHECK(!has_error_);
@@ -509,6 +557,28 @@
     return;
   }
   remote_decoder_type_ = decoder_type;
+
+  if (OOPVideoDecoderSupportedConfigsManager::Instance()
+          .GetInterfaceVersion() >= 1u) {
+    // Starting on version 1, the remote decoder tells us if we need to do
+    // transcryption before sending the encoded data.
+    needs_transcryption_ =
+        initialized_for_protected_content_ && needs_transcryption;
+  } else {
+    // Before version 1, the remote decoder does not tell us this information,
+    // so we need to find it ourselves.
+    //
+    // TODO(b/171813538): remove this once the maximum version skew between
+    // lacros-chrome and ash-chrome makes it impossible for the former to run on
+    // ash-chrome < M115 (since M115 is when StableVideoDecoder got upgraded to
+    // version 1).
+#if BUILDFLAG(USE_VAAPI)
+    needs_transcryption_ = initialized_for_protected_content_ &&
+                           (VaapiWrapper::GetImplementationType() ==
+                            VAImplementation::kMesaGallium);
+#endif  // BUILDFLAG(USE_VAAPI)
+  }
+
   std::move(init_cb_).Run(status);
 }
 
diff --git a/media/gpu/chromeos/oop_video_decoder.h b/media/gpu/chromeos/oop_video_decoder.h
index 9ddc943..abc3c5b 100644
--- a/media/gpu/chromeos/oop_video_decoder.h
+++ b/media/gpu/chromeos/oop_video_decoder.h
@@ -112,7 +112,8 @@
   void OnInitializeDone(const DecoderStatus& status,
                         bool needs_bitstream_conversion,
                         int32_t max_decode_requests,
-                        VideoDecoderType decoder_type);
+                        VideoDecoderType decoder_type,
+                        bool needs_transcryption);
 
   void OnDecodeDone(uint64_t decode_id,
                     bool is_flush_cb,
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
index 29ee996..627b9961 100644
--- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
+++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -1251,7 +1251,7 @@
     has_prepared_input_sample_ = true;
   }
 
-  HRESULT hr = 0;
+  HRESULT hr = S_OK;
   {
     TRACE_EVENT1("media", "IMFTransform::ProcessInput", "timestamp",
                  input.frame->timestamp());
diff --git a/media/mojo/mojom/stable/stable_video_decoder.mojom b/media/mojo/mojom/stable/stable_video_decoder.mojom
index 79b9af4..c59b7ecd 100644
--- a/media/mojo/mojom/stable/stable_video_decoder.mojom
+++ b/media/mojo/mojom/stable/stable_video_decoder.mojom
@@ -95,6 +95,7 @@
 
 // Based on |media.mojom.VideoDecoder|.
 // Next min method ID: 5
+// Next min version: 2
 [Stable, Uuid="85611470-3e87-43a9-ac75-a11a63e76415"]
 interface StableVideoDecoder {
   // Returns a list of supported configs as well as the decoder ID for the
@@ -129,6 +130,9 @@
   // |cdm_context| is required for the first Initialize() call that sets up
   // encryption and is ignored on subsequent calls.
   //
+  // |needs_transcryption| tells the client whether it needs to do transcryption
+  // for encrypted content before sending it to the decoder.
+  //
   // TODO(b/195769334): consider passing |cdm_context| in Construct() instead of
   // Initialize().
   Initialize@2(VideoDecoderConfig config, bool low_delay,
@@ -136,7 +140,8 @@
       => (Status status,
           bool needs_bitstream_conversion,
           int32 max_decode_requests,
-          VideoDecoderType decoder_type);
+          VideoDecoderType decoder_type,
+          [MinVersion=1] bool needs_transcryption);
 
   // Request decoding of exactly one frame or an EOS buffer. This must not be
   // called while there are pending Initialize(), Reset(), or Decode(EOS)
diff --git a/media/mojo/services/stable_video_decoder_service.cc b/media/mojo/services/stable_video_decoder_service.cc
index 81e445ca..b8ae422 100644
--- a/media/mojo/services/stable_video_decoder_service.cc
+++ b/media/mojo/services/stable_video_decoder_service.cc
@@ -6,6 +6,10 @@
 
 #include "media/mojo/common/media_type_converters.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(USE_VAAPI)
+#include "media/gpu/vaapi/vaapi_wrapper.h"
+#endif
+
 namespace media {
 
 namespace {
@@ -192,10 +196,13 @@
     std::move(callback).Run(DecoderStatus::Codes::kFailedToCreateDecoder,
                             /*needs_bitstream_conversion=*/false,
                             /*max_decode_requests=*/1,
-                            VideoDecoderType::kUnknown);
+                            VideoDecoderType::kUnknown,
+                            /*needs_transcryption=*/false);
     return;
   }
 
+  bool needs_transcryption = false;
+
   // The |config| should have been validated at deserialization time.
   DCHECK(config.IsValidConfig());
   if (config.is_encrypted()) {
@@ -205,7 +212,8 @@
         std::move(callback).Run(DecoderStatus::Codes::kMissingCDM,
                                 /*needs_bitstream_conversion=*/false,
                                 /*max_decode_requests=*/1,
-                                VideoDecoderType::kUnknown);
+                                VideoDecoderType::kUnknown,
+                                /*needs_transcryption=*/false);
         return;
       }
       remote_cdm_context_ = base::WrapRefCounted(
@@ -213,11 +221,16 @@
       cdm_id_ = cdm_service_context_->RegisterRemoteCdmContext(
           remote_cdm_context_.get());
     }
+#if BUILDFLAG(USE_VAAPI)
+    needs_transcryption = (VaapiWrapper::GetImplementationType() ==
+                           VAImplementation::kMesaGallium);
+#endif
 #else
     std::move(callback).Run(DecoderStatus::Codes::kUnsupportedConfig,
                             /*needs_bitstream_conversion=*/false,
                             /*max_decode_requests=*/1,
-                            VideoDecoderType::kUnknown);
+                            VideoDecoderType::kUnknown,
+                            /*needs_transcryption=*/false);
     return;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   }
@@ -225,8 +238,28 @@
   // Even though this is in-process, we still need to pass a |cdm_id_|
   // instead of a media::CdmContext* since this goes through Mojo IPC. This is
   // why we need to register with the |cdm_service_context_| above.
-  dst_video_decoder_remote_->Initialize(config, low_delay, cdm_id_,
-                                        std::move(callback));
+  //
+  // Note: base::Unretained() is safe because *|this| fully owns
+  // |dst_video_decoder_remote_|, so the response callback will never run beyond
+  // the lifetime of *|this|.
+  dst_video_decoder_remote_->Initialize(
+      config, low_delay, cdm_id_,
+      base::BindOnce(&StableVideoDecoderService::OnInitializeDone,
+                     base::Unretained(this), std::move(callback),
+                     needs_transcryption));
+}
+
+void StableVideoDecoderService::OnInitializeDone(
+    InitializeCallback init_cb,
+    bool needs_transcryption,
+    const DecoderStatus& status,
+    bool needs_bitstream_conversion,
+    int32_t max_decode_requests,
+    VideoDecoderType decoder_type) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  std::move(init_cb).Run(status, needs_bitstream_conversion,
+                         max_decode_requests, decoder_type,
+                         needs_transcryption);
 }
 
 void StableVideoDecoderService::Decode(
diff --git a/media/mojo/services/stable_video_decoder_service.h b/media/mojo/services/stable_video_decoder_service.h
index 09e5474a..6428953 100644
--- a/media/mojo/services/stable_video_decoder_service.h
+++ b/media/mojo/services/stable_video_decoder_service.h
@@ -96,6 +96,13 @@
   void AddLogRecord(const MediaLogRecord& event) final;
 
  private:
+  void OnInitializeDone(InitializeCallback init_cb,
+                        bool needs_transcryption,
+                        const DecoderStatus& status,
+                        bool needs_bitstream_conversion,
+                        int32_t max_decode_requests,
+                        VideoDecoderType decoder_type);
+
   mojo::Remote<stable::mojom::StableVideoDecoderTracker> tracker_remote_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
diff --git a/media/mojo/services/stable_video_decoder_service_unittest.cc b/media/mojo/services/stable_video_decoder_service_unittest.cc
index b7524982..5d26290 100644
--- a/media/mojo/services/stable_video_decoder_service_unittest.cc
+++ b/media/mojo/services/stable_video_decoder_service_unittest.cc
@@ -530,7 +530,8 @@
   constexpr absl::optional<base::UnguessableToken> kCdmId = absl::nullopt;
   StrictMock<base::MockOnceCallback<void(
       const media::DecoderStatus& status, bool needs_bitstream_conversion,
-      int32_t max_decode_requests, VideoDecoderType decoder_type)>>
+      int32_t max_decode_requests, VideoDecoderType decoder_type,
+      bool needs_transcryption)>>
       initialize_cb_to_send;
   mojom::VideoDecoder::InitializeCallback received_initialize_cb;
   const DecoderStatus kDecoderStatus = DecoderStatus::Codes::kAborted;
@@ -549,7 +550,7 @@
       });
   EXPECT_CALL(initialize_cb_to_send,
               Run(kDecoderStatus, kNeedsBitstreamConversion, kMaxDecodeRequests,
-                  kDecoderType));
+                  kDecoderType, /*needs_transcryption=*/false));
   stable_video_decoder_remote->Initialize(
       config_to_send, kLowDelay,
       mojo::PendingRemote<stable::mojom::StableCdmContext>(),
@@ -578,13 +579,15 @@
   constexpr bool kLowDelay = true;
   StrictMock<base::MockOnceCallback<void(
       const media::DecoderStatus& status, bool needs_bitstream_conversion,
-      int32_t max_decode_requests, VideoDecoderType decoder_type)>>
+      int32_t max_decode_requests, VideoDecoderType decoder_type,
+      bool needs_transcryption)>>
       initialize_cb_to_send;
 
   EXPECT_CALL(initialize_cb_to_send,
               Run(DecoderStatus(DecoderStatus::Codes::kFailed),
                   /*needs_bitstream_conversion=*/false,
-                  /*max_decode_requests=*/1, VideoDecoderType::kUnknown));
+                  /*max_decode_requests=*/1, VideoDecoderType::kUnknown,
+                  /*needs_transcryption=*/false));
   stable_video_decoder_remote->Initialize(
       config_to_send, kLowDelay,
       mojo::PendingRemote<stable::mojom::StableCdmContext>(),
diff --git a/net/base/features.cc b/net/base/features.cc
index 34c12754..0750947 100644
--- a/net/base/features.cc
+++ b/net/base/features.cc
@@ -318,7 +318,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
 BASE_FEATURE(kKerberosInBrowserRedirect,
              "KerberosInBrowserRedirect",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 #endif
 
 // A flag to use asynchronous session creation for new QUIC sessions.
diff --git a/net/disk_cache/blockfile/block_files.cc b/net/disk_cache/blockfile/block_files.cc
index 98f86cb..e81ff3d6 100644
--- a/net/disk_cache/blockfile/block_files.cc
+++ b/net/disk_cache/blockfile/block_files.cc
@@ -69,7 +69,6 @@
     return false;
   }
 
-  TimeTicks start = TimeTicks::Now();
   // We are going to process the map on 32-block chunks (32 bits), and on every
   // chunk, iterate through the 8 nibbles where the new block can be located.
   int current = header_->hints[target - 1];
@@ -102,7 +101,6 @@
       if (target != size) {
         header_->empty[target - size - 1]++;
       }
-      LOCAL_HISTOGRAM_TIMES("DiskCache.CreateBlock", TimeTicks::Now() - start);
       return true;
     }
   }
@@ -119,7 +117,6 @@
     NOTREACHED();
     return;
   }
-  TimeTicks start = TimeTicks::Now();
   int byte_index = index / 8;
   uint8_t* byte_map = reinterpret_cast<uint8_t*>(header_->allocation_map);
   uint8_t map_block = byte_map[byte_index];
@@ -149,7 +146,6 @@
   std::atomic_thread_fence(std::memory_order_seq_cst);
   header_->num_entries--;
   STRESS_DCHECK(header_->num_entries >= 0);
-  LOCAL_HISTOGRAM_TIMES("DiskCache.DeleteBlock", TimeTicks::Now() - start);
 }
 
 // Note that this is a simplified version of DeleteMapBlock().
@@ -523,7 +519,6 @@
   MappedFile* file = block_files_[block_type - 1].get();
   BlockHeader file_header(file);
 
-  TimeTicks start = TimeTicks::Now();
   while (file_header.NeedToGrowBlockFile(block_count)) {
     if (kMaxBlocks == file_header.Header()->max_entries) {
       file = NextFile(file);
@@ -537,8 +532,6 @@
       return nullptr;
     break;
   }
-  LOCAL_HISTOGRAM_TIMES("DiskCache.GetFileForNewBlock",
-                        TimeTicks::Now() - start);
   return file;
 }
 
@@ -605,7 +598,6 @@
       block_files_[file_index] = nullptr;
 
       int failure = base::DeleteFile(name) ? 0 : 1;
-      UMA_HISTOGRAM_COUNTS_1M("DiskCache.DeleteFailed2", failure);
       if (failure)
         LOG(ERROR) << "Failed to delete " << name.value() << " from the cache.";
       continue;
diff --git a/net/http/http_stream_factory_unittest.cc b/net/http/http_stream_factory_unittest.cc
index 1208e4fd..a017e03 100644
--- a/net/http/http_stream_factory_unittest.cc
+++ b/net/http/http_stream_factory_unittest.cc
@@ -3449,14 +3449,9 @@
     session_context_.quic_context = &quic_context_;
   }
 
- protected:
-  HttpNetworkSessionParams session_params_;
-  HttpNetworkSessionContext session_context_;
-  std::unique_ptr<HttpNetworkSession> session_;
-  HttpServerProperties http_server_properties_;
-  QuicContext quic_context_;
-
  private:
+  // Parameters passed in the NetworkSessionContext must outlive the
+  // HttpNetworkSession.
   std::unique_ptr<ProxyResolutionService> proxy_resolution_service_ =
       ConfiguredProxyResolutionService::CreateDirect();
   SSLConfigServiceDefaults ssl_config_service_;
@@ -3465,6 +3460,14 @@
   MockCertVerifier cert_verifier_;
   TransportSecurityState transport_security_state_;
   DefaultCTPolicyEnforcer ct_policy_enforcer_;
+
+ protected:
+  HttpServerProperties http_server_properties_;
+  QuicContext quic_context_;
+  HttpNetworkSessionParams session_params_;
+  HttpNetworkSessionContext session_context_;
+  std::unique_ptr<HttpNetworkSession> session_;
+
 };
 
 TEST_F(ProcessAlternativeServicesTest, ProcessEmptyAltSvc) {
diff --git a/remoting/host/chromeos/features.cc b/remoting/host/chromeos/features.cc
index a2ce667..5eeb2cd 100644
--- a/remoting/host/chromeos/features.cc
+++ b/remoting/host/chromeos/features.cc
@@ -20,4 +20,8 @@
              "EnableFrameSinkDesktopCapturerInCrd",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+BASE_FEATURE(kEnableCrdFileTransferForKiosk,
+             "EnableCrdFileTransferForKiosk",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 }  // namespace remoting::features
diff --git a/remoting/host/chromeos/features.h b/remoting/host/chromeos/features.h
index b299a50..4278a2c5 100644
--- a/remoting/host/chromeos/features.h
+++ b/remoting/host/chromeos/features.h
@@ -20,6 +20,9 @@
 // Enable to allow FrameSinkDesktopCapturer to be used for CRD video streaming.
 BASE_DECLARE_FEATURE(kEnableFrameSinkDesktopCapturerInCrd);
 
+// Enable to allow file transfer in CRD video streaming to Kiosk devices.
+BASE_DECLARE_FEATURE(kEnableCrdFileTransferForKiosk);
+
 }  // namespace remoting::features
 
 #endif  // REMOTING_HOST_CHROMEOS_FEATURES_H_
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc
index 0550c2f..b3aa3105 100644
--- a/remoting/host/client_session.cc
+++ b/remoting/host/client_session.cc
@@ -187,7 +187,10 @@
     for (const auto& [_, video_stream] : video_streams_) {
       video_stream->SetTargetFramerate(target_framerate_);
     }
-    mouse_shape_pump_->SetCursorCaptureInterval(base::Hertz(target_framerate_));
+    if (mouse_shape_pump_) {
+      mouse_shape_pump_->SetCursorCaptureInterval(
+          base::Hertz(target_framerate_));
+    }
   }
 
   if (video_control.has_framerate_boost()) {
@@ -667,6 +670,7 @@
       desktop_environment_->CreateMouseCursorMonitor(),
       connection_->client_stub());
   mouse_shape_pump_->SetMouseCursorMonitorCallback(this);
+  mouse_shape_pump_->SetCursorCaptureInterval(base::Hertz(target_framerate_));
 
   // Create KeyboardLayoutMonitor to send keyboard layout.
   // Unretained is sound because callback will never be called after
diff --git a/remoting/host/security_key/security_key_extension_session.cc b/remoting/host/security_key/security_key_extension_session.cc
index 612719d..24bba7c 100644
--- a/remoting/host/security_key/security_key_extension_session.cc
+++ b/remoting/host/security_key/security_key_extension_session.cc
@@ -161,7 +161,8 @@
   std::string response;
   const base::Value::List* bytes_list = message_data.FindList(kDataPayload);
   if (bytes_list && ConvertListToString(*bytes_list, &response)) {
-    HOST_LOG << "Sending security key response: " << GetCommandCode(response);
+    HOST_LOG << "Processing security key response: "
+             << GetCommandCode(response);
     security_key_auth_handler_->SendClientResponse(connection_id, response);
   } else {
     LOG(WARNING) << "Could not extract response data from message.";
@@ -193,6 +194,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(client_stub_);
 
+  HOST_LOG << "Sending security key request: " << GetCommandCode(data);
+
   base::Value::Dict request_dict;
   request_dict.Set(kMessageType, kDataMessage);
   request_dict.Set(kConnectionId, connection_id);
diff --git a/remoting/host/security_key/security_key_ipc_client.cc b/remoting/host/security_key/security_key_ipc_client.cc
index 96215f6..1b666313 100644
--- a/remoting/host/security_key/security_key_ipc_client.cc
+++ b/remoting/host/security_key/security_key_ipc_client.cc
@@ -13,6 +13,7 @@
 #include "base/logging.h"
 #include "base/task/single_thread_task_runner.h"
 #include "build/build_config.h"
+#include "remoting/base/logging.h"
 #include "remoting/host/chromoting_host_services_client.h"
 #include "remoting/host/security_key/security_key_ipc_constants.h"
 
@@ -83,18 +84,21 @@
 
 void SecurityKeyIpcClient::CloseIpcConnection() {
   DCHECK(thread_checker_.CalledOnValidThread());
+  HOST_LOG << "IPC connection closed.";
   security_key_forwarder_.reset();
 }
 
 void SecurityKeyIpcClient::OnQueryVersionResult(uint32_t unused_version) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
+  HOST_LOG << "IPC channel connected.";
   std::move(connected_callback_).Run();
 }
 
 void SecurityKeyIpcClient::OnChannelError() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
+  LOG(ERROR) << "IPC channel error.";
   security_key_forwarder_.reset();
   if (connection_error_callback_) {
     std::move(connection_error_callback_).Run();
diff --git a/remoting/host/security_key/security_key_message_handler.cc b/remoting/host/security_key/security_key_message_handler.cc
index bf5d830..0647acc 100644
--- a/remoting/host/security_key/security_key_message_handler.cc
+++ b/remoting/host/security_key/security_key_message_handler.cc
@@ -12,6 +12,7 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/logging.h"
+#include "remoting/base/logging.h"
 #include "remoting/host/security_key/security_key_ipc_client.h"
 #include "remoting/host/security_key/security_key_ipc_constants.h"
 #include "remoting/host/security_key/security_key_message_reader_impl.h"
@@ -74,6 +75,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   SecurityKeyMessageType message_type = message->type();
+  HOST_LOG << "Received message from pipe. type="
+           << static_cast<int>(message_type);
   if (message_type == SecurityKeyMessageType::CONNECT) {
     HandleConnectRequest(message->payload());
   } else if (message_type == SecurityKeyMessageType::REQUEST) {
@@ -168,7 +171,12 @@
     SecurityKeyMessageType message_type,
     const std::string& message_payload) {
   if (!writer_->WriteMessageWithPayload(message_type, message_payload)) {
+    HOST_LOG << "Failed to send message to pipe. type="
+             << static_cast<int>(message_type);
     OnError();
+  } else {
+    HOST_LOG << "Successfully sent message to pipe. type="
+             << static_cast<int>(message_type);
   }
 }
 
diff --git a/services/device/public/cpp/bluetooth/BUILD.gn b/services/device/public/cpp/bluetooth/BUILD.gn
index 2470ecf5..3b42a79 100644
--- a/services/device/public/cpp/bluetooth/BUILD.gn
+++ b/services/device/public/cpp/bluetooth/BUILD.gn
@@ -2,11 +2,15 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-source_set("bluetooth") {
+component("bluetooth") {
   sources = [
     "bluetooth_utils.cc",
     "bluetooth_utils.h",
   ]
+  defines = [ "IS_BLUETOOTH_IMPL=1" ]
 
-  deps = [ "//device/bluetooth/public/cpp:cpp" ]
+  deps = [
+    "//base",
+    "//device/bluetooth/public/cpp",
+  ]
 }
diff --git a/services/device/public/cpp/bluetooth/bluetooth_utils.h b/services/device/public/cpp/bluetooth/bluetooth_utils.h
index 2cecfa9..1fc1c31 100644
--- a/services/device/public/cpp/bluetooth/bluetooth_utils.h
+++ b/services/device/public/cpp/bluetooth/bluetooth_utils.h
@@ -5,12 +5,13 @@
 #ifndef SERVICES_DEVICE_PUBLIC_CPP_BLUETOOTH_BLUETOOTH_UTILS_H_
 #define SERVICES_DEVICE_PUBLIC_CPP_BLUETOOTH_BLUETOOTH_UTILS_H_
 
+#include "base/component_export.h"
 #include "device/bluetooth/public/cpp/bluetooth_uuid.h"
 
 namespace device {
 
 // Returns a BluetoothUUID for a Bluetooth SPP device.
-const BluetoothUUID& GetSerialPortProfileUUID();
+COMPONENT_EXPORT(BLUETOOTH) const BluetoothUUID& GetSerialPortProfileUUID();
 
 }  // namespace device
 
diff --git a/services/device/public/mojom/BUILD.gn b/services/device/public/mojom/BUILD.gn
index ead4c12..515a2ce 100644
--- a/services/device/public/mojom/BUILD.gn
+++ b/services/device/public/mojom/BUILD.gn
@@ -38,6 +38,7 @@
   ]
 
   public_deps = [
+    "//device/bluetooth/public/mojom",
     "//mojo/public/mojom/base",
     "//services/network/public/mojom",
     "//services/network/public/mojom:mojom_proxy_config",
diff --git a/services/device/public/mojom/serial.mojom b/services/device/public/mojom/serial.mojom
index 070d8f82..ee2f7cc 100644
--- a/services/device/public/mojom/serial.mojom
+++ b/services/device/public/mojom/serial.mojom
@@ -4,6 +4,7 @@
 
 module device.mojom;
 
+import "device/bluetooth/public/mojom/uuid.mojom";
 import "mojo/public/mojom/base/file_path.mojom";
 import "mojo/public/mojom/base/unguessable_token.mojom";
 
@@ -11,9 +12,8 @@
   mojo_base.mojom.UnguessableToken token;
   mojo_base.mojom.FilePath path;
 
-  // This member is used to identify whether the SerialPortInfo object is
-  // converted from a Bluetooth serial device.
-  DeviceType type = PLATFORM_SERIAL;
+  // The backend implementation for the serial port.
+  SerialPortType type = PLATFORM_SERIAL;
 
   // On macOS a serial device may have two paths, one for the call-out device
   // and one for the dial-in device. The call-out device is preferred. If
@@ -35,8 +35,14 @@
   uint16 product_id;
   bool has_product_id = false;
 
+  // The Bluetooth service class ID of the port if the port is from a Bluetooth
+  // device. It is a 128-bit canonical UUID.
+  bluetooth.mojom.UUID? bluetooth_service_class_id;
+
   // A string suitable for display to the user for describing this device. May
   // be, for example, the USB device product name string.
+  // If no display_name is provided, the path will be displayed to the user
+  // instead.
   string? display_name;
 
   // The USB device serial number.
@@ -95,11 +101,11 @@
   kTransmit,
 };
 
-enum DeviceType {
-  // The SerialPortInfo object is created from a serial device.
+enum SerialPortType {
+  // The serial port is implemented using the platform's serial device API.
   PLATFORM_SERIAL,
-  // The SerialPortInfo object is created from a Bluetooth SPP device.
-  SPP_DEVICE,
+  // The serial port is implemented using the Bluetooth classic RFCOMM protocol.
+  BLUETOOTH_CLASSIC_RFCOMM,
 };
 
 struct SerialConnectionOptions {
diff --git a/services/device/serial/bluetooth_serial_device_enumerator.cc b/services/device/serial/bluetooth_serial_device_enumerator.cc
index 31f54856..c47d934 100644
--- a/services/device/serial/bluetooth_serial_device_enumerator.cc
+++ b/services/device/serial/bluetooth_serial_device_enumerator.cc
@@ -19,6 +19,22 @@
 
 namespace device {
 
+namespace {
+
+mojom::SerialPortInfoPtr CreatePort(base::StringPiece device_address,
+                                    base::StringPiece16 device_name,
+                                    const BluetoothUUID& service_class_id) {
+  auto port = mojom::SerialPortInfo::New();
+  port->token = base::UnguessableToken::Create();
+  port->path = base::FilePath::FromUTF8Unsafe(device_address);
+  port->type = mojom::SerialPortType::BLUETOOTH_CLASSIC_RFCOMM;
+  port->bluetooth_service_class_id = service_class_id;
+  port->display_name = base::UTF16ToUTF8(device_name);
+  return port;
+}
+
+}  // namespace
+
 // Helper class to interact with the BluetoothAdapter which must be accessed
 // on a specific sequence.
 class BluetoothSerialDeviceEnumerator::AdapterHelper
@@ -140,19 +156,8 @@
   if (base::Contains(device_ports_, key))
     return;
 
-  auto port = mojom::SerialPortInfo::New();
-  port->token = base::UnguessableToken::Create();
-  port->path = base::FilePath::FromUTF8Unsafe(device_address);
-  port->type = mojom::DeviceType::SPP_DEVICE;
-  // TODO(crbug.com/1261557): Use better name.
-  // Using service class ID for development to disambiguate device services.
-  const std::string device_name_utf8 = base::UTF16ToUTF8(device_name);
-  if (service_class_id == GetSerialPortProfileUUID()) {
-    port->display_name = device_name_utf8;
-  } else {
-    port->display_name = base::StringPrintf("%s [%s]", device_name_utf8.c_str(),
-                                            service_class_id.value().c_str());
-  }
+  auto port = CreatePort(device_address, device_name, service_class_id);
+
   device_ports_.insert(std::make_pair(std::move(key), port->token));
   AddPort(std::move(port));
 }
diff --git a/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc b/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc
index c09d3eb3..db3ddc3 100644
--- a/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc
+++ b/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc
@@ -144,7 +144,8 @@
                     serial_port_info.path);
           EXPECT_EQ(kTestDeviceName, serial_port_info.display_name);
           EXPECT_EQ(absl::nullopt, serial_port_info.serial_number);
-          EXPECT_EQ(mojom::DeviceType::SPP_DEVICE, serial_port_info.type);
+          EXPECT_EQ(mojom::SerialPortType::BLUETOOTH_CLASSIC_RFCOMM,
+                    serial_port_info.type);
           EXPECT_FALSE(serial_port_info.has_vendor_id);
           EXPECT_EQ(0x0, serial_port_info.vendor_id);
           EXPECT_FALSE(serial_port_info.has_product_id);
diff --git a/services/device/serial/serial_port_manager_impl_unittest.cc b/services/device/serial/serial_port_manager_impl_unittest.cc
index 0b70314..8a10a3b2 100644
--- a/services/device/serial/serial_port_manager_impl_unittest.cc
+++ b/services/device/serial/serial_port_manager_impl_unittest.cc
@@ -381,7 +381,8 @@
         .WillOnce(Invoke([&](mojom::SerialPortInfoPtr port) {
           EXPECT_EQ(port1_token, port->token);
           EXPECT_EQ(port->path, base::FilePath::FromASCII(kDeviceAddress));
-          EXPECT_EQ(mojom::DeviceType::SPP_DEVICE, port->type);
+          EXPECT_EQ(mojom::SerialPortType::BLUETOOTH_CLASSIC_RFCOMM,
+                    port->type);
           run_loop.Quit();
         }));
     run_loop.Run();
@@ -401,7 +402,8 @@
         .WillOnce(Invoke([&](mojom::SerialPortInfoPtr port) {
           EXPECT_NE(port1_token, port->token);
           EXPECT_EQ(port->path, base::FilePath::FromASCII(kDeviceAddress));
-          EXPECT_EQ(mojom::DeviceType::SPP_DEVICE, port->type);
+          EXPECT_EQ(mojom::SerialPortType::BLUETOOTH_CLASSIC_RFCOMM,
+                    port->type);
           run_loop.Quit();
         }));
     run_loop.Run();
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc
index 412d5136..71eba8c 100644
--- a/services/network/cors/cors_url_loader.cc
+++ b/services/network/cors/cors_url_loader.cc
@@ -525,14 +525,13 @@
     }
   }
 
-  if (shared_dictionary_storage_ && (IsCorsEnabledRequestMode(request_.mode))) {
+  if (request_.shared_dictionary_writer_enabled && shared_dictionary_storage_ &&
+      (IsCorsEnabledRequestMode(request_.mode))) {
     // The compressed dictionary transport feature currently supports storing
     // dictionaries only if the request was fetched using Cors enabled mode.
     // Note: We may extend this support in future (For example, same-origin mode
     // requests, responses containing a valid Access-Control-Allow-Origin header
     // even if the request mode was not Cors.)
-    // TODO(crbug.com/1413922): Check the Origin Trial state flag of
-    // CompressionDictionaryTransport which will be set in ResourceRequest.
     auto writer = shared_dictionary_storage_->MaybeCreateWriter(
         request_.url, response_head->response_time, *response_head->headers);
     if (writer) {
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index cb61809..12a9319 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -9,6 +9,7 @@
 #include "base/debug/crash_logging.h"
 #include "base/functional/bind.h"
 #include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/types/optional_util.h"
 #include "mojo/public/cpp/bindings/message.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -215,7 +216,8 @@
     DCHECK_EQ(mojom::kBrowserProcessId, process_id_);
   }
 
-  if (context_->GetSharedDictionaryManager()) {
+  if (context_->GetSharedDictionaryManager() && client_security_state_ &&
+      client_security_state_->is_web_secure_context) {
     absl::optional<net::SharedDictionaryStorageIsolationKey> isolation_key =
         net::SharedDictionaryStorageIsolationKey::MaybeCreate(
             params->isolation_info);
@@ -284,6 +286,14 @@
     const ResourceRequest& resource_request,
     mojo::PendingRemote<mojom::URLLoaderClient> client,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
+#if BUILDFLAG(IS_ANDROID)
+  // Use pseudo flag to investigate histogram issue.
+  // See https://crbug.com/1439721.
+  const bool observed = true;
+  base::UmaHistogramBoolean("NetworkService.CorsURLLoaderFactoryStart",
+                            observed);
+#endif
+
   debug::ScopedResourceRequestCrashKeys request_crash_keys(resource_request);
   SCOPED_CRASH_KEY_NUMBER("net", "traffic_annotation_hash",
                           traffic_annotation.unique_id_hash_code);
diff --git a/services/network/cors/cors_url_loader_shared_dictionary_unittest.cc b/services/network/cors/cors_url_loader_shared_dictionary_unittest.cc
index 31d88757..ba0bffb1 100644
--- a/services/network/cors/cors_url_loader_shared_dictionary_unittest.cc
+++ b/services/network/cors/cors_url_loader_shared_dictionary_unittest.cc
@@ -13,6 +13,7 @@
 #include "services/network/shared_dictionary/shared_dictionary_manager.h"
 #include "services/network/shared_dictionary/shared_dictionary_storage.h"
 #include "services/network/shared_dictionary/shared_dictionary_storage_in_memory.h"
+#include "services/network/test/client_security_state_builder.h"
 #include "services/network/test/test_url_loader_client.h"
 #include "url/scheme_host_port.h"
 
@@ -40,19 +41,25 @@
       const CorsURLLoaderSharedDictionaryTest&) = delete;
 
  protected:
-  void ResetFactory() {
+  void ResetFactory(bool is_web_secure_context = true) {
     ResetFactoryParams factory_params;
     factory_params.isolation_info = isolation_info_;
+    factory_params.client_security_state =
+        ClientSecurityStateBuilder()
+            .WithIsSecureContext(is_web_secure_context)
+            .Build();
     CorsURLLoaderTestBase::ResetFactory(isolation_info_.frame_origin(),
                                         kRendererProcessId, factory_params);
   }
 
-  ResourceRequest CreateResourceRequest() {
+  ResourceRequest CreateResourceRequest(
+      bool shared_dictionary_writer_enabled = true) {
     ResourceRequest request;
     request.method = "GET";
     request.mode = mojom::RequestMode::kCors;
     request.url = GURL("https://origin.test/test");
     request.request_initiator = isolation_info_.frame_origin();
+    request.shared_dictionary_writer_enabled = shared_dictionary_writer_enabled;
     return request;
   }
 
@@ -380,4 +387,43 @@
   CheckDictionaryInStorage(/*expect_exists=*/true);
 }
 
+TEST_F(CorsURLLoaderSharedDictionaryTest, InsecureContext) {
+  ResetFactory(/*is_web_secure_context=*/false);
+
+  ResourceRequest request = CreateResourceRequest();
+  EXPECT_EQ(mojom::RequestMode::kCors, request.mode);
+  CreateLoaderAndStart(request);
+  RunUntilCreateLoaderAndStartCalled();
+
+  CreateDataPipeAndWriteTestData();
+  CallOnReceiveResponseAndOnCompleteAndFinishBody();
+
+  RunUntilComplete();
+  EXPECT_EQ(net::OK, client().completion_status().error_code);
+
+  // The response of should be stored to the dictionary storage because the web
+  // context is not secure.
+  CheckDictionaryInStorage(/*expect_exists=*/false);
+}
+
+TEST_F(CorsURLLoaderSharedDictionaryTest, SharedDictionaryWriterDisabled) {
+  ResetFactory();
+
+  ResourceRequest request =
+      CreateResourceRequest(/*shared_dictionary_writer_enabled=*/false);
+  EXPECT_EQ(mojom::RequestMode::kCors, request.mode);
+  CreateLoaderAndStart(request);
+  RunUntilCreateLoaderAndStartCalled();
+
+  CreateDataPipeAndWriteTestData();
+  CallOnReceiveResponseAndOnCompleteAndFinishBody();
+
+  RunUntilComplete();
+  EXPECT_EQ(net::OK, client().completion_status().error_code);
+
+  // The response of should be stored to the dictionary storage because shared
+  // dictionary writer is disabled.
+  CheckDictionaryInStorage(/*expect_exists=*/false);
+}
+
 }  // namespace network::cors
diff --git a/services/network/network_service.cc b/services/network/network_service.cc
index f25bf2e0..a1db27ca4 100644
--- a/services/network/network_service.cc
+++ b/services/network/network_service.cc
@@ -358,6 +358,11 @@
 
   initialized_ = true;
 
+#if BUILDFLAG(IS_ANDROID)
+  base::UmaHistogramTimes("NetworkService.InitializedTime",
+                          base::Time::Now().since_origin());
+#endif
+
 #if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_ARMEL)
   // Make sure OpenSSL is initialized before using it to histogram data.
   crypto::EnsureOpenSSLInit();
diff --git a/services/network/public/cpp/network_switches.cc b/services/network/public/cpp/network_switches.cc
index c1f7f6e..e90916d 100644
--- a/services/network/public/cpp/network_switches.cc
+++ b/services/network/public/cpp/network_switches.cc
@@ -37,6 +37,23 @@
 const char kIgnoreCertificateErrorsSPKIList[] =
     "ignore-certificate-errors-spki-list";
 
+// Specifies a proxy server for origins specified in
+// kIPAnonymizationProxyAllowList. This proxy will be used on a best-effort
+// basis when normal proxy resolution would result in trying direct connections
+// (possibly after trying some other proxy server).
+const char kIPAnonymizationProxyServer[] = "ip-anonymization-proxy-server";
+
+// Specifies a list of origins on which to use the server specified by
+// `kIPAnonymizationProxyServer`. if `kIPAnonymizationProxyServer` is empty this
+// list will be ignored. This is intended as a reverse bypass rules list.
+const char kIPAnonymizationProxyAllowList[] =
+    "ip-anonymization-proxy-allow-list";
+
+// Specifies a value for the "password" header to be passed to the proxy
+// specified by `kIPAnonymizationProxyServer`. if `kIPAnonymizationProxyServer`
+// is empty this list will be ignored.
+const char kIPAnonymizationProxyPassword[] = "ip-anonymization-proxy-password";
+
 // Enables saving net log events to a file. If a value is given, it used as the
 // path the the file, otherwise the file is named netlog.json and placed in the
 // user data directory.
diff --git a/services/network/public/cpp/network_switches.h b/services/network/public/cpp/network_switches.h
index 3b3f067..e6675d48 100644
--- a/services/network/public/cpp/network_switches.h
+++ b/services/network/public/cpp/network_switches.h
@@ -18,6 +18,10 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const char kIgnoreCertificateErrorsSPKIList[];
 COMPONENT_EXPORT(NETWORK_CPP) extern const char kIgnoreUrlFetcherCertRequests[];
+COMPONENT_EXPORT(NETWORK_CPP) extern const char kIPAnonymizationProxyServer[];
+COMPONENT_EXPORT(NETWORK_CPP)
+extern const char kIPAnonymizationProxyAllowList[];
+COMPONENT_EXPORT(NETWORK_CPP) extern const char kIPAnonymizationProxyPassword[];
 COMPONENT_EXPORT(NETWORK_CPP) extern const char kLogNetLog[];
 COMPONENT_EXPORT(NETWORK_CPP) extern const char kNetLogCaptureMode[];
 COMPONENT_EXPORT(NETWORK_CPP) extern const char kSSLKeyLogFile[];
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc
index f59007a..1e15e62d 100644
--- a/services/network/public/cpp/resource_request.cc
+++ b/services/network/public/cpp/resource_request.cc
@@ -282,7 +282,9 @@
                                             request.net_log_create_info) &&
          OptionalNetLogInfoEqualsForTesting(net_log_reference_info,
                                             request.net_log_reference_info) &&
-         target_ip_address_space == request.target_ip_address_space;
+         target_ip_address_space == request.target_ip_address_space &&
+         shared_dictionary_writer_enabled ==
+             request.shared_dictionary_writer_enabled;
 }
 
 bool ResourceRequest::SendsCookies() const {
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h
index b4d389b1..185c4ba2 100644
--- a/services/network/public/cpp/resource_request.h
+++ b/services/network/public/cpp/resource_request.h
@@ -202,6 +202,7 @@
       mojom::AttributionReportingEligibility::kUnset;
   network::AttributionReportingRuntimeFeatures
       attribution_reporting_runtime_features;
+  bool shared_dictionary_writer_enabled = false;
 };
 
 // This does not accept |kDefault| referrer policy.
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
index b2d4065f..07fd0387 100644
--- a/services/network/public/cpp/url_request_mojom_traits.cc
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -230,6 +230,8 @@
   out->attribution_reporting_support = data.attribution_reporting_support();
   out->attribution_reporting_eligibility =
       data.attribution_reporting_eligibility();
+  out->shared_dictionary_writer_enabled =
+      data.shared_dictionary_writer_enabled();
   return true;
 }
 
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h
index 088c805..d49c105 100644
--- a/services/network/public/cpp/url_request_mojom_traits.h
+++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -394,6 +394,10 @@
       const network::ResourceRequest& request) {
     return request.attribution_reporting_runtime_features;
   }
+  static bool shared_dictionary_writer_enabled(
+      const network::ResourceRequest& request) {
+    return request.shared_dictionary_writer_enabled;
+  }
 
   static bool Read(network::mojom::URLRequestDataView data,
                    network::ResourceRequest* out);
diff --git a/services/network/public/mojom/url_request.mojom b/services/network/public/mojom/url_request.mojom
index c9a4e16..4767f2af 100644
--- a/services/network/public/mojom/url_request.mojom
+++ b/services/network/public/mojom/url_request.mojom
@@ -520,6 +520,12 @@
   // TODO(https://crbug.com/1443602): Get rid of this with proper OT
   // infrastructure support in the network service.
   AttributionReportingRuntimeFeatures attribution_reporting_runtime_features;
+
+  // Indicate the state of CompressionDictionaryTransport feature. When it is
+  // true, `use-as-dictionary` response HTTP header may be processed.
+  // TODO(crbug.com/1413922): Remove this flag when we launch
+  // CompressionDictionaryTransport feature.
+  bool shared_dictionary_writer_enabled = false;
 };
 
 // URLRequestBody represents body (i.e. upload data) of a HTTP request.
diff --git a/services/network/test/url_loader_context_for_tests.cc b/services/network/test/url_loader_context_for_tests.cc
index 805f89a1..c75cfd0 100644
--- a/services/network/test/url_loader_context_for_tests.cc
+++ b/services/network/test/url_loader_context_for_tests.cc
@@ -9,7 +9,7 @@
 URLLoaderContextForTests::URLLoaderContextForTests() = default;
 URLLoaderContextForTests::~URLLoaderContextForTests() = default;
 
-bool URLLoaderContextForTests::ShouldRequireNetworkIsolationKey() const {
+bool URLLoaderContextForTests::ShouldRequireIsolationInfo() const {
   return false;
 }
 
diff --git a/services/network/test/url_loader_context_for_tests.h b/services/network/test/url_loader_context_for_tests.h
index 5a2f2db2..0c8cce3 100644
--- a/services/network/test/url_loader_context_for_tests.h
+++ b/services/network/test/url_loader_context_for_tests.h
@@ -38,7 +38,7 @@
   }
 
   // URLLoaderContext implementation.
-  bool ShouldRequireNetworkIsolationKey() const override;
+  bool ShouldRequireIsolationInfo() const override;
   const cors::OriginAccessList& GetOriginAccessList() const override;
   const mojom::URLLoaderFactoryParams& GetFactoryParams() const override;
   mojom::CookieAccessObserver* GetCookieAccessObserver() const override;
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 7319494..73955b10 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -606,8 +606,9 @@
   if (isolation_info)
     url_request_->set_isolation_info(isolation_info.value());
 
-  if (context.ShouldRequireNetworkIsolationKey())
+  if (context.ShouldRequireIsolationInfo()) {
     DCHECK(!url_request_->isolation_info().IsEmpty());
+  }
 
   if (ShouldForceIgnoreTopFramePartyForCookies())
     url_request_->set_force_ignore_top_frame_party_for_cookies(true);
@@ -1726,15 +1727,19 @@
     return;
   }
 
-  // Enforce FLEDGE auction-only signals -- the renderer process isn't allowed
-  // to read auction-only signals for FLEDGE auctions; only the browser process
+  // Enforce ad-auction-only signals -- the renderer process isn't allowed
+  // to read auction-only signals for ad auctions; only the browser process
   // is allowed to read those, and only the browser process can issue trusted
   // requests.
-  std::string fledge_auction_only_signals;
+  std::string auction_only;
+  // TODO(crbug.com/1448564): Remove old names once API users have migrated to
+  // new names.
   if (!factory_params_->is_trusted && response_->headers &&
-      response_->headers->GetNormalizedHeader("X-FLEDGE-Auction-Only",
-                                              &fledge_auction_only_signals) &&
-      base::EqualsCaseInsensitiveASCII(fledge_auction_only_signals, "true")) {
+      (response_->headers->GetNormalizedHeader("Ad-Auction-Only",
+                                               &auction_only) ||
+       response_->headers->GetNormalizedHeader("X-FLEDGE-Auction-Only",
+                                               &auction_only)) &&
+      base::EqualsCaseInsensitiveASCII(auction_only, "true")) {
     CompleteBlockedResponse(net::ERR_BLOCKED_BY_RESPONSE, false);
     url_request_->AbortAndCloseConnection();
     DeleteSelf();
diff --git a/services/network/url_loader_context.h b/services/network/url_loader_context.h
index c8fafa2..8f59ee4 100644
--- a/services/network/url_loader_context.h
+++ b/services/network/url_loader_context.h
@@ -36,7 +36,7 @@
 // by URLLoaderContextForTests in unit tests).
 class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoaderContext {
  public:
-  virtual bool ShouldRequireNetworkIsolationKey() const = 0;
+  virtual bool ShouldRequireIsolationInfo() const = 0;
   virtual const cors::OriginAccessList& GetOriginAccessList() const = 0;
   virtual const mojom::URLLoaderFactoryParams& GetFactoryParams() const = 0;
   virtual mojom::CookieAccessObserver* GetCookieAccessObserver() const = 0;
diff --git a/services/network/url_loader_factory.cc b/services/network/url_loader_factory.cc
index 58719917..586a7528 100644
--- a/services/network/url_loader_factory.cc
+++ b/services/network/url_loader_factory.cc
@@ -150,7 +150,7 @@
   return cors_url_loader_factory_->coep_reporter();
 }
 
-bool URLLoaderFactory::ShouldRequireNetworkIsolationKey() const {
+bool URLLoaderFactory::ShouldRequireIsolationInfo() const {
   return context_->require_network_anonymization_key();
 }
 
diff --git a/services/network/url_loader_factory.h b/services/network/url_loader_factory.h
index 2c2e820..73a4c65 100644
--- a/services/network/url_loader_factory.h
+++ b/services/network/url_loader_factory.h
@@ -68,7 +68,7 @@
   void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override;
 
   // URLLoaderContext implementation.
-  bool ShouldRequireNetworkIsolationKey() const override;
+  bool ShouldRequireIsolationInfo() const override;
   const cors::OriginAccessList& GetOriginAccessList() const override;
   const mojom::URLLoaderFactoryParams& GetFactoryParams() const override;
   mojom::CookieAccessObserver* GetCookieAccessObserver() const override;
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index 65ff5f3..04436c6b 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -7013,7 +7013,11 @@
   EXPECT_FALSE(socket_data.socket());
 }
 
-TEST_F(URLLoaderMockSocketTest,
+class URLLoaderMockSocketAuctionOnlyTest
+    : public URLLoaderMockSocketTest,
+      public testing::WithParamInterface<std::string> {};
+
+TEST_P(URLLoaderMockSocketAuctionOnlyTest,
        FetchAuctionOnlySignalsFromRendererClosesSocket) {
   auto client_security_state = NewSecurityState();
   client_security_state->local_network_request_policy =
@@ -7028,13 +7032,15 @@
                      "User-Agent: \r\n"
                      "Accept-Encoding: gzip, deflate\r\n\r\n"),
   };
+  const std::string first_read = base::StringPrintf(
+      "HTTP/1.1 200 OK\r\n"
+      "Connection: keep-alive\r\n"
+      "%s"
+      "Content-Type: text/plain\r\n"
+      "Content-Length: 23\r\n\r\n",
+      GetParam().c_str());
   net::MockRead kReads[] = {
-      net::MockRead(net::SYNCHRONOUS, 1,
-                    "HTTP/1.1 200 OK\r\n"
-                    "Connection: keep-alive\r\n"
-                    "X-FLEDGE-Auction-Only: true\r\n"
-                    "Content-Type: text/plain\r\n"
-                    "Content-Length: 23\r\n\r\n"),
+      net::MockRead(net::SYNCHRONOUS, 1, first_read.c_str()),
       net::MockRead(net::SYNCHRONOUS, 2, "This should not be read"),
   };
 
@@ -7055,7 +7061,7 @@
   EXPECT_FALSE(socket_data.socket());
 }
 
-TEST_F(URLLoaderMockSocketTest,
+TEST_P(URLLoaderMockSocketAuctionOnlyTest,
        FetchAuctionOnlySignalsFromBrowserProcessSucceeds) {
   auto client_security_state = NewSecurityState();
   client_security_state->local_network_request_policy =
@@ -7070,13 +7076,15 @@
                      "User-Agent: \r\n"
                      "Accept-Encoding: gzip, deflate\r\n\r\n"),
   };
+  const std::string first_read = base::StringPrintf(
+      "HTTP/1.1 200 OK\r\n"
+      "Connection: keep-alive\r\n"
+      "%s"
+      "Content-Type: text/plain\r\n"
+      "Content-Length: 23\r\n\r\n",
+      GetParam().c_str());
   net::MockRead kReads[] = {
-      net::MockRead(net::SYNCHRONOUS, 1,
-                    "HTTP/1.1 200 OK\r\n"
-                    "Connection: keep-alive\r\n"
-                    "X-FLEDGE-Auction-Only: true\r\n"
-                    "Content-Type: text/plain\r\n"
-                    "Content-Length: 23\r\n\r\n"),
+      net::MockRead(net::SYNCHRONOUS, 1, first_read.c_str()),
       net::MockRead(net::SYNCHRONOUS, 2, "This should not be read"),
   };
 
@@ -7094,6 +7102,16 @@
   EXPECT_TRUE(socket_data.socket());
 }
 
+// TODO(crbug.com/1448564): Remove old names once API users have migrated to new
+// names.
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    URLLoaderMockSocketAuctionOnlyTest,
+    testing::Values(
+        "Ad-Auction-Only: true\r\n",
+        "X-FLEDGE-Auction-Only: true\r\n",
+        "Ad-Auction-Only: true\r\nX-FLEDGE-Auction-Only: true\r\n"));
+
 TEST_F(URLLoaderMockSocketTest, PrivateNetworkRequestPolicyDoesNotCloseSocket) {
   auto client_security_state = NewSecurityState();
   client_security_state->local_network_request_policy =
diff --git a/services/network/web_bundle/web_bundle_url_loader_factory.cc b/services/network/web_bundle/web_bundle_url_loader_factory.cc
index eba6b4fb..4b411ba 100644
--- a/services/network/web_bundle/web_bundle_url_loader_factory.cc
+++ b/services/network/web_bundle/web_bundle_url_loader_factory.cc
@@ -889,15 +889,19 @@
     return;
   }
 
-  // Enforce FLEDGE auction-only signals -- the renderer process isn't allowed
-  // to read auction-only signals for FLEDGE auctions; only the browser process
+  // Enforce ad-auction-only signals -- the renderer process isn't allowed
+  // to read auction-only signals for ad auctions; only the browser process
   // is allowed to read those, and only the browser process can issue trusted
   // requests.
-  std::string fledge_auction_only_signals;
+  std::string auction_only;
+  // TODO(crbug.com/1448564): Remove old names once API users have migrated to
+  // new names.
   if (!loader->is_trusted() && response_head->headers &&
-      response_head->headers->GetNormalizedHeader(
-          "X-FLEDGE-Auction-Only", &fledge_auction_only_signals) &&
-      base::EqualsCaseInsensitiveASCII(fledge_auction_only_signals, "true")) {
+      (response_head->headers->GetNormalizedHeader("Ad-Auction-Only",
+                                                   &auction_only) ||
+       response_head->headers->GetNormalizedHeader("X-FLEDGE-Auction-Only",
+                                                   &auction_only)) &&
+      base::EqualsCaseInsensitiveASCII(auction_only, "true")) {
     loader->CompleteBlockedResponse(net::ERR_BLOCKED_BY_RESPONSE,
                                     /*reason=*/absl::nullopt);
     return;
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index edf9373..47ca3a3 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -50,10 +50,7 @@
     "SK_DISABLE_LEGACY_SKSURFACE_METHODS",
     "SK_DISABLE_LEGACY_GRAPHITE_IMAGE_FACTORIES",
     "SK_DISABLE_LEGACY_GRAPHITE_IMAGE_METHODS",
-
-    # Cannot turn this on until PDFium rolls into Chrome
-    # https://pdfium-review.googlesource.com/c/pdfium/+/107410
-    #"SK_DISABLE_LEGACY_SKSURFACE_FACTORIES",
+    "SK_DISABLE_LEGACY_SKSURFACE_FACTORIES",
   ]
 
   include_dirs = [ "//third_party/skia" ]
@@ -594,6 +591,12 @@
     ]
     public += skia_pdf_public
     sources += skia_pdf_sources
+    if (use_blink) {
+      # Blink includes Skia's JPEG decoder
+      sources += skia_pdf_jpeginfo_lib
+    } else {
+      sources += skia_pdf_jpeginfo_none
+    }
   } else {
     sources += [ "//third_party/skia/src/pdf/SkDocument_PDF_None.cpp" ]
   }
diff --git a/storage/browser/blob/blob_data_builder.cc b/storage/browser/blob/blob_data_builder.cc
index 2d18d91..26d1315 100644
--- a/storage/browser/blob/blob_data_builder.cc
+++ b/storage/browser/blob/blob_data_builder.cc
@@ -186,14 +186,17 @@
     return;
   }
 
-  // We can't reference a blob with unknown size.
-  if (ref_entry->total_size() == blink::BlobUtils::kUnknownSize) {
+  // If we're referencing a blob with unknown size, the caller needs to provide
+  // an explicit length for how much of the blob to reference.
+  if (ref_entry->total_size() == blink::BlobUtils::kUnknownSize &&
+      length == blink::BlobUtils::kUnknownSize) {
     has_blob_errors_ = true;
     return;
   }
 
-  if (length == blink::BlobUtils::kUnknownSize)
+  if (length == blink::BlobUtils::kUnknownSize) {
     length = ref_entry->total_size() - offset;
+  }
 
   total_size_ += length;
 
@@ -218,6 +221,24 @@
     return;
   }
 
+  // If `ref_entry` is a blob with unknown size it must always consist of a
+  // single file item, and as such we can just add a reference to the same file.
+  if (ref_entry->total_size() == blink::BlobUtils::kUnknownSize) {
+    CHECK_EQ(ref_entry->items().size(), 1u);
+    const scoped_refptr<BlobDataItem>& source_item =
+        ref_entry->items()[0]->item();
+    CHECK_EQ(source_item->type(), BlobDataItem::Type::kFile);
+    CHECK(!source_item->IsFutureFileItem());
+
+    items_.push_back(base::MakeRefCounted<ShareableBlobDataItem>(
+        BlobDataItem::CreateFile(
+            source_item->path(), source_item->offset() + offset, length,
+            source_item->expected_modification_time(), source_item->file_ref_,
+            source_item->file_access_),
+        ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA));
+    return;
+  }
+
   SliceBlob(ref_entry, offset, length);
 }
 
@@ -241,7 +262,7 @@
         source_items[item_index]->item();
     uint64_t source_length = source_item->length();
     BlobDataItem::Type type = source_item->type();
-    DCHECK_NE(source_length, std::numeric_limits<uint64_t>::max());
+    DCHECK_NE(source_length, blink::BlobUtils::kUnknownSize);
     DCHECK_NE(source_length, 0ull);
 
     uint64_t read_size =
diff --git a/storage/browser/file_system/file_system_url.cc b/storage/browser/file_system/file_system_url.cc
index 8768f1f..af9b81d 100644
--- a/storage/browser/file_system/file_system_url.cc
+++ b/storage/browser/file_system/file_system_url.cc
@@ -65,12 +65,14 @@
       url, blink::StorageKey::CreateFirstParty(url::Origin::Create(url)));
 }
 
+// static
 FileSystemURL FileSystemURL::CreateForTest(const blink::StorageKey& storage_key,
                                            FileSystemType mount_type,
                                            const base::FilePath& virtual_path) {
   return FileSystemURL(storage_key, mount_type, virtual_path);
 }
 
+// static
 FileSystemURL FileSystemURL::CreateForTest(
     const blink::StorageKey& storage_key,
     FileSystemType mount_type,
@@ -85,6 +87,52 @@
                        filesystem_id, mount_option);
 }
 
+// static
+bool FileSystemURL::TypeImpliesPathIsReal(FileSystemType type) {
+  switch (type) {
+    // Public enum values, also exposed to JavaScript.
+    case kFileSystemTypeTemporary:
+    case kFileSystemTypePersistent:
+    case kFileSystemTypeIsolated:
+    case kFileSystemTypeExternal:
+      break;
+
+      // Everything else is a private (also known as internal) enum value.
+
+    case kFileSystemInternalTypeEnumStart:
+    case kFileSystemInternalTypeEnumEnd:
+      NOTREACHED();
+      break;
+
+    case kFileSystemTypeLocal:
+    case kFileSystemTypeRestrictedLocal:
+    case kFileSystemTypeLocalMedia:
+    case kFileSystemTypeLocalForPlatformApp:
+    case kFileSystemTypeDriveFs:
+    case kFileSystemTypeSmbFs:
+    case kFileSystemTypeFuseBox:
+      return true;
+
+    case kFileSystemTypeUnknown:
+    case kFileSystemTypeTest:
+    case kFileSystemTypeDragged:
+    case kFileSystemTypeDeviceMedia:
+    case kFileSystemTypeSyncable:
+    case kFileSystemTypeSyncableForInternalSync:
+    case kFileSystemTypeForTransientFile:
+    case kFileSystemTypeProvided:
+    case kFileSystemTypeDeviceMediaAsFileStorage:
+    case kFileSystemTypeArcContent:
+    case kFileSystemTypeArcDocumentsProvider:
+      break;
+
+      // We don't use a "default:" case. Whenever `FileSystemType` gains a
+      // new enum value, raise a compiler error (with -Werror,-Wswitch) unless
+      // this switch statement is also updated.
+  }
+  return false;
+}
+
 FileSystemURL::FileSystemURL(const GURL& url,
                              const blink::StorageKey& storage_key)
     : is_null_(false),
diff --git a/storage/browser/file_system/file_system_url.h b/storage/browser/file_system/file_system_url.h
index 50592cef..7862564 100644
--- a/storage/browser/file_system/file_system_url.h
+++ b/storage/browser/file_system/file_system_url.h
@@ -135,7 +135,8 @@
 // the same as what FileSystemURL::path() returns. The FileSystemURL::path()
 // often locates a real file on the kernel-level file system but it does not
 // have to and sometimes it's just a string identifier (presented in C++ as a
-// base::FilePath) whose meaning depends on the FileSystemURL::type().
+// base::FilePath) whose meaning depends on the FileSystemURL::type(). See the
+// `TypeImpliesPathIsReal()` method.
 //
 // For example, kFileSystemTypeProvided (which corresponds to the
 // https://developer.chrome.com/docs/extensions/reference/fileSystemProvider/
@@ -182,6 +183,16 @@
                                      const std::string& filesystem_id,
                                      const FileSystemMountOption& mount_option);
 
+  // Whether a `FileSystemURL`'s `path()` refers to a real (kernel visible, can
+  // be passed to https://man7.org/linux/man-pages/man2/open.2.html) file,
+  // instead of being a string identifier in `base::FilePath` clothing.
+  //
+  // Must be called on a `FileSystemURL`'s `type()`. Do not call this method
+  // with a `mount_type()`.
+  static bool TypeImpliesPathIsReal(FileSystemType type);
+  // Instance method is provided for convenience.
+  bool TypeImpliesPathIsReal() const { return TypeImpliesPathIsReal(type()); }
+
   // Returns true if this instance represents a valid FileSystem URL.
   bool is_valid() const { return is_valid_; }
 
diff --git a/storage/common/file_system/file_system_mount_option.h b/storage/common/file_system/file_system_mount_option.h
index bbc7aa0..d0ebd06 100644
--- a/storage/common/file_system/file_system_mount_option.h
+++ b/storage/common/file_system/file_system_mount_option.h
@@ -10,14 +10,15 @@
 // Option for specifying if flush or disk sync operation is wanted after
 // writing.
 enum class FlushPolicy {
-  // No flushing is required after a writing operation is completed.
+  // Specify this policy if flushing is required in order to commit written
+  // data. Note, that syncing is only invoked via FileStreamWriter::Flush() and
+  // via base::File::Flush() for native files. Hence, syncing will not be
+  // performed for copying within non-native file systems as well as for
+  // non-native copies performed with snapshots.
   FLUSH_ON_COMPLETION,
 
-  // Flushing is required in order to commit written data. Note, that syncing
-  // is only invoked via FileStreamWriter::Flush() and via base::File::Flush()
-  // for native files. Hence, syncing will not be performed for copying within
-  // non-native file systems as well as for non-native copies performed with
-  // snapshots.
+  // Specify this policy if no flushing is required after a writing operation is
+  // completed.
   NO_FLUSH_ON_COMPLETION
 };
 
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index ea3688b8..56135bd6 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -1559,7 +1559,7 @@
         "name": "chrome_all_tast_tests OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM",
         "shards": 10,
         "swarming": {},
-        "tast_expr": "(\"group:mainline\" && !informational)",
+        "tast_expr": "(\"group:mainline\" && \"dep:chrome\" && !informational)",
         "test": "chrome_all_tast_tests",
         "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
         "timeout_sec": 21600,
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 136e627..bfd3f7d 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -1713,7 +1713,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1729,7 +1729,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1749,7 +1749,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1765,7 +1765,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1781,7 +1781,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1798,7 +1798,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1814,7 +1814,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1831,7 +1831,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1847,7 +1847,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -1864,7 +1864,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1880,7 +1880,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1896,7 +1896,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1912,7 +1912,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1928,7 +1928,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1944,7 +1944,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1960,7 +1960,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1977,7 +1977,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -1993,7 +1993,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2009,7 +2009,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2025,7 +2025,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -2045,7 +2045,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2061,7 +2061,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2077,7 +2077,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2093,7 +2093,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2109,7 +2109,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2125,7 +2125,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2141,7 +2141,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2157,7 +2157,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2173,7 +2173,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2189,7 +2189,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2205,7 +2205,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2221,7 +2221,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -2238,7 +2238,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2254,7 +2254,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2270,7 +2270,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2286,7 +2286,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2302,7 +2302,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2318,7 +2318,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2335,7 +2335,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2351,7 +2351,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2367,7 +2367,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2383,7 +2383,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2399,7 +2399,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2415,7 +2415,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2431,7 +2431,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2447,7 +2447,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2463,7 +2463,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2479,7 +2479,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2495,7 +2495,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2511,7 +2511,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2527,7 +2527,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2543,7 +2543,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -2560,7 +2560,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2576,7 +2576,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2592,7 +2592,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2609,7 +2609,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2625,7 +2625,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2641,7 +2641,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2657,7 +2657,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2673,7 +2673,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2689,7 +2689,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2705,7 +2705,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2721,7 +2721,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2737,7 +2737,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2753,7 +2753,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -2773,7 +2773,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2789,7 +2789,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2805,7 +2805,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2821,7 +2821,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2837,7 +2837,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2853,7 +2853,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2869,7 +2869,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2885,7 +2885,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2901,7 +2901,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2917,7 +2917,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2933,7 +2933,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2949,7 +2949,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2965,7 +2965,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2981,7 +2981,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -2997,7 +2997,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3013,7 +3013,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3029,7 +3029,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3045,7 +3045,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -3062,7 +3062,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3078,7 +3078,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3094,7 +3094,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3110,7 +3110,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -3127,7 +3127,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3144,7 +3144,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3160,7 +3160,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3176,7 +3176,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3192,7 +3192,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3208,7 +3208,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3224,7 +3224,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -3240,7 +3240,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "os": "Ubuntu-18.04"
+              "os": "Ubuntu-22.04"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -5736,9 +5736,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5749,8 +5749,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -5901,9 +5901,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5914,8 +5914,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -6048,9 +6048,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6061,8 +6061,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 44823cf..19d0086 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -24087,7 +24087,8 @@
         "args": [
           "--num-retries=3",
           "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json",
-          "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw"
+          "--additional-driver-flag=--no-sandbox",
+          "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%9m.profraw"
         ],
         "check_flakiness_for_new_tests": false,
         "isolate_name": "blink_web_tests",
@@ -24119,7 +24120,8 @@
         "args": [
           "--num-retries=3",
           "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json",
-          "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw"
+          "--additional-driver-flag=--no-sandbox",
+          "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%9m.profraw"
         ],
         "check_flakiness_for_new_tests": false,
         "isolate_name": "blink_wpt_tests",
@@ -24143,7 +24145,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 12
+          "shards": 7
         },
         "test_id_prefix": "ninja://:blink_wpt_tests/"
       },
@@ -24368,7 +24370,8 @@
           "--flag-specific=disable-site-isolation-trials",
           "--num-retries=3",
           "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json",
-          "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw"
+          "--additional-driver-flag=--no-sandbox",
+          "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%9m.profraw"
         ],
         "check_flakiness_for_new_tests": false,
         "isolate_name": "blink_web_tests",
@@ -25491,9 +25494,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25504,8 +25507,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -25656,9 +25659,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25669,8 +25672,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -25803,9 +25806,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25816,8 +25819,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json
index 5fe34f0..0dc47bee 100644
--- a/testing/buildbot/chromium.dawn.json
+++ b/testing/buildbot/chromium.dawn.json
@@ -101,7 +101,89 @@
         "test_id_prefix": "ninja://third_party/dawn/src/dawn/tests:dawn_end2end_tests/"
       }
     ],
-    "isolated_scripts": []
+    "isolated_scripts": [
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=1"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test_android_chrome",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 36
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_android_chrome/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=1"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test_android_chrome",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 36
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_android_chrome/"
+      }
+    ]
   },
   "Dawn Android arm Release (Pixel 4)": {
     "gtest_tests": [
@@ -203,7 +285,89 @@
         "test_id_prefix": "ninja://third_party/dawn/src/dawn/tests:dawn_end2end_tests/"
       }
     ],
-    "isolated_scripts": []
+    "isolated_scripts": [
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=1"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test_android_chrome",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 36
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_android_chrome/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=1"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test_android_chrome",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 36
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_android_chrome/"
+      }
+    ]
   },
   "Dawn Android arm64 DEPS Release (Pixel 6)": {
     "gtest_tests": [
@@ -305,7 +469,89 @@
         "test_id_prefix": "ninja://third_party/dawn/src/dawn/tests:dawn_end2end_tests/"
       }
     ],
-    "isolated_scripts": []
+    "isolated_scripts": [
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=1"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test_android_chrome",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "TP1A.220624.021",
+              "device_os_type": "userdebug",
+              "device_type": "oriole",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 36
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_android_chrome/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=1"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test_android_chrome",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "TP1A.220624.021",
+              "device_os_type": "userdebug",
+              "device_type": "oriole",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 36
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_android_chrome/"
+      }
+    ]
   },
   "Dawn Android arm64 Release (Pixel 6)": {
     "gtest_tests": [
@@ -407,7 +653,89 @@
         "test_id_prefix": "ninja://third_party/dawn/src/dawn/tests:dawn_end2end_tests/"
       }
     ],
-    "isolated_scripts": []
+    "isolated_scripts": [
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=1"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test_android_chrome",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "TP1A.220624.021",
+              "device_os_type": "userdebug",
+              "device_type": "oriole",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 36
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_android_chrome/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=1"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test_android_chrome",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "TP1A.220624.021",
+              "device_os_type": "userdebug",
+              "device_type": "oriole",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 36
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_android_chrome/"
+      }
+    ]
   },
   "Dawn Linux TSAN Release": {
     "gtest_tests": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 74bffa7d..969e19e 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -20544,6 +20544,5437 @@
   "ios15-beta-simulator": {
     "additional_compile_targets": [
       "all"
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "absl_hardening_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "absl_hardening_tests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "absl_hardening_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "absl_hardening_tests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "base_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "base_unittests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://base:base_unittests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "base_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "base_unittests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://base:base_unittests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "base_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "base_unittests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://base:base_unittests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "base_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "base_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://base:base_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "boringssl_crypto_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "boringssl_crypto_tests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "boringssl_crypto_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "boringssl_crypto_tests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "boringssl_ssl_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "boringssl_ssl_tests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "boringssl_ssl_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "boringssl_ssl_tests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "components_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "components_unittests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://components:components_unittests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "components_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "components_unittests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://components:components_unittests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "components_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "components_unittests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://components:components_unittests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "components_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "components_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://components:components_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "crashpad_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "crashpad_tests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "crashpad_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "crashpad_tests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "crypto_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "crypto_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://crypto:crypto_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "crypto_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "crypto_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://crypto:crypto_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "gfx_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gfx_unittests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "gfx_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gfx_unittests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "gfx_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gfx_unittests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "gfx_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gfx_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "google_apis_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "google_apis_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://google_apis:google_apis_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "google_apis_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "google_apis_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://google_apis:google_apis_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Air (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_bookmarks_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_bookmarks_eg2tests_module iPad Air (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/",
+        "variant_id": "iPad Air (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Pro (12.9-inch) (3rd generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_bookmarks_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_bookmarks_eg2tests_module iPad Pro (12.9-inch) (3rd generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/",
+        "variant_id": "iPad Pro (12.9-inch) (3rd generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_bookmarks_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_bookmarks_eg2tests_module iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_bookmarks_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_bookmarks_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad (6th generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_integration_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_integration_eg2tests_module iPad (6th generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/",
+        "variant_id": "iPad (6th generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_integration_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_integration_eg2tests_module iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_integration_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_integration_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Air (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_settings_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_settings_eg2tests_module iPad Air (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/",
+        "variant_id": "iPad Air (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Pro (12.9-inch) (3rd generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_settings_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_settings_eg2tests_module iPad Pro (12.9-inch) (3rd generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/",
+        "variant_id": "iPad Pro (12.9-inch) (3rd generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_settings_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_settings_eg2tests_module iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_settings_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_settings_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Air (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_signin_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_signin_eg2tests_module iPad Air (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 6
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/",
+        "variant_id": "iPad Air (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Pro (12.9-inch) (3rd generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_signin_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_signin_eg2tests_module iPad Pro (12.9-inch) (3rd generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 6
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/",
+        "variant_id": "iPad Pro (12.9-inch) (3rd generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_signin_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_signin_eg2tests_module iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 6
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_signin_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_signin_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 6
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Air (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_smoke_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_smoke_eg2tests_module iPad Air (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/",
+        "variant_id": "iPad Air (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Pro (12.9-inch) (3rd generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_smoke_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_smoke_eg2tests_module iPad Pro (12.9-inch) (3rd generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/",
+        "variant_id": "iPad Pro (12.9-inch) (3rd generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_smoke_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_smoke_eg2tests_module iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_smoke_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_smoke_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Air (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_ui_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_ui_eg2tests_module iPad Air (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 12
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/",
+        "variant_id": "iPad Air (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Pro (12.9-inch) (3rd generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_ui_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_ui_eg2tests_module iPad Pro (12.9-inch) (3rd generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 12
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/",
+        "variant_id": "iPad Pro (12.9-inch) (3rd generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_ui_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_ui_eg2tests_module iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 12
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_ui_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_ui_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 12
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_chrome_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_unittests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_chrome_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_unittests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_chrome_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_unittests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_chrome_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Air (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_web_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_web_eg2tests_module iPad Air (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/",
+        "variant_id": "iPad Air (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Pro (12.9-inch) (3rd generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_web_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_web_eg2tests_module iPad Pro (12.9-inch) (3rd generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/",
+        "variant_id": "iPad Pro (12.9-inch) (3rd generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_web_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_web_eg2tests_module iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_chrome_web_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_web_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_components_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_components_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/components:ios_components_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_components_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_components_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/components:ios_components_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Air 2",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_crash_xcuitests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_crash_xcuitests_module iPad Air 2 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/crashpad/crashpad/test/ios:ios_crash_xcuitests_module/",
+        "variant_id": "iPad Air 2 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_crash_xcuitests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_crash_xcuitests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/crashpad/crashpad/test/ios:ios_crash_xcuitests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_net_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_net_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://ios/net:ios_net_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_net_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_net_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://ios/net:ios_net_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_remoting_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_remoting_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://remoting/ios:ios_remoting_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_remoting_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_remoting_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://remoting/ios:ios_remoting_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Air (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_showcase_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_showcase_eg2tests_module iPad Air (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/",
+        "variant_id": "iPad Air (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad Pro (12.9-inch) (3rd generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_showcase_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_showcase_eg2tests_module iPad Pro (12.9-inch) (3rd generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/",
+        "variant_id": "iPad Pro (12.9-inch) (3rd generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_showcase_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_showcase_eg2tests_module iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_showcase_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_showcase_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_testing_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_testing_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/testing:ios_testing_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_testing_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_testing_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/testing:ios_testing_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_inttests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_inttests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_inttests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_inttests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_inttests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_inttests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_inttests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_inttests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_inttests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_inttests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_inttests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_inttests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPad (6th generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_web_shell_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_shell_eg2tests_module iPad (6th generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/",
+        "variant_id": "iPad (6th generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_web_shell_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_shell_eg2tests_module iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest",
+          "--xcode-parallelization",
+          "--record-video",
+          "failed_only"
+        ],
+        "isolate_name": "ios_web_shell_eg2tests_module",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_shell_eg2tests_module iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_unittests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_unittests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_unittests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_unittests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_unittests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_unittests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_inttests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_inttests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_inttests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_inttests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_inttests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_inttests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_inttests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_inttests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_unittests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_unittests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_unittests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "net_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "net_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://net:net_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "net_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "net_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://net:net_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "services_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "services_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://services:services_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "services_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "services_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://services:services_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "skia_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "skia_unittests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://skia:skia_unittests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "skia_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "skia_unittests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://skia:skia_unittests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "skia_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "skia_unittests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://skia:skia_unittests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "skia_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "skia_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://skia:skia_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "sql_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "sql_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://sql:sql_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "sql_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "sql_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://sql:sql_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ui_base_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ui_base_unittests iPhone SE (1st generation) 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/",
+        "variant_id": "iPhone SE (1st generation) 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone SE (3rd generation)",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ui_base_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ui_base_unittests iPhone SE (3rd generation) 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/",
+        "variant_id": "iPhone SE (3rd generation) 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ui_base_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ui_base_unittests iPhone X 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/",
+        "variant_id": "iPhone X 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "ui_base_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ui_base_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/",
+        "variant_id": "iPhone X 16.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "15.5",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "url_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "url_unittests iPhone 6s 15.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_15_5",
+              "path": "Runtime-ios-15.5"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://url:url_unittests/",
+        "variant_id": "iPhone 6s 15.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone X",
+          "--version",
+          "16.2",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "14c18",
+          "--xctest"
+        ],
+        "isolate_name": "url_unittests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "url_unittests iPhone X 16.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:3e597065cb23c1fe03aeb2ebd792d83e0709c5c2"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-13"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_14c18",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_16_2",
+              "path": "Runtime-ios-16.2"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://url:url_unittests/",
+        "variant_id": "iPhone X 16.2"
+      }
     ]
   },
   "ios15-sdk-simulator": {
@@ -40153,9 +45584,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -40165,8 +45596,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -40318,9 +45749,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -40330,8 +45761,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -40465,9 +45896,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -40477,8 +45908,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -41942,9 +47373,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -41954,8 +47385,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -42107,9 +47538,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -42119,8 +47550,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -42254,9 +47685,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -42266,8 +47697,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -43002,9 +48433,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43014,8 +48445,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 6f604ec2..e37f0385 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -18080,12 +18080,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18096,8 +18096,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -18265,12 +18265,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18281,8 +18281,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
@@ -18427,12 +18427,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 115.0.5789.0",
+        "description": "Run with ash-chrome version 116.0.5791.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18443,8 +18443,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5789.0",
-              "revision": "version:115.0.5789.0"
+              "location": "lacros_version_skew_tests_v116.0.5791.0",
+              "revision": "version:116.0.5791.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter b/testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter
index 9948a383..9d346f7 100644
--- a/testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter
+++ b/testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter
@@ -17,6 +17,7 @@
 SwitchAccess*
 VpnExtensionObserverBrowserTest*
 WebAppsCrosapiBrowserTest*
+WebAppPreloadInstallerLacrosBrowserTest*
 WebAppProviderBridgeBrowserTest*
 WebKioskAcceleratorLacrosTest*
 WebKioskLacrosTest*
diff --git a/testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter b/testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter
index 694ca94..187bd1e 100644
--- a/testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter
+++ b/testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter
@@ -135,26 +135,3 @@
 # TODO(b/256212431): Re-enable when linux-lacros-rel support
 # signin::MakePrimaryAccountAvailable().
 -AccessCodeCastHandlerBrowserTest.ExpectProfileSynErrorWhenNoSync
-
-# Can be enabled once this version skew variant uses Ash >= 114.0.5735.19.
--MenuItemViewTestRemoveWithSubmenu0.RemoveItemWithSubmenu0
--TabDragging/DetachToBrowserTabDragControllerTest.CancelOnNewTabWhenDragging/0
--TabDragging/DetachToBrowserTabDragControllerTest.CancelOnNewTabWhenDragging/2
--TabDragging/DetachToBrowserTabDragControllerTest.CaptureLostDuringDrag/0
--TabDragging/DetachToBrowserTabDragControllerTest.CaptureLostDuringDrag/2
--TabDragging/DetachToBrowserTabDragControllerTest.DeleteBeforeStartedDragging/0
--TabDragging/DetachToBrowserTabDragControllerTest.DeleteBeforeStartedDragging/2
--TabDragging/DetachToBrowserTabDragControllerTest.DeleteTabsWhileDetached/0
--TabDragging/DetachToBrowserTabDragControllerTest.DeleteTabsWhileDetached/2
--TabDragging/DetachToBrowserTabDragControllerTest.DeleteTabWhileAttached/0
--TabDragging/DetachToBrowserTabDragControllerTest.DeleteTabWhileAttached/2
--TabDragging/DetachToBrowserTabDragControllerTest.DetachToOwnWindow/0
--TabDragging/DetachToBrowserTabDragControllerTest.DetachToOwnWindow/2
--TabDragging/DetachToBrowserTabDragControllerTest.DetachToOwnWindowFromMaximizedWindow/0
--TabDragging/DetachToBrowserTabDragControllerTest.DetachToOwnWindowFromMaximizedWindow/2
--TabDragging/DetachToBrowserTabDragControllerTest.DragAll/0
--TabDragging/DetachToBrowserTabDragControllerTest.DragAll/2
--TabDragging/DetachToBrowserTabDragControllerTest.KeyPressShouldEndDragTest/0
--TabDragging/DetachToBrowserTabDragControllerTest.KeyPressShouldEndDragTest/2
--TabDragging/DetachToBrowserTabDragControllerTest.RevertDragWhileDetached/0
--TabDragging/DetachToBrowserTabDragControllerTest.RevertDragWhileDetached/2
diff --git a/testing/buildbot/filters/pixel_tests.filter b/testing/buildbot/filters/pixel_tests.filter
index edc48c9..0f4233b 100644
--- a/testing/buildbot/filters/pixel_tests.filter
+++ b/testing/buildbot/filters/pixel_tests.filter
@@ -8,6 +8,7 @@
 
 AccessCodeCastDialogBrowserTest.*
 AppInfoDialogBrowserTest.*
+AppMenuBrowserTest*.InvokeUi_*
 AskGoogleForSuggestionsDialogTest.*
 BookmarkBubbleViewBrowserTest.*
 BookmarkEditorViewBrowserTest.*
@@ -39,6 +40,7 @@
 HomeButtonUiTest.*
 HungRendererDialogViewBrowserTest.*
 ImportLockDialogViewBrowserTest.*
+InfoBarUiTest.*
 InlineLoginHelperBrowserTest.InvokeUi_*
 IntentPickerDialogTest.*
 IntentPickerDialogGridViewTest.*
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json
index 8c881f9..9f8ae49e 100644
--- a/testing/buildbot/internal.chromeos.fyi.json
+++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1209,7 +1209,7 @@
         "name": "chrome_all_tast_tests JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM",
         "shards": 10,
         "swarming": {},
-        "tast_expr": "(\"group:mainline\" && !informational)",
+        "tast_expr": "(\"group:mainline\" && \"dep:chrome\" && !informational)",
         "test": "chrome_all_tast_tests",
         "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
         "timeout_sec": 21600,
@@ -1232,7 +1232,7 @@
         "name": "chrome_all_tast_tests OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM",
         "shards": 10,
         "swarming": {},
-        "tast_expr": "(\"group:mainline\" && !informational)",
+        "tast_expr": "(\"group:mainline\" && \"dep:chrome\" && !informational)",
         "test": "chrome_all_tast_tests",
         "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
         "timeout_sec": 21600,
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index c4368b93..a6b878b 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -537,7 +537,8 @@
       },
       'linux-code-coverage': {
         'args': [
-          '--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw',
+          '--additional-driver-flag=--no-sandbox',
+          '--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%9m.profraw',
         ],
         'swarming': {
           'shards': 8,
@@ -643,6 +644,15 @@
           'hard_timeout': 2400,
         },
       },
+      'win11-arm64-blink-rel': {
+        'swarming': {
+          'hard_timeout': 2400,
+        },
+        'args': [
+          '--target',
+          'Release_x64',
+        ],
+      },
       'win11-blink-rel': {
         'swarming': {
           'hard_timeout': 2400,
@@ -872,11 +882,9 @@
       },
       'linux-code-coverage': {
         'args': [
-          '--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw',
+          '--additional-driver-flag=--no-sandbox',
+          '--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%9m.profraw',
         ],
-        'swarming': {
-          'shards': 12,
-        },
       },
       'linux-layout-tests-edit-ng': {
         'args': [
@@ -975,6 +983,15 @@
           'hard_timeout': 2400,
         },
       },
+      'win11-arm64-blink-rel': {
+        'swarming': {
+          'hard_timeout': 2400,
+        },
+        'args': [
+          '--target',
+          'Release_x64',
+        ],
+      },
       'win11-blink-rel': {
         'swarming': {
           'hard_timeout': 2400,
@@ -3208,7 +3225,8 @@
       },
       'linux-code-coverage': {
         'args': [
-          '--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw',
+          '--additional-driver-flag=--no-sandbox',
+          '--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%9m.profraw',
         ],
         'swarming': {
           'shards': 20,
@@ -4407,15 +4425,19 @@
     ],
   },
   'webgpu_cts_tests': {
-    'remove_from': [
-      # TODO(crbug.com/1363409): Enable these once they're shown to work on
-      # Android.
-      'Dawn Android arm DEPS Release (Pixel 4)',
-      'Dawn Android arm Release (Pixel 4)',
-      'Dawn Android arm64 DEPS Release (Pixel 6)',
-      'Dawn Android arm64 Release (Pixel 6)',
-    ],
     'modifications': {
+      'Dawn Android arm DEPS Release (Pixel 4)': {
+        'ci_only': True,
+      },
+      'Dawn Android arm Release (Pixel 4)': {
+        'ci_only': True,
+      },
+      'Dawn Android arm64 DEPS Release (Pixel 6)': {
+        'ci_only': True,
+      },
+      'Dawn Android arm64 Release (Pixel 6)': {
+        'ci_only': True,
+      },
       'Dawn Mac x64 DEPS Release (AMD)': {
         'ci_only': True,
       },
@@ -4470,12 +4492,6 @@
   },
   'webgpu_cts_with_validation_tests': {
     'remove_from': [
-      # TODO(crbug.com/1363409): Enable these once they're shown to work on
-      # Android.
-      'Dawn Android arm DEPS Release (Pixel 4)',
-      'Dawn Android arm Release (Pixel 4)',
-      'Dawn Android arm64 DEPS Release (Pixel 6)',
-      'Dawn Android arm64 Release (Pixel 6)',
       # Remove from bots where capacity is constrained.
       'Dawn Win10 x64 DEPS Release (Intel)',
       'Dawn Win10 x64 Release (Intel)',
@@ -4491,6 +4507,18 @@
       'win10-code-coverage',
     ],
     'modifications': {
+      'Dawn Android arm DEPS Release (Pixel 4)': {
+        'ci_only': True,
+      },
+      'Dawn Android arm Release (Pixel 4)': {
+        'ci_only': True,
+      },
+      'Dawn Android arm64 DEPS Release (Pixel 6)': {
+        'ci_only': True,
+      },
+      'Dawn Android arm64 Release (Pixel 6)': {
+        'ci_only': True,
+      },
       # ci_only for bots where capacity is constrained.
       'Dawn Linux x64 DEPS Release (Intel UHD 630)': {
         'ci_only': True,
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index b02814c..55ddfc8 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -2716,6 +2716,9 @@
         'swarming': {
           'shards': 14,
         },
+        'android_swarming': {
+          'shards': 36,
+        },
       },
       'webgpu_cts_with_validation': {
         'args': [
@@ -2728,6 +2731,9 @@
         'swarming': {
           'shards': 14,
         },
+        'android_swarming': {
+          'shards': 36,
+        },
         'telemetry_test_name': 'webgpu_cts',
       },
     },
@@ -6809,6 +6815,48 @@
       },
     },
 
+    'ios15_beta_simulator_tests': {
+      'ios_common_tests': {
+        'variants': [
+          'SIM_IPHONE_X_16_2',
+          'SIM_IPHONE_6S_15_5',
+        ],
+      },
+      'ios_eg2_tests': {
+        'mixins': ['xcode_parallelization', 'record_failed_tests'],
+        'variants': [
+          'SIM_IPHONE_X_16_2',
+          'SIM_IPAD_AIR_3RD_GEN_16_2',
+          'SIM_IPHONE_X_15_5',
+          'SIM_IPAD_PRO_3RD_GEN_15_5',
+        ]
+      },
+      'ios_eg2_cq_tests': {
+        'mixins': ['xcode_parallelization', 'record_failed_tests'],
+        'variants': [
+          'SIM_IPHONE_X_16_2',
+          'SIM_IPAD_6_GEN_16_2',
+          'SIM_IPHONE_SE_1ST_GEN_15_5',
+        ]
+      },
+      'ios_screen_size_dependent_tests': {
+        'variants': [
+          'SIM_IPHONE_X_16_2',
+          'SIM_IPHONE_SE_3RD_GEN_16_2',
+          'SIM_IPHONE_X_15_5',
+          'SIM_IPHONE_SE_1ST_GEN_15_5',
+        ],
+      },
+      'ios_crash_xcuitests': {
+        'mixins': ['xcode_parallelization'],
+        'variants': [
+          'SIM_IPHONE_X_16_2',
+          'SIM_IPAD_AIR_2_15_5',
+
+        ]
+      },
+    },
+
     'ios15_sdk_simulator_tests': {
       'ios_common_tests': {
         'variants': [
diff --git a/testing/buildbot/tryserver.blink.json b/testing/buildbot/tryserver.blink.json
index b64c2c3..791d1d0 100644
--- a/testing/buildbot/tryserver.blink.json
+++ b/testing/buildbot/tryserver.blink.json
@@ -927,7 +927,9 @@
       {
         "args": [
           "--num-retries=3",
-          "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json"
+          "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json",
+          "--target",
+          "Release_x64"
         ],
         "check_flakiness_for_new_tests": false,
         "isolate_name": "blink_web_tests",
@@ -952,7 +954,7 @@
             }
           ],
           "expiration": 64800,
-          "hard_timeout": 43200,
+          "hard_timeout": 2400,
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
           "shards": 5
         },
@@ -961,7 +963,9 @@
       {
         "args": [
           "--num-retries=3",
-          "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json"
+          "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json",
+          "--target",
+          "Release_x64"
         ],
         "check_flakiness_for_new_tests": false,
         "isolate_name": "blink_wpt_tests",
@@ -986,7 +990,7 @@
             }
           ],
           "expiration": 64800,
-          "hard_timeout": 43200,
+          "hard_timeout": 2400,
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
           "shards": 7
         },
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 40714d3..7698085 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5789.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5791.0/test_ash_chrome',
     ],
-    'description': 'Run with ash-chrome version 115.0.5789.0',
+    'description': 'Run with ash-chrome version 116.0.5791.0',
     'identifier': 'Lacros version skew testing ash canary',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v115.0.5789.0',
-          'revision': 'version:115.0.5789.0',
+          'location': 'lacros_version_skew_tests_v116.0.5791.0',
+          'revision': 'version:116.0.5791.0',
         },
       ],
     },
@@ -582,7 +582,6 @@
       'cros_board': 'jacuzzi',
       'cros_chrome_version': '115.0.5762.0',
       'cros_img': 'jacuzzi-release/R115-15460.0.0',
-      'tast_expr': '("group:mainline" && !informational)',
       'autotest_name': 'tast.chrome-from-tls',
       'shards': 10,
     },
@@ -655,7 +654,6 @@
       'cros_board': 'octopus',
       'cros_chrome_version': '115.0.5762.0',
       'cros_img': 'octopus-release/R115-15460.0.0',
-      'tast_expr': '("group:mainline" && !informational)',
       'autotest_name': 'tast.chrome-from-tls',
       'shards': 10,
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 9d42fdb4..89c559b1 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -1582,7 +1582,7 @@
       },
       'linux-cfm-rel': {
         'mixins': [
-          'linux-bionic',
+          'linux-jammy',
         ],
         'test_suites': {
           'gtest_tests': 'linux_cfm_gtests',
@@ -1590,7 +1590,7 @@
       },
       'linux-chromeos-dbg': {
         'mixins': [
-          'linux-bionic',
+          'linux-jammy',
         ],
         'test_suites': {
           'gtest_tests': 'linux_chromeos_gtests',
@@ -1610,9 +1610,6 @@
         },
       },
       'linux-lacros-dbg': {
-        'mixins': [
-          'linux-bionic',
-        ],
         'additional_compile_targets': [
           'all',
         ],
@@ -3443,6 +3440,9 @@
           'xcode_14_main',
           'xctest',
         ],
+        'test_suites': {
+          'isolated_scripts': 'ios15_beta_simulator_tests'
+        },
       },
       'ios15-sdk-simulator': {
         'additional_compile_targets': [
diff --git a/testing/merge_scripts/code_coverage/convert_to_istanbul.js b/testing/merge_scripts/code_coverage/convert_to_istanbul.js
index e006c33..67b85f6 100644
--- a/testing/merge_scripts/code_coverage/convert_to_istanbul.js
+++ b/testing/merge_scripts/code_coverage/convert_to_istanbul.js
@@ -99,7 +99,6 @@
     }
   });
 
-  console.log(validMap)
   // Destroy consumer as we dont need it anymore.
   consumer.destroy();
   return validMap;
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 498296a..3c889bc 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -51,26 +51,6 @@
             ]
         }
     ],
-    "AddPageLoadTokenToClientSafeBrowsingReport": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "AddPageLoadTokenToClientSafeBrowsingReport"
-                    ]
-                }
-            ]
-        }
-    ],
     "AlignWakeUpsWithAntiStarvation": [
         {
             "platforms": [
@@ -1488,7 +1468,7 @@
             ],
             "experiments": [
                 {
-                    "name": "Card_20230522",
+                    "name": "Card_20230523",
                     "params": {
                         "en_site_id": "F2fsskHvB0ugnJ3q1cK0NXLjUaK5",
                         "probability": "1.0"
@@ -1502,7 +1482,7 @@
                     ]
                 },
                 {
-                    "name": "Password_20230522",
+                    "name": "Password_20230523",
                     "params": {
                         "en_site_id": "6VQ4NCCaq0ugnJ3q1cK0TR13rB8t",
                         "probability": "1.0"
@@ -1516,7 +1496,7 @@
                     ]
                 },
                 {
-                    "name": "Address_20230522",
+                    "name": "Address_20230523",
                     "params": {
                         "en_site_id": "qQW9c2ho10ugnJ3q1cK0X48UQjZs",
                         "probability": "1.0"
@@ -1755,9 +1735,9 @@
             ],
             "experiments": [
                 {
-                    "name": "EnabledPolicy_CacheSize3_20230328",
+                    "name": "EnabledPolicy_CacheSize6_20230525",
                     "params": {
-                        "cache_size": "3",
+                        "cache_size": "6",
                         "foreground_cache_size": "0"
                     },
                     "enable_features": [
@@ -2860,6 +2840,10 @@
                     "enable_features": [
                         "CrOSLateBootSchedUtilHints60",
                         "SchedUtilHints"
+                    ],
+                    "disable_features": [
+                        "CrOSLateBootSchedUtilHints40",
+                        "CrOSLateBootSchedUtilHints80"
                     ]
                 }
             ]
@@ -3970,6 +3954,21 @@
             ]
         }
     ],
+    "CursiveManagedStylusPreinstall": [
+        {
+            "platforms": [
+                "chromeos"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "CursiveManagedStylusPreinstall"
+                    ]
+                }
+            ]
+        }
+    ],
     "CursiveStylusPreinstall": [
         {
             "platforms": [
@@ -5390,47 +5389,6 @@
             ]
         }
     ],
-    "ExcludeLowEntropyImagesFromLCP": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "ExcludeEntropyL_V1",
-                    "params": {
-                        "min_bpp": "0.01"
-                    },
-                    "enable_features": [
-                        "ExcludeLowEntropyImagesFromLCP"
-                    ]
-                },
-                {
-                    "name": "ExcludeEntropyM_V1",
-                    "params": {
-                        "min_bpp": "0.05"
-                    },
-                    "enable_features": [
-                        "ExcludeLowEntropyImagesFromLCP"
-                    ]
-                },
-                {
-                    "name": "ExcludeEntropyH_V1",
-                    "params": {
-                        "min_bpp": "0.2"
-                    },
-                    "enable_features": [
-                        "ExcludeLowEntropyImagesFromLCP"
-                    ]
-                }
-            ]
-        }
-    ],
     "ExplicitHighResolutionTimerWin": [
         {
             "platforms": [
@@ -7019,7 +6977,7 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled_ACR_6_20230503",
+                    "name": "Enabled_ACR_6_Disabled_HSR_20230524",
                     "params": {
                         "EnableFeedAppCloseForegroundRefresh": "true",
                         "FeedUnseenRefreshThresholdInSeconds": "21600"
@@ -7030,25 +6988,23 @@
                     ]
                 },
                 {
-                    "name": "Enabled_ACR_12_20230503",
+                    "name": "Enabled_ACR_6_20230524",
                     "params": {
                         "EnableFeedAppCloseForegroundRefresh": "true",
-                        "FeedUnseenRefreshThresholdInSeconds": "43200"
+                        "FeedUnseenRefreshThresholdInSeconds": "21600"
                     },
                     "enable_features": [
-                        "EnableFeedInvisibleForegroundRefresh",
-                        "FeedDisableHotStartRefresh"
+                        "EnableFeedInvisibleForegroundRefresh"
                     ]
                 },
                 {
-                    "name": "Enabled_ACR_24_20230503",
+                    "name": "Enabled_ACR_24_20230524",
                     "params": {
                         "EnableFeedAppCloseForegroundRefresh": "true",
                         "FeedUnseenRefreshThresholdInSeconds": "86400"
                     },
                     "enable_features": [
-                        "EnableFeedInvisibleForegroundRefresh",
-                        "FeedDisableHotStartRefresh"
+                        "EnableFeedInvisibleForegroundRefresh"
                     ]
                 },
                 {
@@ -7058,7 +7014,7 @@
                     ]
                 },
                 {
-                    "name": "Enabled_app_close_foreground_20230405",
+                    "name": "Enabled_app_close_foreground_20230416",
                     "params": {
                         "EnableFeedAppCloseBackgroundRefresh": "false",
                         "EnableFeedAppCloseForegroundRefresh": "true",
@@ -7069,7 +7025,7 @@
                     ]
                 },
                 {
-                    "name": "Enabled_app_close_background_20230405",
+                    "name": "Enabled_app_close_background_20230416",
                     "params": {
                         "EnableFeedAppCloseBackgroundRefresh": "true",
                         "EnableFeedAppCloseForegroundRefresh": "false",
@@ -7080,7 +7036,7 @@
                     ]
                 },
                 {
-                    "name": "Enabled_session_close_foreground_20230405",
+                    "name": "Enabled_session_close_foreground_20230416",
                     "params": {
                         "EnableFeedAppCloseBackgroundRefresh": "false",
                         "EnableFeedAppCloseForegroundRefresh": "false",
@@ -8829,6 +8785,7 @@
                         "NtpHistoryClustersModuleCategoriesAllowlistParam": "/m/testparsinglogicallow,/m/testparsinglogicallow-2",
                         "NtpHistoryClustersModuleCategoriesBlocklistParam": "/m/testparsinglogicblock,/m/testparsinglogicblock-2",
                         "NtpHistoryClustersModuleCategoriesBoostlistParam": "/m/testparsinglogicboost,/m/testparsinglogicboost-2",
+                        "collections_blocklist": "/collection/it_glossary,/collection/periodicals,/collection/software,/collection/tv_networks,/collection/websites",
                         "search_visits_only": "false"
                     },
                     "enable_features": [
@@ -9649,26 +9606,6 @@
             ]
         }
     ],
-    "PageImageService": [
-        {
-            "platforms": [
-                "chromeos",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_Journeys_Suggest_SalientImages",
-                    "enable_features": [
-                        "ImageServiceOptimizationGuideSalientImages",
-                        "ImageServiceSuggestPoweredImages",
-                        "JourneysImages"
-                    ]
-                }
-            ]
-        }
-    ],
     "PageInfoAboutThisSiteImprovedBottomSheet": [
         {
             "platforms": [
@@ -11723,28 +11660,6 @@
             ]
         }
     ],
-    "SafeBrowsingOnUIThread": [
-        {
-            "platforms": [
-                "android",
-                "android_webview",
-                "chromeos",
-                "chromeos_lacros",
-                "ios",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "SafeBrowsingOnUIThread"
-                    ]
-                }
-            ]
-        }
-    ],
     "SafeBrowsingPhishingClassificationESBThreshold": [
         {
             "platforms": [
@@ -12909,22 +12824,6 @@
             ]
         }
     ],
-    "SuggestionsTruncationIOS": [
-        {
-            "platforms": [
-                "ios"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "MultilineFadeTruncatingLabel",
-                        "OmniboxMultilineSearchSuggest"
-                    ]
-                }
-            ]
-        }
-    ],
     "SupportPartitionedBlobUrlKillSwitchDisabled": [
         {
             "platforms": [
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium
index e7a209e..9904bad7 100644
--- a/third_party/abseil-cpp/README.chromium
+++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@
 License: Apache 2.0
 License File: LICENSE
 Version: 0
-Revision: c8b33b0191a2db8364cacf94b267ea8a3f20ad83
+Revision: d23adc1cfba78931b4aa2edb81f10a39135d2d24
 Security Critical: yes
 
 Description:
diff --git a/third_party/abseil-cpp/absl/base/attributes.h b/third_party/abseil-cpp/absl/base/attributes.h
index 3e5aafb..0394d64 100644
--- a/third_party/abseil-cpp/absl/base/attributes.h
+++ b/third_party/abseil-cpp/absl/base/attributes.h
@@ -685,6 +685,28 @@
 #define ABSL_DEPRECATED(message)
 #endif
 
+// When deprecating Abseil code, it is sometimes necessary to turn off the
+// warning within Abseil, until the deprecated code is actually removed. The
+// deprecated code can be surrounded with these directives to acheive that
+// result.
+//
+// class ABSL_DEPRECATED("Use Bar instead") Foo;
+//
+// ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
+// Baz ComputeBazFromFoo(Foo f);
+// ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
+#if defined(__GNUC__) || defined(__clang__)
+// Clang also supports these GCC pragmas.
+#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING \
+  _Pragma("GCC diagnostic push")             \
+  _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING \
+  _Pragma("GCC diagnostic pop")
+#else
+#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
+#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
+#endif  // __GNUC__
+
 // ABSL_CONST_INIT
 //
 // A variable declaration annotated with the `ABSL_CONST_INIT` attribute will
diff --git a/third_party/abseil-cpp/absl/container/BUILD.bazel b/third_party/abseil-cpp/absl/container/BUILD.bazel
index 902f6ed3..f22da59 100644
--- a/third_party/abseil-cpp/absl/container/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/container/BUILD.bazel
@@ -160,8 +160,8 @@
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:exception_testing",
-        "//absl/base:raw_logging_internal",
         "//absl/hash:hash_testing",
+        "//absl/log:check",
         "//absl/memory",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
@@ -255,7 +255,7 @@
         ":unordered_map_lookup_test",
         ":unordered_map_members_test",
         ":unordered_map_modifiers_test",
-        "//absl/base:raw_logging_internal",
+        "//absl/log:check",
         "//absl/types:any",
         "@com_google_googletest//:gtest_main",
     ],
@@ -289,7 +289,7 @@
         ":unordered_set_lookup_test",
         ":unordered_set_members_test",
         ":unordered_set_modifiers_test",
-        "//absl/base:raw_logging_internal",
+        "//absl/log:check",
         "//absl/memory",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
@@ -656,7 +656,6 @@
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:prefetch",
-        "//absl/base:raw_logging_internal",
         "//absl/log",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
@@ -743,7 +742,7 @@
         ":layout",
         "//absl/base:config",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log:check",
         "//absl/types:span",
         "@com_google_googletest//:gtest_main",
     ],
diff --git a/third_party/abseil-cpp/absl/container/BUILD.gn b/third_party/abseil-cpp/absl/container/BUILD.gn
index be9409d..6d0ce3b 100644
--- a/third_party/abseil-cpp/absl/container/BUILD.gn
+++ b/third_party/abseil-cpp/absl/container/BUILD.gn
@@ -52,6 +52,22 @@
   visibility = [ ":*" ]
 }
 
+absl_test("inlined_vector_test") {
+  sources = [ "inlined_vector_test.cc" ]
+  deps = [
+    ":counting_allocator",
+    ":inlined_vector",
+    ":test_instance_tracker",
+    "//third_party/abseil-cpp/absl/base:config",
+    "//third_party/abseil-cpp/absl/base:core_headers",
+    "//third_party/abseil-cpp/absl/base:exception_testing",
+    "//third_party/abseil-cpp/absl/hash:hash_testing",
+    "//third_party/abseil-cpp/absl/log:check",
+    "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/strings",
+  ]
+}
+
 absl_source_set("test_instance_tracker") {
   testonly = true
   sources = [ "internal/test_instance_tracker.cc" ]
@@ -404,22 +420,6 @@
   ]
 }
 
-absl_test("inlined_vector_test") {
-  sources = [ "inlined_vector_test.cc" ]
-  deps = [
-    ":counting_allocator",
-    ":inlined_vector",
-    ":test_instance_tracker",
-    "//third_party/abseil-cpp/absl/base:config",
-    "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/base:exception_testing",
-    "//third_party/abseil-cpp/absl/base:raw_logging_internal",
-    "//third_party/abseil-cpp/absl/hash:hash_testing",
-    "//third_party/abseil-cpp/absl/memory",
-    "//third_party/abseil-cpp/absl/strings",
-  ]
-}
-
 # TODO(mbonadei): Fix issue with EXPECT_DEATH and uncomment.
 # absl_test("btree_test") {
 #   sources = [ "btree_test.cc" ]
diff --git a/third_party/abseil-cpp/absl/container/CMakeLists.txt b/third_party/abseil-cpp/absl/container/CMakeLists.txt
index 3c48270..39d95e0 100644
--- a/third_party/abseil-cpp/absl/container/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/container/CMakeLists.txt
@@ -221,16 +221,16 @@
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
-    absl::counting_allocator
-    absl::inlined_vector
-    absl::test_instance_tracker
+    absl::check
     absl::config
     absl::core_headers
+    absl::counting_allocator
     absl::exception_testing
     absl::hash_testing
+    absl::inlined_vector
     absl::memory
-    absl::raw_logging_internal
     absl::strings
+    absl::test_instance_tracker
     GTest::gmock_main
 )
 
@@ -300,14 +300,14 @@
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
+    absl::any
+    absl::check
     absl::flat_hash_map
     absl::hash_generator_testing
     absl::unordered_map_constructor_test
     absl::unordered_map_lookup_test
     absl::unordered_map_members_test
     absl::unordered_map_modifiers_test
-    absl::any
-    absl::raw_logging_internal
     GTest::gmock_main
 )
 
@@ -337,15 +337,15 @@
     ${ABSL_TEST_COPTS}
     "-DUNORDERED_SET_CXX17"
   DEPS
+    absl::check
     absl::flat_hash_set
     absl::hash_generator_testing
+    absl::memory
+    absl::strings
     absl::unordered_set_constructor_test
     absl::unordered_set_lookup_test
     absl::unordered_set_members_test
     absl::unordered_set_modifiers_test
-    absl::memory
-    absl::raw_logging_internal
-    absl::strings
     GTest::gmock_main
 )
 
@@ -742,7 +742,6 @@
     absl::log
     absl::prefetch
     absl::raw_hash_set
-    absl::raw_logging_internal
     absl::strings
     GTest::gmock_main
 )
@@ -788,9 +787,9 @@
     ${ABSL_TEST_COPTS}
   DEPS
     absl::layout
+    absl::check
     absl::config
     absl::core_headers
-    absl::raw_logging_internal
     absl::span
     GTest::gmock_main
 )
diff --git a/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc b/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc
index 03171f6d..e6acbea2 100644
--- a/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc
+++ b/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc
@@ -16,12 +16,12 @@
 
 #include <memory>
 
-#include "absl/base/internal/raw_logging.h"
 #include "absl/container/internal/hash_generator_testing.h"
 #include "absl/container/internal/unordered_map_constructor_test.h"
 #include "absl/container/internal/unordered_map_lookup_test.h"
 #include "absl/container/internal/unordered_map_members_test.h"
 #include "absl/container/internal/unordered_map_modifiers_test.h"
+#include "absl/log/check.h"
 #include "absl/types/any.h"
 
 namespace absl {
@@ -40,10 +40,10 @@
   BeforeMain() {
     absl::flat_hash_map<int, int> x;
     x.insert({1, 1});
-    ABSL_RAW_CHECK(x.find(0) == x.end(), "x should not contain 0");
+    CHECK(x.find(0) == x.end()) << "x should not contain 0";
     auto it = x.find(1);
-    ABSL_RAW_CHECK(it != x.end(), "x should contain 1");
-    ABSL_RAW_CHECK(it->second, "1 should map to 1");
+    CHECK(it != x.end()) << "x should contain 1";
+    CHECK(it->second) << "1 should map to 1";
   }
 };
 const BeforeMain before_main;
diff --git a/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc b/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc
index b6a72a2..20130f9 100644
--- a/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc
+++ b/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc
@@ -16,12 +16,12 @@
 
 #include <vector>
 
-#include "absl/base/internal/raw_logging.h"
 #include "absl/container/internal/hash_generator_testing.h"
 #include "absl/container/internal/unordered_set_constructor_test.h"
 #include "absl/container/internal/unordered_set_lookup_test.h"
 #include "absl/container/internal/unordered_set_members_test.h"
 #include "absl/container/internal/unordered_set_modifiers_test.h"
+#include "absl/log/check.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
 
@@ -42,8 +42,8 @@
   BeforeMain() {
     absl::flat_hash_set<int> x;
     x.insert(1);
-    ABSL_RAW_CHECK(!x.contains(0), "x should not contain 0");
-    ABSL_RAW_CHECK(x.contains(1), "x should contain 1");
+    CHECK(!x.contains(0)) << "x should not contain 0";
+    CHECK(x.contains(1)) << "x should contain 1";
   }
 };
 const BeforeMain before_main;
diff --git a/third_party/abseil-cpp/absl/container/inlined_vector_test.cc b/third_party/abseil-cpp/absl/container/inlined_vector_test.cc
index 808f97c..6f4625d 100644
--- a/third_party/abseil-cpp/absl/container/inlined_vector_test.cc
+++ b/third_party/abseil-cpp/absl/container/inlined_vector_test.cc
@@ -31,12 +31,12 @@
 #include "gtest/gtest.h"
 #include "absl/base/attributes.h"
 #include "absl/base/internal/exception_testing.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
 #include "absl/base/options.h"
 #include "absl/container/internal/counting_allocator.h"
 #include "absl/container/internal/test_instance_tracker.h"
 #include "absl/hash/hash_testing.h"
+#include "absl/log/check.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/str_cat.h"
 
@@ -103,13 +103,13 @@
   }
 
   void Ref() const {
-    ABSL_RAW_CHECK(count_ != nullptr, "");
+    CHECK_NE(count_, nullptr);
     ++(*count_);
   }
 
   void Unref() const {
     --(*count_);
-    ABSL_RAW_CHECK(*count_ >= 0, "");
+    CHECK_GE(*count_, 0);
   }
 
   int value_;
diff --git a/third_party/abseil-cpp/absl/container/internal/layout_test.cc b/third_party/abseil-cpp/absl/container/internal/layout_test.cc
index 54e5d5bb..ce599ce7 100644
--- a/third_party/abseil-cpp/absl/container/internal/layout_test.cc
+++ b/third_party/abseil-cpp/absl/container/internal/layout_test.cc
@@ -26,7 +26,7 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/check.h"
 #include "absl/types/span.h"
 
 namespace absl {
@@ -38,7 +38,7 @@
 using ::testing::ElementsAre;
 
 size_t Distance(const void* from, const void* to) {
-  ABSL_RAW_CHECK(from <= to, "Distance must be non-negative");
+  CHECK_LE(from, to) << "Distance must be non-negative";
   return static_cast<const char*>(to) - static_cast<const char*>(from);
 }
 
@@ -366,7 +366,7 @@
 }
 
 TEST(Layout, PointerByIndex) {
-  alignas(max_align_t) const unsigned char p[100] = {};
+  alignas(max_align_t) const unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
@@ -447,7 +447,7 @@
 }
 
 TEST(Layout, PointerByType) {
-  alignas(max_align_t) const unsigned char p[100] = {};
+  alignas(max_align_t) const unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(
@@ -526,7 +526,7 @@
 }
 
 TEST(Layout, MutablePointerByIndex) {
-  alignas(max_align_t) unsigned char p[100];
+  alignas(max_align_t) unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
@@ -581,7 +581,7 @@
 }
 
 TEST(Layout, MutablePointerByType) {
-  alignas(max_align_t) unsigned char p[100];
+  alignas(max_align_t) unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p))));
@@ -647,7 +647,7 @@
 }
 
 TEST(Layout, Pointers) {
-  alignas(max_align_t) const unsigned char p[100] = {};
+  alignas(max_align_t) const unsigned char p[100] = {0};
   using L = Layout<int8_t, int8_t, Int128>;
   {
     const auto x = L::Partial();
@@ -683,7 +683,7 @@
 }
 
 TEST(Layout, MutablePointers) {
-  alignas(max_align_t) unsigned char p[100];
+  alignas(max_align_t) unsigned char p[100] = {0};
   using L = Layout<int8_t, int8_t, Int128>;
   {
     const auto x = L::Partial();
@@ -716,7 +716,7 @@
 }
 
 TEST(Layout, SliceByIndexSize) {
-  alignas(max_align_t) const unsigned char p[100] = {};
+  alignas(max_align_t) const unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
@@ -744,7 +744,7 @@
 }
 
 TEST(Layout, SliceByTypeSize) {
-  alignas(max_align_t) const unsigned char p[100] = {};
+  alignas(max_align_t) const unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
@@ -766,7 +766,7 @@
 }
 
 TEST(Layout, MutableSliceByIndexSize) {
-  alignas(max_align_t) unsigned char p[100];
+  alignas(max_align_t) unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
@@ -794,7 +794,7 @@
 }
 
 TEST(Layout, MutableSliceByTypeSize) {
-  alignas(max_align_t) unsigned char p[100];
+  alignas(max_align_t) unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
@@ -816,7 +816,7 @@
 }
 
 TEST(Layout, SliceByIndexData) {
-  alignas(max_align_t) const unsigned char p[100] = {};
+  alignas(max_align_t) const unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(
@@ -939,7 +939,7 @@
 }
 
 TEST(Layout, SliceByTypeData) {
-  alignas(max_align_t) const unsigned char p[100] = {};
+  alignas(max_align_t) const unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(
@@ -1037,7 +1037,7 @@
 }
 
 TEST(Layout, MutableSliceByIndexData) {
-  alignas(max_align_t) unsigned char p[100];
+  alignas(max_align_t) unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(
@@ -1122,7 +1122,7 @@
 }
 
 TEST(Layout, MutableSliceByTypeData) {
-  alignas(max_align_t) unsigned char p[100];
+  alignas(max_align_t) unsigned char p[100] = {0};
   {
     using L = Layout<int32_t>;
     EXPECT_EQ(
@@ -1268,7 +1268,7 @@
 }
 
 TEST(Layout, Slices) {
-  alignas(max_align_t) const unsigned char p[100] = {};
+  alignas(max_align_t) const unsigned char p[100] = {0};
   using L = Layout<int8_t, int8_t, Int128>;
   {
     const auto x = L::Partial();
@@ -1302,7 +1302,7 @@
 }
 
 TEST(Layout, MutableSlices) {
-  alignas(max_align_t) unsigned char p[100] = {};
+  alignas(max_align_t) unsigned char p[100] = {0};
   using L = Layout<int8_t, int8_t, Int128>;
   {
     const auto x = L::Partial();
diff --git a/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc b/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
index c46a593..ce1070b 100644
--- a/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
+++ b/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
@@ -40,7 +40,6 @@
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/internal/cycleclock.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/prefetch.h"
 #include "absl/container/flat_hash_map.h"
 #include "absl/container/flat_hash_set.h"
@@ -1280,7 +1279,7 @@
                 {{0.95, 0}, {0.99, 1}, {0.999, 4}, {0.9999, 10}}};
       }
   }
-  ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width");
+  LOG(FATAL) << "Unknown Group width";
   return {};
 }
 
@@ -1376,7 +1375,7 @@
                 {{0.95, 0}, {0.99, 1}, {0.999, 6}, {0.9999, 10}}};
       }
   }
-  ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width");
+  LOG(FATAL) << "Unknown Group width";
   return {};
 }
 
diff --git a/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc b/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc
index d61b701..83838085 100644
--- a/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc
+++ b/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc
@@ -28,15 +28,12 @@
 #include <intrin.h>
 #endif
 
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace crc_internal {
-
 #if defined(__x86_64__) || defined(_M_X64)
-
-namespace {
-
-#if !defined(_WIN32) && !defined(_WIN64)
+#if ABSL_HAVE_BUILTIN(__cpuid)
+// MSVC-equivalent __cpuid intrinsic declaration for clang-like compilers
+// for non-Windows build environments.
+extern void __cpuid(int[4], int);
+#elif !defined(_WIN32) && !defined(_WIN64)
 // MSVC defines this function for us.
 // https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex
 static void __cpuid(int cpu_info[4], int info_type) {
@@ -46,6 +43,15 @@
                    : "a"(info_type), "c"(0));
 }
 #endif  // !defined(_WIN32) && !defined(_WIN64)
+#endif  // defined(__x86_64__) || defined(_M_X64)
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace crc_internal {
+
+#if defined(__x86_64__) || defined(_M_X64)
+
+namespace {
 
 enum class Vendor {
   kUnknown,
diff --git a/third_party/abseil-cpp/absl/debugging/BUILD.bazel b/third_party/abseil-cpp/absl/debugging/BUILD.bazel
index e89dbae8..42124bf 100644
--- a/third_party/abseil-cpp/absl/debugging/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/debugging/BUILD.bazel
@@ -122,7 +122,8 @@
         "//absl/base",
         "//absl/base:config",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
+        "//absl/log:check",
         "//absl/memory",
         "//absl/strings",
         "@com_google_googletest//:gtest",
@@ -180,6 +181,7 @@
         ":stacktrace",
         ":symbolize",
         "//absl/base:raw_logging_internal",
+        "//absl/log:check",
         "//absl/strings",
         "@com_google_googletest//:gtest",
     ],
@@ -233,7 +235,7 @@
         ":stack_consumption",
         "//absl/base:config",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/memory",
         "@com_google_googletest//:gtest_main",
     ],
@@ -260,7 +262,7 @@
     deps = [
         ":leak_check",
         "//absl/base:config",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "@com_google_googletest//:gtest_main",
     ],
 )
@@ -277,7 +279,7 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":leak_check",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "@com_google_googletest//:gtest_main",
     ],
 )
@@ -306,7 +308,7 @@
     deps = [
         ":stack_consumption",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "@com_google_googletest//:gtest_main",
     ],
 )
diff --git a/third_party/abseil-cpp/absl/debugging/CMakeLists.txt b/third_party/abseil-cpp/absl/debugging/CMakeLists.txt
index ef6b496..65e2af88 100644
--- a/third_party/abseil-cpp/absl/debugging/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/debugging/CMakeLists.txt
@@ -101,14 +101,15 @@
   LINKOPTS
     $<$<BOOL:${MSVC}>:-DEBUG>
   DEPS
-    absl::stack_consumption
-    absl::symbolize
     absl::base
+    absl::check
     absl::config
     absl::core_headers
+    absl::log
     absl::memory
-    absl::raw_logging_internal
+    absl::stack_consumption
     absl::strings
+    absl::symbolize
     GTest::gmock
 )
 
@@ -157,6 +158,7 @@
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
+    absl::check
     absl::failure_signal_handler
     absl::stacktrace
     absl::symbolize
@@ -216,8 +218,8 @@
     absl::stack_consumption
     absl::config
     absl::core_headers
+    absl::log
     absl::memory
-    absl::raw_logging_internal
     GTest::gmock_main
 )
 
@@ -248,6 +250,7 @@
   DEPS
     absl::leak_check
     absl::base
+    absl::log
     GTest::gmock_main
 )
 
@@ -278,7 +281,7 @@
   DEPS
     absl::stack_consumption
     absl::core_headers
-    absl::raw_logging_internal
+    absl::log
     GTest::gmock_main
 )
 
diff --git a/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc b/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc
index 6a62428..72816a3 100644
--- a/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc
+++ b/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc
@@ -22,11 +22,12 @@
 #include <cstring>
 #include <fstream>
 
-#include "gtest/gtest.h"
 #include "gmock/gmock.h"
+#include "gtest/gtest.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/debugging/stacktrace.h"
 #include "absl/debugging/symbolize.h"
+#include "absl/log/check.h"
 #include "absl/strings/match.h"
 #include "absl/strings/str_cat.h"
 
@@ -87,7 +88,7 @@
 // This function runs in a fork()ed process on most systems.
 void InstallHandlerWithWriteToFileAndRaise(const char* file, int signo) {
   error_file = fopen(file, "w");
-  ABSL_RAW_CHECK(error_file != nullptr, "Failed create error_file");
+  CHECK_NE(error_file, nullptr) << "Failed create error_file";
   absl::FailureSignalHandlerOptions options;
   options.writerfn = WriteToErrorFile;
   absl::InstallFailureSignalHandler(options);
diff --git a/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc b/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc
index 2fa4143..faec72b 100644
--- a/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc
+++ b/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc
@@ -19,8 +19,8 @@
 
 #include "gtest/gtest.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/debugging/internal/stack_consumption.h"
+#include "absl/log/log.h"
 #include "absl/memory/memory.h"
 
 namespace absl {
@@ -151,7 +151,7 @@
                                             int *stack_consumed) {
   g_mangled = mangled;
   *stack_consumed = GetSignalHandlerStackConsumption(DemangleSignalHandler);
-  ABSL_RAW_LOG(INFO, "Stack consumption of Demangle: %d", *stack_consumed);
+  LOG(INFO) << "Stack consumption of Demangle: " << *stack_consumed;
   return g_demangle_result;
 }
 
diff --git a/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h b/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h
index 113071a..5f4537ba 100644
--- a/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h
+++ b/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h
@@ -33,7 +33,7 @@
 
 #if defined(__ELF__) && !defined(__OpenBSD__) && !defined(__QNX__) && \
     !defined(__native_client__) && !defined(__asmjs__) &&             \
-    !defined(__wasm__) && !defined(__HAIKU__)
+    !defined(__wasm__) && !defined(__HAIKU__) && !defined(__sun)
 #define ABSL_HAVE_ELF_MEM_IMAGE 1
 #endif
 
diff --git a/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc b/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc
index 80445bf..0255ac8 100644
--- a/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc
+++ b/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc
@@ -20,7 +20,7 @@
 #include <string.h>
 
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -33,7 +33,7 @@
 
   // Never true, but prevents compiler from optimizing buf out.
   if (signo == 0) {
-    ABSL_RAW_LOG(INFO, "%p", static_cast<void*>(buf));
+    LOG(INFO) << static_cast<void*>(buf);
   }
 }
 
diff --git a/third_party/abseil-cpp/absl/debugging/leak_check_fail_test.cc b/third_party/abseil-cpp/absl/debugging/leak_check_fail_test.cc
index c49b81a9..46e9fb6 100644
--- a/third_party/abseil-cpp/absl/debugging/leak_check_fail_test.cc
+++ b/third_party/abseil-cpp/absl/debugging/leak_check_fail_test.cc
@@ -13,9 +13,10 @@
 // limitations under the License.
 
 #include <memory>
+
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/debugging/leak_check.h"
+#include "absl/log/log.h"
 
 namespace {
 
@@ -25,7 +26,7 @@
   // failed exit code.
 
   char* foo = strdup("lsan should complain about this leaked string");
-  ABSL_RAW_LOG(INFO, "Should detect leaked string %s", foo);
+  LOG(INFO) << "Should detect leaked string " << foo;
 }
 
 TEST(LeakCheckTest, LeakMemoryAfterDisablerScope) {
@@ -34,8 +35,7 @@
   // failed exit code.
   { absl::LeakCheckDisabler disabler; }
   char* foo = strdup("lsan should also complain about this leaked string");
-  ABSL_RAW_LOG(INFO, "Re-enabled leak detection.Should detect leaked string %s",
-               foo);
+  LOG(INFO) << "Re-enabled leak detection.Should detect leaked string " << foo;
 }
 
 }  // namespace
diff --git a/third_party/abseil-cpp/absl/debugging/leak_check_test.cc b/third_party/abseil-cpp/absl/debugging/leak_check_test.cc
index 6a42e31..6f0135e 100644
--- a/third_party/abseil-cpp/absl/debugging/leak_check_test.cc
+++ b/third_party/abseil-cpp/absl/debugging/leak_check_test.cc
@@ -16,8 +16,8 @@
 
 #include "gtest/gtest.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/debugging/leak_check.h"
+#include "absl/log/log.h"
 
 namespace {
 
@@ -26,7 +26,7 @@
     GTEST_SKIP() << "LeakChecker is not active";
   }
   auto foo = absl::IgnoreLeak(new std::string("some ignored leaked string"));
-  ABSL_RAW_LOG(INFO, "Ignoring leaked string %s", foo->c_str());
+  LOG(INFO) << "Ignoring leaked string " << foo;
 }
 
 TEST(LeakCheckTest, LeakCheckDisablerIgnoresLeak) {
@@ -35,7 +35,7 @@
   }
   absl::LeakCheckDisabler disabler;
   auto foo = new std::string("some string leaked while checks are disabled");
-  ABSL_RAW_LOG(INFO, "Ignoring leaked string %s", foo->c_str());
+  LOG(INFO) << "Ignoring leaked string " << foo;
 }
 
 }  // namespace
diff --git a/third_party/abseil-cpp/absl/debugging/symbolize_test.cc b/third_party/abseil-cpp/absl/debugging/symbolize_test.cc
index 3165c6e..1d1199f 100644
--- a/third_party/abseil-cpp/absl/debugging/symbolize_test.cc
+++ b/third_party/abseil-cpp/absl/debugging/symbolize_test.cc
@@ -29,9 +29,10 @@
 #include "absl/base/casts.h"
 #include "absl/base/config.h"
 #include "absl/base/internal/per_thread_tls.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/optimization.h"
 #include "absl/debugging/internal/stack_consumption.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
 
@@ -124,15 +125,17 @@
 // absl::Symbolize() returns false, otherwise returns try_symbolize_buffer with
 // the result of absl::Symbolize().
 static const char *TrySymbolizeWithLimit(void *pc, int limit) {
-  ABSL_RAW_CHECK(limit <= sizeof(try_symbolize_buffer),
-                 "try_symbolize_buffer is too small");
+  CHECK_LE(limit, sizeof(try_symbolize_buffer))
+      << "try_symbolize_buffer is too small";
 
   // Use the heap to facilitate heap and buffer sanitizer tools.
   auto heap_buffer = absl::make_unique<char[]>(sizeof(try_symbolize_buffer));
   bool found = absl::Symbolize(pc, heap_buffer.get(), limit);
   if (found) {
-    ABSL_RAW_CHECK(strnlen(heap_buffer.get(), limit) < limit,
-                   "absl::Symbolize() did not properly terminate the string");
+    CHECK_LT(static_cast<int>(
+                 strnlen(heap_buffer.get(), static_cast<size_t>(limit))),
+             limit)
+        << "absl::Symbolize() did not properly terminate the string";
     strncpy(try_symbolize_buffer, heap_buffer.get(),
             sizeof(try_symbolize_buffer) - 1);
     try_symbolize_buffer[sizeof(try_symbolize_buffer) - 1] = '\0';
@@ -155,8 +158,8 @@
 #if defined(ABSL_HAVE_ATTRIBUTE_NOINLINE)
   void *return_address = __builtin_return_address(0);
   const char *symbol = TrySymbolize(return_address);
-  ABSL_RAW_CHECK(symbol != nullptr, "TestWithReturnAddress failed");
-  ABSL_RAW_CHECK(strcmp(symbol, "main") == 0, "TestWithReturnAddress failed");
+  CHECK_NE(symbol, nullptr) << "TestWithReturnAddress failed";
+  CHECK_STREQ(symbol, "main") << "TestWithReturnAddress failed";
   std::cout << "TestWithReturnAddress passed" << std::endl;
 #endif
 }
@@ -314,8 +317,8 @@
 TEST(Symbolize, SymbolizeWithMultipleMaps) {
   // Force kPadding0 and kPadding1 to be linked in.
   if (volatile_bool) {
-    ABSL_RAW_LOG(INFO, "%s", kPadding0);
-    ABSL_RAW_LOG(INFO, "%s", kPadding1);
+    LOG(INFO) << kPadding0;
+    LOG(INFO) << kPadding1;
   }
 
   // Verify we can symbolize everything.
@@ -463,9 +466,9 @@
     (defined(__i386__) || defined(__x86_64__))
   void *pc = non_inline_func();
   const char *symbol = TrySymbolize(pc);
-  ABSL_RAW_CHECK(symbol != nullptr, "TestWithPCInsideNonInlineFunction failed");
-  ABSL_RAW_CHECK(strcmp(symbol, "non_inline_func") == 0,
-                 "TestWithPCInsideNonInlineFunction failed");
+  CHECK_NE(symbol, nullptr) << "TestWithPCInsideNonInlineFunction failed";
+  CHECK_STREQ(symbol, "non_inline_func")
+      << "TestWithPCInsideNonInlineFunction failed";
   std::cout << "TestWithPCInsideNonInlineFunction passed" << std::endl;
 #endif
 }
@@ -475,9 +478,8 @@
     (defined(__i386__) || defined(__x86_64__))
   void *pc = inline_func();  // Must be inlined.
   const char *symbol = TrySymbolize(pc);
-  ABSL_RAW_CHECK(symbol != nullptr, "TestWithPCInsideInlineFunction failed");
-  ABSL_RAW_CHECK(strcmp(symbol, __FUNCTION__) == 0,
-                 "TestWithPCInsideInlineFunction failed");
+  CHECK_NE(symbol, nullptr) << "TestWithPCInsideInlineFunction failed";
+  CHECK_STREQ(symbol, __FUNCTION__) << "TestWithPCInsideInlineFunction failed";
   std::cout << "TestWithPCInsideInlineFunction passed" << std::endl;
 #endif
 }
@@ -519,9 +521,8 @@
 void ABSL_ATTRIBUTE_NOINLINE TestArmThumbOverlap() {
 #if defined(ABSL_HAVE_ATTRIBUTE_NOINLINE)
   const char *symbol = TrySymbolize((void *)&ArmThumbOverlapArm);
-  ABSL_RAW_CHECK(symbol != nullptr, "TestArmThumbOverlap failed");
-  ABSL_RAW_CHECK(strcmp("ArmThumbOverlapArm()", symbol) == 0,
-                 "TestArmThumbOverlap failed");
+  CHECK_NE(symbol, nullptr) << "TestArmThumbOverlap failed";
+  CHECK_STREQ("ArmThumbOverlapArm()", symbol) << "TestArmThumbOverlap failed";
   std::cout << "TestArmThumbOverlap passed" << std::endl;
 #endif
 }
@@ -584,7 +585,7 @@
 #if !defined(__EMSCRIPTEN__)
   // Make sure kHpageTextPadding is linked into the binary.
   if (volatile_bool) {
-    ABSL_RAW_LOG(INFO, "%s", kHpageTextPadding);
+    LOG(INFO) << kHpageTextPadding;
   }
 #endif  // !defined(__EMSCRIPTEN__)
 
diff --git a/third_party/abseil-cpp/absl/flags/BUILD.bazel b/third_party/abseil-cpp/absl/flags/BUILD.bazel
index 570d280..627f453a 100644
--- a/third_party/abseil-cpp/absl/flags/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/flags/BUILD.bazel
@@ -452,8 +452,8 @@
         ":parse",
         ":reflection",
         ":usage_internal",
-        "//absl/base:raw_logging_internal",
         "//absl/base:scoped_set_env",
+        "//absl/log",
         "//absl/strings",
         "//absl/types:span",
         "@com_google_googletest//:gtest_main",
diff --git a/third_party/abseil-cpp/absl/flags/CMakeLists.txt b/third_party/abseil-cpp/absl/flags/CMakeLists.txt
index b5f6dfc..b9d3b97b 100644
--- a/third_party/abseil-cpp/absl/flags/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/flags/CMakeLists.txt
@@ -374,7 +374,7 @@
     absl::flags_parse
     absl::flags_reflection
     absl::flags_usage_internal
-    absl::raw_logging_internal
+    absl::log
     absl::scoped_set_env
     absl::span
     absl::strings
diff --git a/third_party/abseil-cpp/absl/flags/parse_test.cc b/third_party/abseil-cpp/absl/flags/parse_test.cc
index cd32efc..97b7898 100644
--- a/third_party/abseil-cpp/absl/flags/parse_test.cc
+++ b/third_party/abseil-cpp/absl/flags/parse_test.cc
@@ -24,12 +24,12 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/internal/scoped_set_env.h"
 #include "absl/flags/flag.h"
 #include "absl/flags/internal/parse.h"
 #include "absl/flags/internal/usage.h"
 #include "absl/flags/reflection.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 #include "absl/strings/substitute.h"
@@ -150,8 +150,7 @@
     }
 
     if (res->empty()) {
-      ABSL_INTERNAL_LOG(FATAL,
-                        "Failed to make temporary directory for data files");
+      LOG(FATAL) << "Failed to make temporary directory for data files";
     }
 
 #ifdef _WIN32
diff --git a/third_party/abseil-cpp/absl/functional/CMakeLists.txt b/third_party/abseil-cpp/absl/functional/CMakeLists.txt
index 628b2ff..c704e04 100644
--- a/third_party/abseil-cpp/absl/functional/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/functional/CMakeLists.txt
@@ -39,7 +39,7 @@
     "any_invocable_test.cc"
     "internal/any_invocable.h"
   COPTS
-    ${ABSL_DEFAULT_COPTS}
+    ${ABSL_TEST_COPTS}
   DEPS
     absl::any_invocable
     absl::base_internal
diff --git a/third_party/abseil-cpp/absl/functional/internal/any_invocable.h b/third_party/abseil-cpp/absl/functional/internal/any_invocable.h
index d41b7e56..a52fa87 100644
--- a/third_party/abseil-cpp/absl/functional/internal/any_invocable.h
+++ b/third_party/abseil-cpp/absl/functional/internal/any_invocable.h
@@ -135,8 +135,16 @@
 template <class ReturnType, class F, class... P,
           absl::enable_if_t<!std::is_void<ReturnType>::value, int> = 0>
 ReturnType InvokeR(F&& f, P&&... args) {
+  // GCC 12 has a false-positive -Wmaybe-uninitialized warning here.
+#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
   return absl::base_internal::invoke(std::forward<F>(f),
                                      std::forward<P>(args)...);
+#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
+#pragma GCC diagnostic pop
+#endif
 }
 
 //
@@ -197,7 +205,7 @@
 template <class T>
 T& ObjectInLocalStorage(TypeErasedState* const state) {
   // We launder here because the storage may be reused with the same type.
-#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
+#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606L
   return *std::launder(reinterpret_cast<T*>(&state->storage));
 #elif ABSL_HAVE_BUILTIN(__builtin_launder)
   return *__builtin_launder(reinterpret_cast<T*>(&state->storage));
diff --git a/third_party/abseil-cpp/absl/log/BUILD.bazel b/third_party/abseil-cpp/absl/log/BUILD.bazel
index 4813111..e141063 100644
--- a/third_party/abseil-cpp/absl/log/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/log/BUILD.bazel
@@ -289,7 +289,7 @@
         "no_test_ios",
         "no_test_wasm",
     ],
-    textual_hdrs = ["check_test_impl.h"],
+    textual_hdrs = ["check_test_impl.inc"],
     visibility = ["//visibility:private"],
     deps = [
         "//absl/base:config",
@@ -373,7 +373,7 @@
     testonly = True,
     copts = ABSL_TEST_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
-    textual_hdrs = ["log_basic_test_impl.h"],
+    textual_hdrs = ["log_basic_test_impl.inc"],
     visibility = ["//visibility:private"],
     deps = [
         "//absl/base",
@@ -459,7 +459,6 @@
         ":log_sink_registry",
         ":scoped_mock_log",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
         "//absl/log/internal:test_actions",
         "//absl/log/internal:test_helpers",
         "//absl/log/internal:test_matchers",
diff --git a/third_party/abseil-cpp/absl/log/BUILD.gn b/third_party/abseil-cpp/absl/log/BUILD.gn
index 1e5eab27..febc0e8 100644
--- a/third_party/abseil-cpp/absl/log/BUILD.gn
+++ b/third_party/abseil-cpp/absl/log/BUILD.gn
@@ -186,7 +186,7 @@
 
 absl_source_set("check_test_impl") {
   testonly = true
-  public = [ "check_test_impl.h" ]
+  public = [ "check_test_impl.inc" ]
   visibility = [ ":*" ]
   deps = [
     "//third_party/abseil-cpp/absl/base:config",
@@ -247,7 +247,7 @@
 }
 
 absl_source_set("log_basic_test_impl") {
-  public = [ "log_basic_test_impl.h" ]
+  public = [ "log_basic_test_impl.inc" ]
   testonly = true
   visibility = [ ":*" ]
   deps = [
@@ -314,7 +314,6 @@
     ":log_sink_registry",
     ":scoped_mock_log",
     "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/base:raw_logging_internal",
     "//third_party/abseil-cpp/absl/log/internal:test_actions",
     "//third_party/abseil-cpp/absl/log/internal:test_helpers",
     "//third_party/abseil-cpp/absl/log/internal:test_matchers",
diff --git a/third_party/abseil-cpp/absl/log/CMakeLists.txt b/third_party/abseil-cpp/absl/log/CMakeLists.txt
index 4cba0082..9320ce5 100644
--- a/third_party/abseil-cpp/absl/log/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/log/CMakeLists.txt
@@ -1,4 +1,3 @@
-#
 # Copyright 2022 The Abseil Authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -679,7 +678,7 @@
     absl_check_test
   SRCS
     "absl_check_test.cc"
-    "check_test_impl.h"
+    "check_test_impl.inc"
   COPTS
     ${ABSL_TEST_COPTS}
   LINKOPTS
@@ -699,7 +698,7 @@
     absl_log_basic_test
   SRCS
     "log_basic_test.cc"
-    "log_basic_test_impl.h"
+    "log_basic_test_impl.inc"
   COPTS
     ${ABSL_TEST_COPTS}
   LINKOPTS
@@ -723,7 +722,7 @@
     check_test
   SRCS
     "check_test.cc"
-    "check_test_impl.h"
+    "check_test_impl.inc"
   COPTS
     ${ABSL_TEST_COPTS}
   LINKOPTS
@@ -759,7 +758,7 @@
     log_basic_test
   SRCS
     "log_basic_test.cc"
-    "log_basic_test_impl.h"
+    "log_basic_test_impl.inc"
   COPTS
     ${ABSL_TEST_COPTS}
   LINKOPTS
@@ -906,7 +905,6 @@
     absl::log_sink
     absl::log_sink_registry
     absl::log_severity
-    absl::raw_logging_internal
     absl::scoped_mock_log
     absl::strings
     GTest::gtest_main
diff --git a/third_party/abseil-cpp/absl/log/absl_check.h b/third_party/abseil-cpp/absl/log/absl_check.h
index 14a2307..1bb43bd 100644
--- a/third_party/abseil-cpp/absl/log/absl_check.h
+++ b/third_party/abseil-cpp/absl/log/absl_check.h
@@ -37,69 +37,81 @@
 
 #include "absl/log/internal/check_impl.h"
 
-#define ABSL_CHECK(condition) ABSL_CHECK_IMPL((condition), #condition)
-#define ABSL_QCHECK(condition) ABSL_QCHECK_IMPL((condition), #condition)
-#define ABSL_PCHECK(condition) ABSL_PCHECK_IMPL((condition), #condition)
-#define ABSL_DCHECK(condition) ABSL_DCHECK_IMPL((condition), #condition)
+#define ABSL_CHECK(condition) \
+  ABSL_LOG_INTERNAL_CHECK_IMPL((condition), #condition)
+#define ABSL_QCHECK(condition) \
+  ABSL_LOG_INTERNAL_QCHECK_IMPL((condition), #condition)
+#define ABSL_PCHECK(condition) \
+  ABSL_LOG_INTERNAL_PCHECK_IMPL((condition), #condition)
+#define ABSL_DCHECK(condition) \
+  ABSL_LOG_INTERNAL_DCHECK_IMPL((condition), #condition)
 
 #define ABSL_CHECK_EQ(val1, val2) \
-  ABSL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_CHECK_NE(val1, val2) \
-  ABSL_CHECK_NE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_CHECK_NE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_CHECK_LE(val1, val2) \
-  ABSL_CHECK_LE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_CHECK_LE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_CHECK_LT(val1, val2) \
-  ABSL_CHECK_LT_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_CHECK_LT_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_CHECK_GE(val1, val2) \
-  ABSL_CHECK_GE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_CHECK_GE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_CHECK_GT(val1, val2) \
-  ABSL_CHECK_GT_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_CHECK_GT_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_QCHECK_EQ(val1, val2) \
-  ABSL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_QCHECK_NE(val1, val2) \
-  ABSL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_QCHECK_LE(val1, val2) \
-  ABSL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_QCHECK_LT(val1, val2) \
-  ABSL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_QCHECK_GE(val1, val2) \
-  ABSL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_QCHECK_GT(val1, val2) \
-  ABSL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_DCHECK_EQ(val1, val2) \
-  ABSL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_DCHECK_NE(val1, val2) \
-  ABSL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_DCHECK_LE(val1, val2) \
-  ABSL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_DCHECK_LT(val1, val2) \
-  ABSL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_DCHECK_GE(val1, val2) \
-  ABSL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2)
 #define ABSL_DCHECK_GT(val1, val2) \
-  ABSL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2)
+  ABSL_LOG_INTERNAL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2)
 
-#define ABSL_CHECK_OK(status) ABSL_CHECK_OK_IMPL((status), #status)
-#define ABSL_QCHECK_OK(status) ABSL_QCHECK_OK_IMPL((status), #status)
-#define ABSL_DCHECK_OK(status) ABSL_DCHECK_OK_IMPL((status), #status)
+#define ABSL_CHECK_OK(status) ABSL_LOG_INTERNAL_CHECK_OK_IMPL((status), #status)
+#define ABSL_QCHECK_OK(status) \
+  ABSL_LOG_INTERNAL_QCHECK_OK_IMPL((status), #status)
+#define ABSL_DCHECK_OK(status) \
+  ABSL_LOG_INTERNAL_DCHECK_OK_IMPL((status), #status)
 
-#define ABSL_CHECK_STREQ(s1, s2) ABSL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
-#define ABSL_CHECK_STRNE(s1, s2) ABSL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
+#define ABSL_CHECK_STREQ(s1, s2) \
+  ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
+#define ABSL_CHECK_STRNE(s1, s2) \
+  ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
 #define ABSL_CHECK_STRCASEEQ(s1, s2) \
-  ABSL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
 #define ABSL_CHECK_STRCASENE(s1, s2) \
-  ABSL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
-#define ABSL_QCHECK_STREQ(s1, s2) ABSL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
-#define ABSL_QCHECK_STRNE(s1, s2) ABSL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
+#define ABSL_QCHECK_STREQ(s1, s2) \
+  ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
+#define ABSL_QCHECK_STRNE(s1, s2) \
+  ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
 #define ABSL_QCHECK_STRCASEEQ(s1, s2) \
-  ABSL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
 #define ABSL_QCHECK_STRCASENE(s1, s2) \
-  ABSL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
-#define ABSL_DCHECK_STREQ(s1, s2) ABSL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
-#define ABSL_DCHECK_STRNE(s1, s2) ABSL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
+#define ABSL_DCHECK_STREQ(s1, s2) \
+  ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
+#define ABSL_DCHECK_STRNE(s1, s2) \
+  ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
 #define ABSL_DCHECK_STRCASEEQ(s1, s2) \
-  ABSL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
 #define ABSL_DCHECK_STRCASENE(s1, s2) \
-  ABSL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
 
 #endif  // ABSL_LOG_ABSL_CHECK_H_
diff --git a/third_party/abseil-cpp/absl/log/absl_check_test.cc b/third_party/abseil-cpp/absl/log/absl_check_test.cc
index 8ddacdb1..d84940f 100644
--- a/third_party/abseil-cpp/absl/log/absl_check_test.cc
+++ b/third_party/abseil-cpp/absl/log/absl_check_test.cc
@@ -55,4 +55,4 @@
 #define ABSL_TEST_QCHECK_STRCASENE ABSL_QCHECK_STRCASENE
 
 #include "gtest/gtest.h"
-#include "absl/log/check_test_impl.h"
+#include "absl/log/check_test_impl.inc"
diff --git a/third_party/abseil-cpp/absl/log/absl_log.h b/third_party/abseil-cpp/absl/log/absl_log.h
index 1c6cf26..0517760b 100644
--- a/third_party/abseil-cpp/absl/log/absl_log.h
+++ b/third_party/abseil-cpp/absl/log/absl_log.h
@@ -35,60 +35,69 @@
 
 #include "absl/log/internal/log_impl.h"
 
-#define ABSL_LOG(severity) ABSL_LOG_IMPL(_##severity)
-#define ABSL_PLOG(severity) ABSL_PLOG_IMPL(_##severity)
-#define ABSL_DLOG(severity) ABSL_DLOG_IMPL(_##severity)
+#define ABSL_LOG(severity) ABSL_LOG_INTERNAL_LOG_IMPL(_##severity)
+#define ABSL_PLOG(severity) ABSL_LOG_INTERNAL_PLOG_IMPL(_##severity)
+#define ABSL_DLOG(severity) ABSL_LOG_INTERNAL_DLOG_IMPL(_##severity)
 
 #define ABSL_LOG_IF(severity, condition) \
-  ABSL_LOG_IF_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_LOG_IF_IMPL(_##severity, condition)
 #define ABSL_PLOG_IF(severity, condition) \
-  ABSL_PLOG_IF_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_PLOG_IF_IMPL(_##severity, condition)
 #define ABSL_DLOG_IF(severity, condition) \
-  ABSL_DLOG_IF_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_DLOG_IF_IMPL(_##severity, condition)
 
-#define ABSL_LOG_EVERY_N(severity, n) ABSL_LOG_EVERY_N_IMPL(_##severity, n)
-#define ABSL_LOG_FIRST_N(severity, n) ABSL_LOG_FIRST_N_IMPL(_##severity, n)
-#define ABSL_LOG_EVERY_POW_2(severity) ABSL_LOG_EVERY_POW_2_IMPL(_##severity)
+#define ABSL_LOG_EVERY_N(severity, n) \
+  ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(_##severity, n)
+#define ABSL_LOG_FIRST_N(severity, n) \
+  ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(_##severity, n)
+#define ABSL_LOG_EVERY_POW_2(severity) \
+  ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(_##severity)
 #define ABSL_LOG_EVERY_N_SEC(severity, n_seconds) \
-  ABSL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
+  ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
 
-#define ABSL_PLOG_EVERY_N(severity, n) ABSL_PLOG_EVERY_N_IMPL(_##severity, n)
-#define ABSL_PLOG_FIRST_N(severity, n) ABSL_PLOG_FIRST_N_IMPL(_##severity, n)
-#define ABSL_PLOG_EVERY_POW_2(severity) ABSL_PLOG_EVERY_POW_2_IMPL(_##severity)
+#define ABSL_PLOG_EVERY_N(severity, n) \
+  ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(_##severity, n)
+#define ABSL_PLOG_FIRST_N(severity, n) \
+  ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(_##severity, n)
+#define ABSL_PLOG_EVERY_POW_2(severity) \
+  ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(_##severity)
 #define ABSL_PLOG_EVERY_N_SEC(severity, n_seconds) \
-  ABSL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
+  ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
 
-#define ABSL_DLOG_EVERY_N(severity, n) ABSL_DLOG_EVERY_N_IMPL(_##severity, n)
-#define ABSL_DLOG_FIRST_N(severity, n) ABSL_DLOG_FIRST_N_IMPL(_##severity, n)
-#define ABSL_DLOG_EVERY_POW_2(severity) ABSL_DLOG_EVERY_POW_2_IMPL(_##severity)
+#define ABSL_DLOG_EVERY_N(severity, n) \
+  ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(_##severity, n)
+#define ABSL_DLOG_FIRST_N(severity, n) \
+  ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(_##severity, n)
+#define ABSL_DLOG_EVERY_POW_2(severity) \
+  ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(_##severity)
 #define ABSL_DLOG_EVERY_N_SEC(severity, n_seconds) \
-  ABSL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
+  ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
 
 #define ABSL_LOG_IF_EVERY_N(severity, condition, n) \
-  ABSL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n)
 #define ABSL_LOG_IF_FIRST_N(severity, condition, n) \
-  ABSL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n)
 #define ABSL_LOG_IF_EVERY_POW_2(severity, condition) \
-  ABSL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
 #define ABSL_LOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
-  ABSL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
+  ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
 
 #define ABSL_PLOG_IF_EVERY_N(severity, condition, n) \
-  ABSL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
 #define ABSL_PLOG_IF_FIRST_N(severity, condition, n) \
-  ABSL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
 #define ABSL_PLOG_IF_EVERY_POW_2(severity, condition) \
-  ABSL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
 #define ABSL_PLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
-  ABSL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
+  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
 
 #define ABSL_DLOG_IF_EVERY_N(severity, condition, n) \
-  ABSL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
 #define ABSL_DLOG_IF_FIRST_N(severity, condition, n) \
-  ABSL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
 #define ABSL_DLOG_IF_EVERY_POW_2(severity, condition) \
-  ABSL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
 #define ABSL_DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
-  ABSL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
+  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
 
 #endif  // ABSL_LOG_ABSL_LOG_H_
diff --git a/third_party/abseil-cpp/absl/log/absl_log_basic_test.cc b/third_party/abseil-cpp/absl/log/absl_log_basic_test.cc
index bc8a787..3a4b83c 100644
--- a/third_party/abseil-cpp/absl/log/absl_log_basic_test.cc
+++ b/third_party/abseil-cpp/absl/log/absl_log_basic_test.cc
@@ -18,4 +18,4 @@
 #define ABSL_TEST_LOG ABSL_LOG
 
 #include "gtest/gtest.h"
-#include "absl/log/log_basic_test_impl.h"
+#include "absl/log/log_basic_test_impl.inc"
diff --git a/third_party/abseil-cpp/absl/log/check.h b/third_party/abseil-cpp/absl/log/check.h
index 33145a57..0a2f2e4 100644
--- a/third_party/abseil-cpp/absl/log/check.h
+++ b/third_party/abseil-cpp/absl/log/check.h
@@ -54,7 +54,7 @@
 // Might produce a message like:
 //
 //   Check failed: !cheese.empty() Out of Cheese
-#define CHECK(condition) ABSL_CHECK_IMPL((condition), #condition)
+#define CHECK(condition) ABSL_LOG_INTERNAL_CHECK_IMPL((condition), #condition)
 
 // QCHECK()
 //
@@ -62,7 +62,7 @@
 // not run registered error handlers (as `QFATAL`).  It is useful when the
 // problem is definitely unrelated to program flow, e.g. when validating user
 // input.
-#define QCHECK(condition) ABSL_QCHECK_IMPL((condition), #condition)
+#define QCHECK(condition) ABSL_LOG_INTERNAL_QCHECK_IMPL((condition), #condition)
 
 // PCHECK()
 //
@@ -77,7 +77,7 @@
 // Might produce a message like:
 //
 //   Check failed: fd != -1 posix is difficult: No such file or directory [2]
-#define PCHECK(condition) ABSL_PCHECK_IMPL((condition), #condition)
+#define PCHECK(condition) ABSL_LOG_INTERNAL_PCHECK_IMPL((condition), #condition)
 
 // DCHECK()
 //
@@ -85,7 +85,7 @@
 // `DLOG`).  Unlike with `CHECK` (but as with `assert`), it is not safe to rely
 // on evaluation of `condition`: when `NDEBUG` is enabled, DCHECK does not
 // evaluate the condition.
-#define DCHECK(condition) ABSL_DCHECK_IMPL((condition), #condition)
+#define DCHECK(condition) ABSL_LOG_INTERNAL_DCHECK_IMPL((condition), #condition)
 
 // `CHECK_EQ` and friends are syntactic sugar for `CHECK(x == y)` that
 // automatically output the expression being tested and the evaluated values on
@@ -113,24 +113,42 @@
 //
 // WARNING: Passing `NULL` as an argument to `CHECK_EQ` and similar macros does
 // not compile.  Use `nullptr` instead.
-#define CHECK_EQ(val1, val2) ABSL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2)
-#define CHECK_NE(val1, val2) ABSL_CHECK_NE_IMPL((val1), #val1, (val2), #val2)
-#define CHECK_LE(val1, val2) ABSL_CHECK_LE_IMPL((val1), #val1, (val2), #val2)
-#define CHECK_LT(val1, val2) ABSL_CHECK_LT_IMPL((val1), #val1, (val2), #val2)
-#define CHECK_GE(val1, val2) ABSL_CHECK_GE_IMPL((val1), #val1, (val2), #val2)
-#define CHECK_GT(val1, val2) ABSL_CHECK_GT_IMPL((val1), #val1, (val2), #val2)
-#define QCHECK_EQ(val1, val2) ABSL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
-#define QCHECK_NE(val1, val2) ABSL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2)
-#define QCHECK_LE(val1, val2) ABSL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2)
-#define QCHECK_LT(val1, val2) ABSL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2)
-#define QCHECK_GE(val1, val2) ABSL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2)
-#define QCHECK_GT(val1, val2) ABSL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2)
-#define DCHECK_EQ(val1, val2) ABSL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
-#define DCHECK_NE(val1, val2) ABSL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2)
-#define DCHECK_LE(val1, val2) ABSL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2)
-#define DCHECK_LT(val1, val2) ABSL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2)
-#define DCHECK_GE(val1, val2) ABSL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2)
-#define DCHECK_GT(val1, val2) ABSL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2)
+#define CHECK_EQ(val1, val2) \
+  ABSL_LOG_INTERNAL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2)
+#define CHECK_NE(val1, val2) \
+  ABSL_LOG_INTERNAL_CHECK_NE_IMPL((val1), #val1, (val2), #val2)
+#define CHECK_LE(val1, val2) \
+  ABSL_LOG_INTERNAL_CHECK_LE_IMPL((val1), #val1, (val2), #val2)
+#define CHECK_LT(val1, val2) \
+  ABSL_LOG_INTERNAL_CHECK_LT_IMPL((val1), #val1, (val2), #val2)
+#define CHECK_GE(val1, val2) \
+  ABSL_LOG_INTERNAL_CHECK_GE_IMPL((val1), #val1, (val2), #val2)
+#define CHECK_GT(val1, val2) \
+  ABSL_LOG_INTERNAL_CHECK_GT_IMPL((val1), #val1, (val2), #val2)
+#define QCHECK_EQ(val1, val2) \
+  ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
+#define QCHECK_NE(val1, val2) \
+  ABSL_LOG_INTERNAL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2)
+#define QCHECK_LE(val1, val2) \
+  ABSL_LOG_INTERNAL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2)
+#define QCHECK_LT(val1, val2) \
+  ABSL_LOG_INTERNAL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2)
+#define QCHECK_GE(val1, val2) \
+  ABSL_LOG_INTERNAL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2)
+#define QCHECK_GT(val1, val2) \
+  ABSL_LOG_INTERNAL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2)
+#define DCHECK_EQ(val1, val2) \
+  ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
+#define DCHECK_NE(val1, val2) \
+  ABSL_LOG_INTERNAL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2)
+#define DCHECK_LE(val1, val2) \
+  ABSL_LOG_INTERNAL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2)
+#define DCHECK_LT(val1, val2) \
+  ABSL_LOG_INTERNAL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2)
+#define DCHECK_GE(val1, val2) \
+  ABSL_LOG_INTERNAL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2)
+#define DCHECK_GT(val1, val2) \
+  ABSL_LOG_INTERNAL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2)
 
 // `CHECK_OK` and friends validate that the provided `absl::Status` or
 // `absl::StatusOr<T>` is OK.  If it isn't, they print a failure message that
@@ -146,9 +164,9 @@
 // Might produce a message like:
 //
 //   Check failed: FunctionReturnsStatus(x, y, z) is OK (ABORTED: timeout) oops!
-#define CHECK_OK(status) ABSL_CHECK_OK_IMPL((status), #status)
-#define QCHECK_OK(status) ABSL_QCHECK_OK_IMPL((status), #status)
-#define DCHECK_OK(status) ABSL_DCHECK_OK_IMPL((status), #status)
+#define CHECK_OK(status) ABSL_LOG_INTERNAL_CHECK_OK_IMPL((status), #status)
+#define QCHECK_OK(status) ABSL_LOG_INTERNAL_QCHECK_OK_IMPL((status), #status)
+#define DCHECK_OK(status) ABSL_LOG_INTERNAL_DCHECK_OK_IMPL((status), #status)
 
 // `CHECK_STREQ` and friends provide `CHECK_EQ` functionality for C strings,
 // i.e., nul-terminated char arrays.  The `CASE` versions are case-insensitive.
@@ -163,21 +181,29 @@
 // Example:
 //
 //   CHECK_STREQ(Foo().c_str(), Bar().c_str());
-#define CHECK_STREQ(s1, s2) ABSL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
-#define CHECK_STRNE(s1, s2) ABSL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
-#define CHECK_STRCASEEQ(s1, s2) ABSL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
-#define CHECK_STRCASENE(s1, s2) ABSL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
-#define QCHECK_STREQ(s1, s2) ABSL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
-#define QCHECK_STRNE(s1, s2) ABSL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
+#define CHECK_STREQ(s1, s2) \
+  ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
+#define CHECK_STRNE(s1, s2) \
+  ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
+#define CHECK_STRCASEEQ(s1, s2) \
+  ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
+#define CHECK_STRCASENE(s1, s2) \
+  ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
+#define QCHECK_STREQ(s1, s2) \
+  ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
+#define QCHECK_STRNE(s1, s2) \
+  ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
 #define QCHECK_STRCASEEQ(s1, s2) \
-  ABSL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
 #define QCHECK_STRCASENE(s1, s2) \
-  ABSL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
-#define DCHECK_STREQ(s1, s2) ABSL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
-#define DCHECK_STRNE(s1, s2) ABSL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
+#define DCHECK_STREQ(s1, s2) \
+  ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
+#define DCHECK_STRNE(s1, s2) \
+  ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
 #define DCHECK_STRCASEEQ(s1, s2) \
-  ABSL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
 #define DCHECK_STRCASENE(s1, s2) \
-  ABSL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
+  ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
 
 #endif  // ABSL_LOG_CHECK_H_
diff --git a/third_party/abseil-cpp/absl/log/check_test.cc b/third_party/abseil-cpp/absl/log/check_test.cc
index f44a686e..ef415bd4 100644
--- a/third_party/abseil-cpp/absl/log/check_test.cc
+++ b/third_party/abseil-cpp/absl/log/check_test.cc
@@ -55,4 +55,4 @@
 #define ABSL_TEST_QCHECK_STRCASENE QCHECK_STRCASENE
 
 #include "gtest/gtest.h"
-#include "absl/log/check_test_impl.h"
+#include "absl/log/check_test_impl.inc"
diff --git a/third_party/abseil-cpp/absl/log/check_test_impl.h b/third_party/abseil-cpp/absl/log/check_test_impl.inc
similarity index 100%
rename from third_party/abseil-cpp/absl/log/check_test_impl.h
rename to third_party/abseil-cpp/absl/log/check_test_impl.inc
diff --git a/third_party/abseil-cpp/absl/log/internal/check_impl.h b/third_party/abseil-cpp/absl/log/internal/check_impl.h
index c9c28e3..00f25f80 100644
--- a/third_party/abseil-cpp/absl/log/internal/check_impl.h
+++ b/third_party/abseil-cpp/absl/log/internal/check_impl.h
@@ -22,128 +22,128 @@
 #include "absl/log/internal/strip.h"
 
 // CHECK
-#define ABSL_CHECK_IMPL(condition, condition_text)                    \
+#define ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text)       \
   ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS,                        \
                                     ABSL_PREDICT_FALSE(!(condition))) \
   ABSL_LOG_INTERNAL_CHECK(condition_text).InternalStream()
 
-#define ABSL_QCHECK_IMPL(condition, condition_text)                    \
+#define ABSL_LOG_INTERNAL_QCHECK_IMPL(condition, condition_text)       \
   ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS,                        \
                                      ABSL_PREDICT_FALSE(!(condition))) \
   ABSL_LOG_INTERNAL_QCHECK(condition_text).InternalStream()
 
-#define ABSL_PCHECK_IMPL(condition, condition_text) \
-  ABSL_CHECK_IMPL(condition, condition_text).WithPerror()
+#define ABSL_LOG_INTERNAL_PCHECK_IMPL(condition, condition_text) \
+  ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text).WithPerror()
 
 #ifndef NDEBUG
-#define ABSL_DCHECK_IMPL(condition, condition_text) \
-  ABSL_CHECK_IMPL(condition, condition_text)
+#define ABSL_LOG_INTERNAL_DCHECK_IMPL(condition, condition_text) \
+  ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text)
 #else
-#define ABSL_DCHECK_IMPL(condition, condition_text) \
-  ABSL_CHECK_IMPL(true || (condition), "true")
+#define ABSL_LOG_INTERNAL_DCHECK_IMPL(condition, condition_text) \
+  ABSL_LOG_INTERNAL_CHECK_IMPL(true || (condition), "true")
 #endif
 
 // CHECK_EQ
-#define ABSL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_CHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text)
-#define ABSL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_CHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text)
-#define ABSL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_CHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text)
-#define ABSL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_CHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text)
-#define ABSL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_CHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text)
-#define ABSL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_CHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text)
-#define ABSL_QCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_QCHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text)
-#define ABSL_QCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_QCHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text)
-#define ABSL_QCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_QCHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text)
-#define ABSL_QCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_QCHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text)
-#define ABSL_QCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_QCHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text)
-#define ABSL_QCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_QCHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text)
 #ifndef NDEBUG
-#define ABSL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
-  ABSL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text)
-#define ABSL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
-  ABSL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text)
-#define ABSL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
-  ABSL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text)
-#define ABSL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
-  ABSL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text)
-#define ABSL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
-  ABSL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text)
-#define ABSL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
-  ABSL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
+  ABSL_LOG_INTERNAL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
+  ABSL_LOG_INTERNAL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
+  ABSL_LOG_INTERNAL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
+  ABSL_LOG_INTERNAL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
+  ABSL_LOG_INTERNAL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
+  ABSL_LOG_INTERNAL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text)
 #else  // ndef NDEBUG
-#define ABSL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
-#define ABSL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
-#define ABSL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
-#define ABSL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
-#define ABSL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
-#define ABSL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
 #endif  // def NDEBUG
 
 // CHECK_OK
-#define ABSL_CHECK_OK_IMPL(status, status_text) \
+#define ABSL_LOG_INTERNAL_CHECK_OK_IMPL(status, status_text) \
   ABSL_LOG_INTERNAL_CHECK_OK(status, status_text)
-#define ABSL_QCHECK_OK_IMPL(status, status_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_OK_IMPL(status, status_text) \
   ABSL_LOG_INTERNAL_QCHECK_OK(status, status_text)
 #ifndef NDEBUG
-#define ABSL_DCHECK_OK_IMPL(status, status_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_OK_IMPL(status, status_text) \
   ABSL_LOG_INTERNAL_CHECK_OK(status, status_text)
 #else
-#define ABSL_DCHECK_OK_IMPL(status, status_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_OK_IMPL(status, status_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(status, nullptr)
 #endif
 
 // CHECK_STREQ
-#define ABSL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text)
-#define ABSL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text)
-#define ABSL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text)
-#define ABSL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, s2_text)
-#define ABSL_QCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text)
-#define ABSL_QCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text)
-#define ABSL_QCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text)
-#define ABSL_QCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text)             \
-  ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, \
+#define ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
+  ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2,  \
                                  s2_text)
 #ifndef NDEBUG
-#define ABSL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
-  ABSL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text)
-#define ABSL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
-  ABSL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text)
-#define ABSL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
-  ABSL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text)
-#define ABSL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
-  ABSL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
+  ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
+  ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
+  ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text)
+#define ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
+  ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text)
 #else  // ndef NDEBUG
-#define ABSL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
-#define ABSL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
-#define ABSL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
-#define ABSL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
+#define ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
   ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
 #endif  // def NDEBUG
 
diff --git a/third_party/abseil-cpp/absl/log/internal/log_impl.h b/third_party/abseil-cpp/absl/log/internal/log_impl.h
index 82b5ed8..9326780 100644
--- a/third_party/abseil-cpp/absl/log/internal/log_impl.h
+++ b/third_party/abseil-cpp/absl/log/internal/log_impl.h
@@ -20,190 +20,194 @@
 #include "absl/log/internal/strip.h"
 
 // ABSL_LOG()
-#define ABSL_LOG_IMPL(severity)                          \
+#define ABSL_LOG_INTERNAL_LOG_IMPL(severity)             \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
 // ABSL_PLOG()
-#define ABSL_PLOG_IMPL(severity)                           \
+#define ABSL_LOG_INTERNAL_PLOG_IMPL(severity)              \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true)   \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
           .WithPerror()
 
 // ABSL_DLOG()
 #ifndef NDEBUG
-#define ABSL_DLOG_IMPL(severity)                         \
+#define ABSL_LOG_INTERNAL_DLOG_IMPL(severity)            \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 #else
-#define ABSL_DLOG_IMPL(severity)                          \
+#define ABSL_LOG_INTERNAL_DLOG_IMPL(severity)             \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, false) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 #endif
 
-#define ABSL_LOG_IF_IMPL(severity, condition)                 \
+#define ABSL_LOG_INTERNAL_LOG_IF_IMPL(severity, condition)    \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
-#define ABSL_PLOG_IF_IMPL(severity, condition)                \
+#define ABSL_LOG_INTERNAL_PLOG_IF_IMPL(severity, condition)   \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()    \
           .WithPerror()
 
 #ifndef NDEBUG
-#define ABSL_DLOG_IF_IMPL(severity, condition)                \
+#define ABSL_LOG_INTERNAL_DLOG_IF_IMPL(severity, condition)   \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 #else
-#define ABSL_DLOG_IF_IMPL(severity, condition)                           \
+#define ABSL_LOG_INTERNAL_DLOG_IF_IMPL(severity, condition)              \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, false && (condition)) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 #endif
 
 // ABSL_LOG_EVERY_N
-#define ABSL_LOG_EVERY_N_IMPL(severity, n)                         \
+#define ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(severity, n)            \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
 // ABSL_LOG_FIRST_N
-#define ABSL_LOG_FIRST_N_IMPL(severity, n)                         \
+#define ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(severity, n)            \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(FirstN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
 // ABSL_LOG_EVERY_POW_2
-#define ABSL_LOG_EVERY_POW_2_IMPL(severity)                        \
+#define ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(severity)           \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryPow2) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
 // ABSL_LOG_EVERY_N_SEC
-#define ABSL_LOG_EVERY_N_SEC_IMPL(severity, n_seconds)                        \
+#define ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(severity, n_seconds)           \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryNSec, n_seconds) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_PLOG_EVERY_N_IMPL(severity, n)                        \
+#define ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(severity, n)           \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()         \
           .WithPerror()
 
-#define ABSL_PLOG_FIRST_N_IMPL(severity, n)                        \
+#define ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(severity, n)           \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(FirstN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()         \
           .WithPerror()
 
-#define ABSL_PLOG_EVERY_POW_2_IMPL(severity)                       \
+#define ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(severity)          \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryPow2) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()         \
           .WithPerror()
 
-#define ABSL_PLOG_EVERY_N_SEC_IMPL(severity, n_seconds)                       \
+#define ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(severity, n_seconds)          \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryNSec, n_seconds) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()                    \
           .WithPerror()
 
 #ifndef NDEBUG
-#define ABSL_DLOG_EVERY_N_IMPL(severity, n)        \
-  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \
+#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(severity, n) \
+  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)       \
   (EveryN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_FIRST_N_IMPL(severity, n)        \
-  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \
+#define ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(severity, n) \
+  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)       \
   (FirstN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_EVERY_POW_2_IMPL(severity)       \
-  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \
+#define ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(severity) \
+  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)        \
   (EveryPow2) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
-  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)      \
+#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
+  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)                   \
   (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
 #else  // def NDEBUG
-#define ABSL_DLOG_EVERY_N_IMPL(severity, n)         \
-  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \
+#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(severity, n) \
+  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)      \
   (EveryN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_FIRST_N_IMPL(severity, n)         \
-  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \
+#define ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(severity, n) \
+  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)      \
   (FirstN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_EVERY_POW_2_IMPL(severity)        \
-  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \
+#define ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(severity) \
+  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)       \
   (EveryPow2) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
-  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)     \
+#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
+  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)                  \
   (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 #endif  // def NDEBUG
 
-#define ABSL_LOG_IF_EVERY_N_IMPL(severity, condition, n)                \
+#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(severity, condition, n)   \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_LOG_IF_FIRST_N_IMPL(severity, condition, n)                \
+#define ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(severity, condition, n)   \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_LOG_IF_EVERY_POW_2_IMPL(severity, condition)               \
+#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(severity, condition)  \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_LOG_IF_EVERY_N_SEC_IMPL(severity, condition, n_seconds)    \
+#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(severity, condition,  \
+                                                  n_seconds)            \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
                                                              n_seconds) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_PLOG_IF_EVERY_N_IMPL(severity, condition, n)               \
+#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(severity, condition, n)  \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()              \
           .WithPerror()
 
-#define ABSL_PLOG_IF_FIRST_N_IMPL(severity, condition, n)               \
+#define ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(severity, condition, n)  \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()              \
           .WithPerror()
 
-#define ABSL_PLOG_IF_EVERY_POW_2_IMPL(severity, condition)              \
+#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(severity, condition) \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()              \
           .WithPerror()
 
-#define ABSL_PLOG_IF_EVERY_N_SEC_IMPL(severity, condition, n_seconds)   \
+#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \
+                                                   n_seconds)           \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
                                                              n_seconds) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()              \
           .WithPerror()
 
 #ifndef NDEBUG
-#define ABSL_DLOG_IF_EVERY_N_IMPL(severity, condition, n)               \
+#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(severity, condition, n)  \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_IF_FIRST_N_IMPL(severity, condition, n)               \
+#define ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(severity, condition, n)  \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition)              \
+#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition) \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, n_seconds)   \
+#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \
+                                                   n_seconds)           \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
                                                              n_seconds) \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
 #else  // def NDEBUG
-#define ABSL_DLOG_IF_EVERY_N_IMPL(severity, condition, n)                \
+#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(severity, condition, n)   \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
       EveryN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_IF_FIRST_N_IMPL(severity, condition, n)                \
+#define ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(severity, condition, n)   \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
       FirstN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition)               \
+#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition)  \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
       EveryPow2) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
 
-#define ABSL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, n_seconds)    \
+#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition,  \
+                                                   n_seconds)            \
   ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
       EveryNSec, n_seconds)                                              \
       ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
diff --git a/third_party/abseil-cpp/absl/log/log.h b/third_party/abseil-cpp/absl/log/log.h
index e060a0b..602b5ac 100644
--- a/third_party/abseil-cpp/absl/log/log.h
+++ b/third_party/abseil-cpp/absl/log/log.h
@@ -196,29 +196,32 @@
 // Example:
 //
 //   LOG(INFO) << "Found " << num_cookies << " cookies";
-#define LOG(severity) ABSL_LOG_IMPL(_##severity)
+#define LOG(severity) ABSL_LOG_INTERNAL_LOG_IMPL(_##severity)
 
 // PLOG()
 //
 // `PLOG` behaves like `LOG` except that a description of the current state of
 // `errno` is appended to the streamed message.
-#define PLOG(severity) ABSL_PLOG_IMPL(_##severity)
+#define PLOG(severity) ABSL_LOG_INTERNAL_PLOG_IMPL(_##severity)
 
 // DLOG()
 //
 // `DLOG` behaves like `LOG` in debug mode (i.e. `#ifndef NDEBUG`).  Otherwise
 // it compiles away and does nothing.  Note that `DLOG(FATAL)` does not
 // terminate the program if `NDEBUG` is defined.
-#define DLOG(severity) ABSL_DLOG_IMPL(_##severity)
+#define DLOG(severity) ABSL_LOG_INTERNAL_DLOG_IMPL(_##severity)
 
 // `LOG_IF` and friends add a second argument which specifies a condition.  If
 // the condition is false, nothing is logged.
 // Example:
 //
 //   LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
-#define LOG_IF(severity, condition) ABSL_LOG_IF_IMPL(_##severity, condition)
-#define PLOG_IF(severity, condition) ABSL_PLOG_IF_IMPL(_##severity, condition)
-#define DLOG_IF(severity, condition) ABSL_DLOG_IF_IMPL(_##severity, condition)
+#define LOG_IF(severity, condition) \
+  ABSL_LOG_INTERNAL_LOG_IF_IMPL(_##severity, condition)
+#define PLOG_IF(severity, condition) \
+  ABSL_LOG_INTERNAL_PLOG_IF_IMPL(_##severity, condition)
+#define DLOG_IF(severity, condition) \
+  ABSL_LOG_INTERNAL_DLOG_IF_IMPL(_##severity, condition)
 
 // LOG_EVERY_N
 //
@@ -231,21 +234,24 @@
 //
 //   LOG_EVERY_N(WARNING, 1000) << "Got a packet with a bad CRC (" << COUNTER
 //                              << " total)";
-#define LOG_EVERY_N(severity, n) ABSL_LOG_EVERY_N_IMPL(_##severity, n)
+#define LOG_EVERY_N(severity, n) \
+  ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(_##severity, n)
 
 // LOG_FIRST_N
 //
 // `LOG_FIRST_N` behaves like `LOG_EVERY_N` except that the specified message is
 // logged when the counter's value is less than `n`.  `LOG_FIRST_N` is
 // thread-safe.
-#define LOG_FIRST_N(severity, n) ABSL_LOG_FIRST_N_IMPL(_##severity, n)
+#define LOG_FIRST_N(severity, n) \
+  ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(_##severity, n)
 
 // LOG_EVERY_POW_2
 //
 // `LOG_EVERY_POW_2` behaves like `LOG_EVERY_N` except that the specified
 // message is logged when the counter's value is a power of 2.
 // `LOG_EVERY_POW_2` is thread-safe.
-#define LOG_EVERY_POW_2(severity) ABSL_LOG_EVERY_POW_2_IMPL(_##severity)
+#define LOG_EVERY_POW_2(severity) \
+  ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(_##severity)
 
 // LOG_EVERY_N_SEC
 //
@@ -257,19 +263,25 @@
 //
 //   LOG_EVERY_N_SEC(INFO, 2.5) << "Got " << COUNTER << " cookies so far";
 #define LOG_EVERY_N_SEC(severity, n_seconds) \
-  ABSL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
+  ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
 
-#define PLOG_EVERY_N(severity, n) ABSL_PLOG_EVERY_N_IMPL(_##severity, n)
-#define PLOG_FIRST_N(severity, n) ABSL_PLOG_FIRST_N_IMPL(_##severity, n)
-#define PLOG_EVERY_POW_2(severity) ABSL_PLOG_EVERY_POW_2_IMPL(_##severity)
+#define PLOG_EVERY_N(severity, n) \
+  ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(_##severity, n)
+#define PLOG_FIRST_N(severity, n) \
+  ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(_##severity, n)
+#define PLOG_EVERY_POW_2(severity) \
+  ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(_##severity)
 #define PLOG_EVERY_N_SEC(severity, n_seconds) \
-  ABSL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
+  ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
 
-#define DLOG_EVERY_N(severity, n) ABSL_DLOG_EVERY_N_IMPL(_##severity, n)
-#define DLOG_FIRST_N(severity, n) ABSL_DLOG_FIRST_N_IMPL(_##severity, n)
-#define DLOG_EVERY_POW_2(severity) ABSL_DLOG_EVERY_POW_2_IMPL(_##severity)
+#define DLOG_EVERY_N(severity, n) \
+  ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(_##severity, n)
+#define DLOG_FIRST_N(severity, n) \
+  ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(_##severity, n)
+#define DLOG_EVERY_POW_2(severity) \
+  ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(_##severity)
 #define DLOG_EVERY_N_SEC(severity, n_seconds) \
-  ABSL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
+  ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
 
 // `LOG_IF_EVERY_N` and friends behave as the corresponding `LOG_EVERY_N`
 // but neither increment a counter nor log a message if condition is false (as
@@ -279,30 +291,30 @@
 //   LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER
 //                                           << "th big cookie";
 #define LOG_IF_EVERY_N(severity, condition, n) \
-  ABSL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n)
 #define LOG_IF_FIRST_N(severity, condition, n) \
-  ABSL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n)
 #define LOG_IF_EVERY_POW_2(severity, condition) \
-  ABSL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
 #define LOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
-  ABSL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
+  ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
 
 #define PLOG_IF_EVERY_N(severity, condition, n) \
-  ABSL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
 #define PLOG_IF_FIRST_N(severity, condition, n) \
-  ABSL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
 #define PLOG_IF_EVERY_POW_2(severity, condition) \
-  ABSL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
 #define PLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
-  ABSL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
+  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
 
 #define DLOG_IF_EVERY_N(severity, condition, n) \
-  ABSL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
 #define DLOG_IF_FIRST_N(severity, condition, n) \
-  ABSL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
+  ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
 #define DLOG_IF_EVERY_POW_2(severity, condition) \
-  ABSL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
+  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
 #define DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
-  ABSL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
+  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
 
 #endif  // ABSL_LOG_LOG_H_
diff --git a/third_party/abseil-cpp/absl/log/log_basic_test.cc b/third_party/abseil-cpp/absl/log/log_basic_test.cc
index b8d87c94..7fc7111d 100644
--- a/third_party/abseil-cpp/absl/log/log_basic_test.cc
+++ b/third_party/abseil-cpp/absl/log/log_basic_test.cc
@@ -18,4 +18,4 @@
 #define ABSL_TEST_LOG LOG
 
 #include "gtest/gtest.h"
-#include "absl/log/log_basic_test_impl.h"
+#include "absl/log/log_basic_test_impl.inc"
diff --git a/third_party/abseil-cpp/absl/log/log_basic_test_impl.h b/third_party/abseil-cpp/absl/log/log_basic_test_impl.inc
similarity index 97%
rename from third_party/abseil-cpp/absl/log/log_basic_test_impl.h
rename to third_party/abseil-cpp/absl/log/log_basic_test_impl.inc
index 35c0b690..f3400095 100644
--- a/third_party/abseil-cpp/absl/log/log_basic_test_impl.h
+++ b/third_party/abseil-cpp/absl/log/log_basic_test_impl.inc
@@ -94,7 +94,7 @@
     EXPECT_CALL(
         test_sink,
         Send(AllOf(SourceFilename(Eq(__FILE__)),
-                   SourceBasename(Eq("log_basic_test_impl.h")),
+                   SourceBasename(Eq("log_basic_test_impl.inc")),
                    SourceLine(Eq(log_line)), Prefix(IsTrue()),
                    LogSeverity(Eq(absl::LogSeverity::kInfo)),
                    TimestampInMatchWindow(),
@@ -123,7 +123,7 @@
     EXPECT_CALL(
         test_sink,
         Send(AllOf(SourceFilename(Eq(__FILE__)),
-                   SourceBasename(Eq("log_basic_test_impl.h")),
+                   SourceBasename(Eq("log_basic_test_impl.inc")),
                    SourceLine(Eq(log_line)), Prefix(IsTrue()),
                    LogSeverity(Eq(absl::LogSeverity::kWarning)),
                    TimestampInMatchWindow(),
@@ -152,7 +152,7 @@
     EXPECT_CALL(
         test_sink,
         Send(AllOf(SourceFilename(Eq(__FILE__)),
-                   SourceBasename(Eq("log_basic_test_impl.h")),
+                   SourceBasename(Eq("log_basic_test_impl.inc")),
                    SourceLine(Eq(log_line)), Prefix(IsTrue()),
                    LogSeverity(Eq(absl::LogSeverity::kError)),
                    TimestampInMatchWindow(),
@@ -203,7 +203,7 @@
           EXPECT_CALL(
               test_sink,
               Send(AllOf(SourceFilename(Eq(__FILE__)),
-                         SourceBasename(Eq("log_basic_test_impl.h")),
+                         SourceBasename(Eq("log_basic_test_impl.inc")),
                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
                          TimestampInMatchWindow(),
@@ -219,7 +219,7 @@
           EXPECT_CALL(
               test_sink,
               Send(AllOf(SourceFilename(Eq(__FILE__)),
-                         SourceBasename(Eq("log_basic_test_impl.h")),
+                         SourceBasename(Eq("log_basic_test_impl.inc")),
                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
                          TimestampInMatchWindow(),
@@ -257,7 +257,7 @@
           EXPECT_CALL(
               test_sink,
               Send(AllOf(SourceFilename(Eq(__FILE__)),
-                         SourceBasename(Eq("log_basic_test_impl.h")),
+                         SourceBasename(Eq("log_basic_test_impl.inc")),
                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
                          TimestampInMatchWindow(),
@@ -293,7 +293,7 @@
       EXPECT_CALL(
           test_sink,
           Send(AllOf(SourceFilename(Eq(__FILE__)),
-                     SourceBasename(Eq("log_basic_test_impl.h")),
+                     SourceBasename(Eq("log_basic_test_impl.inc")),
                      SourceLine(Eq(log_line)), Prefix(IsTrue()),
                      LogSeverity(Eq(severity)), TimestampInMatchWindow(),
                      ThreadID(Eq(absl::base_internal::GetTID())),
@@ -336,7 +336,7 @@
           EXPECT_CALL(
               test_sink,
               Send(AllOf(SourceFilename(Eq(__FILE__)),
-                         SourceBasename(Eq("log_basic_test_impl.h")),
+                         SourceBasename(Eq("log_basic_test_impl.inc")),
                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
                          TimestampInMatchWindow(),
@@ -351,7 +351,7 @@
           EXPECT_CALL(
               test_sink,
               Send(AllOf(SourceFilename(Eq(__FILE__)),
-                         SourceBasename(Eq("log_basic_test_impl.h")),
+                         SourceBasename(Eq("log_basic_test_impl.inc")),
                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
                          TimestampInMatchWindow(),
diff --git a/third_party/abseil-cpp/absl/log/log_sink_test.cc b/third_party/abseil-cpp/absl/log/log_sink_test.cc
index 8903da7..fa74306 100644
--- a/third_party/abseil-cpp/absl/log/log_sink_test.cc
+++ b/third_party/abseil-cpp/absl/log/log_sink_test.cc
@@ -18,7 +18,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "absl/base/attributes.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/log/internal/test_actions.h"
 #include "absl/log/internal/test_helpers.h"
 #include "absl/log/internal/test_matchers.h"
@@ -205,7 +204,7 @@
               << "The log is coming from *inside the sink*.";
           break;
         default:
-          ABSL_RAW_LOG(FATAL, "Invalid mode %d.\n", static_cast<int>(mode_));
+          LOG(FATAL) << "Invalid mode " << static_cast<int>(mode_);
       }
     }
 
diff --git a/third_party/abseil-cpp/absl/random/BUILD.bazel b/third_party/abseil-cpp/absl/random/BUILD.bazel
index 133c065..19130ff 100644
--- a/third_party/abseil-cpp/absl/random/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/random/BUILD.bazel
@@ -189,7 +189,7 @@
     deps = [
         ":distributions",
         ":random",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/numeric:representation",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:pcg_engine",
@@ -244,7 +244,7 @@
     deps = [
         ":distributions",
         ":random",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:pcg_engine",
         "//absl/random/internal:sequence_urbg",
@@ -265,7 +265,7 @@
     deps = [
         ":distributions",
         ":random",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:pcg_engine",
         "//absl/random/internal:sequence_urbg",
@@ -292,8 +292,8 @@
         ":distributions",
         ":random",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
         "//absl/container:flat_hash_map",
+        "//absl/log",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:pcg_engine",
         "//absl/random/internal:sequence_urbg",
@@ -314,7 +314,7 @@
         ":distributions",
         ":random",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/numeric:representation",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:pcg_engine",
@@ -338,7 +338,7 @@
         ":distributions",
         ":random",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/numeric:representation",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:sequence_urbg",
@@ -360,7 +360,7 @@
     deps = [
         ":distributions",
         ":random",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:pcg_engine",
         "//absl/random/internal:sequence_urbg",
@@ -385,7 +385,7 @@
     deps = [
         ":distributions",
         ":random",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/numeric:representation",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:pcg_engine",
@@ -406,7 +406,7 @@
     deps = [
         ":distributions",
         ":random",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/random/internal:distribution_test_util",
         "//absl/random/internal:pcg_engine",
         "//absl/random/internal:sequence_urbg",
diff --git a/third_party/abseil-cpp/absl/random/CMakeLists.txt b/third_party/abseil-cpp/absl/random/CMakeLists.txt
index c74fd30..bd363d88 100644
--- a/third_party/abseil-cpp/absl/random/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/random/CMakeLists.txt
@@ -260,13 +260,13 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
+    absl::log
     absl::numeric_representation
     absl::random_distributions
     absl::random_random
     absl::random_internal_distribution_test_util
     absl::random_internal_sequence_urbg
     absl::random_internal_pcg_engine
-    absl::raw_logging_internal
     absl::strings
     absl::str_format
     GTest::gmock
@@ -299,6 +299,7 @@
     ${ABSL_TEST_COPTS}
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
+  DEPS
     absl::random_distributions
     absl::random_random
     absl::raw_logging_internal
@@ -315,12 +316,13 @@
     ${ABSL_TEST_COPTS}
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
+  DEPS
+    absl::log
     absl::random_distributions
     absl::random_internal_distribution_test_util
     absl::random_internal_pcg_engine
     absl::random_internal_sequence_urbg
     absl::random_random
-    absl::raw_logging_internal
     absl::strings
     absl::str_format
     GTest::gmock
@@ -337,12 +339,12 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
+    absl::log
     absl::random_distributions
     absl::random_internal_distribution_test_util
     absl::random_internal_pcg_engine
     absl::random_internal_sequence_urbg
     absl::random_random
-    absl::raw_logging_internal
     absl::strings
     GTest::gmock
     GTest::gtest_main
@@ -362,10 +364,10 @@
     absl::random_random
     absl::core_headers
     absl::flat_hash_map
+    absl::log
     absl::random_internal_distribution_test_util
     absl::random_internal_pcg_engine
     absl::random_internal_sequence_urbg
-    absl::raw_logging_internal
     absl::strings
     absl::str_format
     GTest::gmock
@@ -383,13 +385,13 @@
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
     absl::core_headers
+    absl::log
     absl::numeric_representation
     absl::random_distributions
     absl::random_internal_distribution_test_util
     absl::random_internal_pcg_engine
     absl::random_internal_sequence_urbg
     absl::random_random
-    absl::raw_logging_internal
     absl::strings
     absl::str_format
     GTest::gmock
@@ -407,12 +409,12 @@
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
     absl::core_headers
+    absl::log
     absl::numeric_representation
     absl::random_distributions
     absl::random_internal_distribution_test_util
     absl::random_internal_sequence_urbg
     absl::random_random
-    absl::raw_logging_internal
     absl::strings
     absl::str_format
     GTest::gmock
@@ -429,12 +431,12 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
+    absl::log
     absl::random_distributions
     absl::random_internal_distribution_test_util
     absl::random_internal_pcg_engine
     absl::random_internal_sequence_urbg
     absl::random_random
-    absl::raw_logging_internal
     absl::strings
     GTest::gmock
     GTest::gtest_main
@@ -450,6 +452,7 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
+    absl::log
     absl::numeric_representation
     absl::random_distributions
     absl::random_internal_distribution_test_util
@@ -471,12 +474,12 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
+    absl::log
     absl::random_distributions
     absl::random_internal_distribution_test_util
     absl::random_internal_pcg_engine
     absl::random_internal_sequence_urbg
     absl::random_random
-    absl::raw_logging_internal
     absl::strings
     GTest::gmock
     GTest::gtest_main
@@ -1090,9 +1093,9 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
+    absl::log
     absl::random_internal_explicit_seed_seq
     absl::random_internal_randen_engine
-    absl::raw_logging_internal
     absl::strings
     absl::time
     GTest::gmock
@@ -1142,10 +1145,10 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
+    absl::log
     absl::random_internal_platform
     absl::random_internal_randen_hwaes
     absl::random_internal_randen_hwaes_impl
-    absl::raw_logging_internal
     absl::str_format
     GTest::gmock
     GTest::gtest
diff --git a/third_party/abseil-cpp/absl/random/beta_distribution_test.cc b/third_party/abseil-cpp/absl/random/beta_distribution_test.cc
index c16fbb4..c93b2a33 100644
--- a/third_party/abseil-cpp/absl/random/beta_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/beta_distribution_test.cc
@@ -28,7 +28,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/numeric/internal/representation.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/distribution_test_util.h"
@@ -107,8 +107,8 @@
   };
   for (TypeParam alpha : kValues) {
     for (TypeParam beta : kValues) {
-      ABSL_INTERNAL_LOG(
-          INFO, absl::StrFormat("Smoke test for Beta(%a, %a)", alpha, beta));
+      LOG(INFO) << absl::StreamFormat("Smoke test for Beta(%a, %a)", alpha,
+                                      beta);
 
       param_type param(alpha, beta);
       absl::beta_distribution<TypeParam> before(alpha, beta);
@@ -327,15 +327,13 @@
       absl::random_internal::Near("z", z_mean, 0.0, max_err) &&
       absl::random_internal::Near("z_variance", z_variance, 0.0, max_err);
   if (!pass) {
-    ABSL_INTERNAL_LOG(
-        INFO,
-        absl::StrFormat(
-            "Beta(%f, %f), "
-            "mean: sample %f, expect %f, which is %f stddevs away, "
-            "variance: sample %f, expect %f, which is %f stddevs away.",
-            alpha_, beta_, m.mean, Mean(),
-            std::abs(m.mean - Mean()) / mean_stddev, m.variance, Variance(),
-            std::abs(m.variance - Variance()) / variance_stddev));
+    LOG(INFO) << "Beta(" << alpha_ << ", " << beta_ << "), mean: sample "
+              << m.mean << ", expect " << Mean() << ", which is "
+              << std::abs(m.mean - Mean()) / mean_stddev
+              << " stddevs away, variance: sample " << m.variance << ", expect "
+              << Variance() << ", which is "
+              << std::abs(m.variance - Variance()) / variance_stddev
+              << " stddevs away.";
   }
   return pass;
 }
@@ -396,18 +394,15 @@
   const bool pass =
       (absl::random_internal::ChiSquarePValue(chi_square, dof) >= p);
   if (!pass) {
-    for (int i = 0; i < cutoffs.size(); i++) {
-      ABSL_INTERNAL_LOG(
-          INFO, absl::StrFormat("cutoff[%d] = %f, actual count %d, expected %d",
-                                i, cutoffs[i], counts[i],
-                                static_cast<int>(expected[i])));
+    for (size_t i = 0; i < cutoffs.size(); i++) {
+      LOG(INFO) << "cutoff[" << i << "] = " << cutoffs[i] << ", actual count "
+                << counts[i] << ", expected " << static_cast<int>(expected[i]);
     }
 
-    ABSL_INTERNAL_LOG(
-        INFO, absl::StrFormat(
-                  "Beta(%f, %f) %s %f, p = %f", alpha_, beta_,
-                  absl::random_internal::kChiSquared, chi_square,
-                  absl::random_internal::ChiSquarePValue(chi_square, dof)));
+    LOG(INFO) << "Beta(" << alpha_ << ", " << beta_ << ") "
+              << absl::random_internal::kChiSquared << " " << chi_square
+              << ", p = "
+              << absl::random_internal::ChiSquarePValue(chi_square, dof);
   }
   return pass;
 }
diff --git a/third_party/abseil-cpp/absl/random/discrete_distribution_test.cc b/third_party/abseil-cpp/absl/random/discrete_distribution_test.cc
index e528a6a..32405ea 100644
--- a/third_party/abseil-cpp/absl/random/discrete_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/discrete_distribution_test.cc
@@ -26,7 +26,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/distribution_test_util.h"
 #include "absl/random/internal/pcg_engine.h"
@@ -194,7 +194,7 @@
     absl::StrAppend(&msg, kChiSquared, " p-value ", p_value, "\n");
     absl::StrAppend(&msg, "High ", kChiSquared, " value: ", chi_square, " > ",
                     kThreshold);
-    ABSL_RAW_LOG(INFO, "%s", msg.c_str());
+    LOG(INFO) << msg;
     FAIL() << msg;
   }
 }
diff --git a/third_party/abseil-cpp/absl/random/exponential_distribution_test.cc b/third_party/abseil-cpp/absl/random/exponential_distribution_test.cc
index 3c44d9e..fb9a0d1 100644
--- a/third_party/abseil-cpp/absl/random/exponential_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/exponential_distribution_test.cc
@@ -29,8 +29,8 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
+#include "absl/log/log.h"
 #include "absl/numeric/internal/representation.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/distribution_test_util.h"
@@ -115,9 +115,8 @@
       if (sample < sample_min) sample_min = sample;
     }
     if (!std::is_same<TypeParam, long double>::value) {
-      ABSL_INTERNAL_LOG(INFO,
-                        absl::StrFormat("Range {%f}: %f, %f, lambda=%f", lambda,
-                                        sample_min, sample_max, lambda));
+      LOG(INFO) << "Range {" << lambda << "}: " << sample_min << ", "
+                << sample_max << ", lambda=" << lambda;
     }
 
     std::stringstream ss;
@@ -219,17 +218,16 @@
   const bool pass = absl::random_internal::Near("z", z, 0.0, max_err);
 
   if (!pass) {
-    ABSL_INTERNAL_LOG(
-        INFO, absl::StrFormat("p=%f max_err=%f\n"
-                              " lambda=%f\n"
-                              " mean=%f vs. %f\n"
-                              " stddev=%f vs. %f\n"
-                              " skewness=%f vs. %f\n"
-                              " kurtosis=%f vs. %f\n"
-                              " z=%f vs. 0",
-                              p, max_err, lambda(), m.mean, mean(),
-                              std::sqrt(m.variance), stddev(), m.skewness,
-                              skew(), m.kurtosis, kurtosis(), z));
+    // clang-format off
+    LOG(INFO)
+        << "p=" << p << " max_err=" << max_err << "\n"
+           " lambda=" << lambda() << "\n"
+           " mean=" << m.mean << " vs. " << mean() << "\n"
+           " stddev=" << std::sqrt(m.variance) << " vs. " << stddev() << "\n"
+           " skewness=" << m.skewness << " vs. " << skew() << "\n"
+           " kurtosis=" << m.kurtosis << " vs. " << kurtosis() << "\n"
+           " z=" << z << " vs. 0";
+    // clang-format on
   }
   return pass;
 }
@@ -274,16 +272,16 @@
   double p = absl::random_internal::ChiSquarePValue(chi_square, dof);
 
   if (chi_square > threshold) {
-    for (int i = 0; i < cutoffs.size(); i++) {
-      ABSL_INTERNAL_LOG(
-          INFO, absl::StrFormat("%d : (%f) = %d", i, cutoffs[i], counts[i]));
+    for (size_t i = 0; i < cutoffs.size(); i++) {
+      LOG(INFO) << i << " : (" << cutoffs[i] << ") = " << counts[i];
     }
 
-    ABSL_INTERNAL_LOG(INFO,
-                      absl::StrCat("lambda ", lambda(), "\n",     //
-                                   " expected ", expected, "\n",  //
-                                   kChiSquared, " ", chi_square, " (", p, ")\n",
-                                   kChiSquared, " @ 0.98 = ", threshold));
+    // clang-format off
+    LOG(INFO) << "lambda " << lambda() << "\n"
+                 " expected " << expected << "\n"
+              << kChiSquared << " " << chi_square << " (" << p << ")\n"
+              << kChiSquared << " @ 0.98 = " << threshold;
+    // clang-format on
   }
   return p;
 }
diff --git a/third_party/abseil-cpp/absl/random/gaussian_distribution_test.cc b/third_party/abseil-cpp/absl/random/gaussian_distribution_test.cc
index 4584ac9..bad3476 100644
--- a/third_party/abseil-cpp/absl/random/gaussian_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/gaussian_distribution_test.cc
@@ -26,8 +26,8 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
+#include "absl/log/log.h"
 #include "absl/numeric/internal/representation.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/distribution_test_util.h"
@@ -116,9 +116,8 @@
           EXPECT_LE(sample, before.max()) << before;
         }
         if (!std::is_same<TypeParam, long double>::value) {
-          ABSL_INTERNAL_LOG(
-              INFO, absl::StrFormat("Range{%f, %f}: %f, %f", mean, stddev,
-                                    sample_min, sample_max));
+          LOG(INFO) << "Range{" << mean << ", " << stddev << "}: " << sample_min
+                    << ", " << sample_max;
         }
 
         std::stringstream ss;
@@ -240,17 +239,16 @@
       (std::pow(m.skewness, 2.0) + std::pow(m.kurtosis - 3.0, 2.0) / 4.0);
 
   if (!pass || jb > 9.21) {
-    ABSL_INTERNAL_LOG(
-        INFO, absl::StrFormat("p=%f max_err=%f\n"
-                              " mean=%f vs. %f\n"
-                              " stddev=%f vs. %f\n"
-                              " skewness=%f vs. %f\n"
-                              " kurtosis=%f vs. %f\n"
-                              " z=%f vs. 0\n"
-                              " jb=%f vs. 9.21",
-                              p, max_err, m.mean, mean(), std::sqrt(m.variance),
-                              stddev(), m.skewness, skew(), m.kurtosis,
-                              kurtosis(), z, jb));
+    // clang-format off
+    LOG(INFO)
+        << "p=" << p << " max_err=" << max_err << "\n"
+           " mean=" << m.mean << " vs. " << mean() << "\n"
+           " stddev=" << std::sqrt(m.variance) << " vs. " << stddev() << "\n"
+           " skewness=" << m.skewness << " vs. " << skew() << "\n"
+           " kurtosis=" << m.kurtosis << " vs. " << kurtosis() << "\n"
+           " z=" << z << " vs. 0\n"
+           " jb=" << jb << " vs. 9.21";
+    // clang-format on
   }
   return pass;
 }
@@ -297,16 +295,16 @@
 
   // Log if the chi_square value is above the threshold.
   if (chi_square > threshold) {
-    for (int i = 0; i < cutoffs.size(); i++) {
-      ABSL_INTERNAL_LOG(
-          INFO, absl::StrFormat("%d : (%f) = %d", i, cutoffs[i], counts[i]));
+    for (size_t i = 0; i < cutoffs.size(); i++) {
+      LOG(INFO) << i << " : (" << cutoffs[i] << ") = " << counts[i];
     }
 
-    ABSL_INTERNAL_LOG(
-        INFO, absl::StrCat("mean=", mean(), " stddev=", stddev(), "\n",   //
-                           " expected ", expected, "\n",                  //
-                           kChiSquared, " ", chi_square, " (", p, ")\n",  //
-                           kChiSquared, " @ 0.98 = ", threshold));
+    // clang-format off
+    LOG(INFO) << "mean=" << mean() << " stddev=" << stddev() << "\n"
+                 " expected " << expected << "\n"
+              << kChiSquared << " " << chi_square << " (" << p << ")\n"
+              << kChiSquared << " @ 0.98 = " << threshold;
+    // clang-format on
   }
   return p;
 }
diff --git a/third_party/abseil-cpp/absl/random/internal/BUILD.bazel b/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
index a51c9375..37f4d6e2 100644
--- a/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
@@ -601,7 +601,7 @@
     deps = [
         ":explicit_seed_seq",
         ":randen_engine",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/strings",
         "//absl/time",
         "@com_google_googletest//:gtest_main",
@@ -646,7 +646,7 @@
         ":platform",
         ":randen_hwaes",
         ":randen_hwaes_impl",  # build_cleaner: keep
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/strings:str_format",
         "@com_google_googletest//:gtest",
     ],
@@ -707,8 +707,10 @@
     ],
     deps = [
         ":nanobenchmark",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
+        "//absl/log:check",
         "//absl/strings",
+        "//absl/strings:str_format",
     ],
 )
 
diff --git a/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc b/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
index f1571e2..d4f1028 100644
--- a/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
@@ -14,8 +14,10 @@
 
 #include "absl/random/internal/nanobenchmark.h"
 
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/numbers.h"
+#include "absl/strings/str_format.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -36,16 +38,16 @@
   params.max_evals = 6;  // avoid test timeout
   const size_t num_results = Measure(&Div, nullptr, inputs, N, results, params);
   if (num_results == 0) {
-    ABSL_RAW_LOG(
-        WARNING,
-        "WARNING: Measurement failed, should not happen when using "
-        "PinThreadToCPU unless the region to measure takes > 1 second.\n");
+    LOG(WARNING)
+        << "WARNING: Measurement failed, should not happen when using "
+           "PinThreadToCPU unless the region to measure takes > 1 second.";
     return;
   }
   for (size_t i = 0; i < num_results; ++i) {
-    ABSL_RAW_LOG(INFO, "%5zu: %6.2f ticks; MAD=%4.2f%%\n", results[i].input,
-                 results[i].ticks, results[i].variability * 100.0);
-    ABSL_RAW_CHECK(results[i].ticks != 0.0f, "Zero duration");
+    LOG(INFO) << absl::StreamFormat("%5u: %6.2f ticks; MAD=%4.2f%%\n",
+                                    results[i].input, results[i].ticks,
+                                    results[i].variability * 100.0);
+    CHECK_NE(results[i].ticks, 0.0f) << "Zero duration";
   }
 }
 
@@ -54,7 +56,7 @@
   int cpu = -1;
   if (argc == 2) {
     if (!absl::SimpleAtoi(argv[1], &cpu)) {
-      ABSL_RAW_LOG(FATAL, "The optional argument must be a CPU number >= 0.\n");
+      LOG(FATAL) << "The optional argument must be a CPU number >= 0.";
     }
   }
   PinThreadToCPU(cpu);
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_detect.cc b/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
index 6dababa..bdeab877 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
@@ -45,6 +45,10 @@
 #if defined(ABSL_INTERNAL_USE_X86_CPUID)
 #if defined(_WIN32) || defined(_WIN64)
 #include <intrin.h>  // NOLINT(build/include_order)
+#elif ABSL_HAVE_BUILTIN(__cpuid)
+// MSVC-equivalent __cpuid intrinsic declaration for clang-like compilers
+// for non-Windows build environments.
+extern void __cpuid(int[4], int);
 #else
 // MSVC-equivalent __cpuid intrinsic function.
 static void __cpuid(int cpu_info[4], int info_type) {
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_engine_test.cc b/third_party/abseil-cpp/absl/random/internal/randen_engine_test.cc
index c8e7685b..a94f491 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_engine_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_engine_test.cc
@@ -21,7 +21,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/random/internal/explicit_seed_seq.h"
 #include "absl/strings/str_cat.h"
 #include "absl/time/clock.h"
@@ -645,9 +645,8 @@
   }
   auto duration = absl::GetCurrentTimeNanos() - start;
 
-  ABSL_INTERNAL_LOG(INFO, absl::StrCat(static_cast<double>(duration) /
-                                           static_cast<double>(kCount),
-                                       "ns"));
+  LOG(INFO) << static_cast<double>(duration) / static_cast<double>(kCount)
+            << "ns";
 
   EXPECT_GT(sum, 0);
   EXPECT_GE(duration, kCount);  // Should be slower than 1ns per call.
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc b/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
index 2348b55..00d96ef 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
@@ -16,7 +16,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/random/internal/platform.h"
 #include "absl/random/internal/randen_detect.h"
 #include "absl/random/internal/randen_traits.h"
@@ -67,32 +67,32 @@
 int main(int argc, char* argv[]) {
   testing::InitGoogleTest(&argc, argv);
 
-  ABSL_RAW_LOG(INFO, "ABSL_HAVE_ACCELERATED_AES=%d", ABSL_HAVE_ACCELERATED_AES);
-  ABSL_RAW_LOG(INFO, "ABSL_RANDOM_INTERNAL_AES_DISPATCH=%d",
-               ABSL_RANDOM_INTERNAL_AES_DISPATCH);
+  LOG(INFO) << "ABSL_HAVE_ACCELERATED_AES=" << ABSL_HAVE_ACCELERATED_AES;
+  LOG(INFO) << "ABSL_RANDOM_INTERNAL_AES_DISPATCH="
+            << ABSL_RANDOM_INTERNAL_AES_DISPATCH;
 
 #if defined(ABSL_ARCH_X86_64)
-  ABSL_RAW_LOG(INFO, "ABSL_ARCH_X86_64");
+  LOG(INFO) << "ABSL_ARCH_X86_64";
 #elif defined(ABSL_ARCH_X86_32)
-  ABSL_RAW_LOG(INFO, "ABSL_ARCH_X86_32");
+  LOG(INFO) << "ABSL_ARCH_X86_32";
 #elif defined(ABSL_ARCH_AARCH64)
-  ABSL_RAW_LOG(INFO, "ABSL_ARCH_AARCH64");
+  LOG(INFO) << "ABSL_ARCH_AARCH64";
 #elif defined(ABSL_ARCH_ARM)
-  ABSL_RAW_LOG(INFO, "ABSL_ARCH_ARM");
+  LOG(INFO) << "ABSL_ARCH_ARM";
 #elif defined(ABSL_ARCH_PPC)
-  ABSL_RAW_LOG(INFO, "ABSL_ARCH_PPC");
+  LOG(INFO) << "ABSL_ARCH_PPC";
 #else
-  ABSL_RAW_LOG(INFO, "ARCH Unknown");
+  LOG(INFO) << "ARCH Unknown";
 #endif
 
   int x = absl::random_internal::HasRandenHwAesImplementation();
-  ABSL_RAW_LOG(INFO, "HasRandenHwAesImplementation = %d", x);
+  LOG(INFO) << "HasRandenHwAesImplementation = " << x;
 
   int y = absl::random_internal::CPUSupportsRandenHwAes();
-  ABSL_RAW_LOG(INFO, "CPUSupportsRandenHwAes = %d", x);
+  LOG(INFO) << "CPUSupportsRandenHwAes = " << x;
 
   if (!x || !y) {
-    ABSL_RAW_LOG(INFO, "Skipping Randen HWAES tests.");
+    LOG(INFO) << "Skipping Randen HWAES tests.";
     return 0;
   }
   return RUN_ALL_TESTS();
diff --git a/third_party/abseil-cpp/absl/random/log_uniform_int_distribution_test.cc b/third_party/abseil-cpp/absl/random/log_uniform_int_distribution_test.cc
index 0d0fcb9..5df3eda 100644
--- a/third_party/abseil-cpp/absl/random/log_uniform_int_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/log_uniform_int_distribution_test.cc
@@ -24,7 +24,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/distribution_test_util.h"
 #include "absl/random/internal/pcg_engine.h"
@@ -108,8 +108,7 @@
       if (sample > sample_max) sample_max = sample;
       if (sample < sample_min) sample_min = sample;
     }
-    ABSL_INTERNAL_LOG(INFO,
-                      absl::StrCat("Range: ", +sample_min, ", ", +sample_max));
+    LOG(INFO) << "Range: " << sample_min << ", " << sample_max;
   }
 }
 
@@ -182,16 +181,14 @@
   const double p = absl::random_internal::ChiSquarePValue(chi_square, dof);
 
   if (chi_square > threshold) {
-    ABSL_INTERNAL_LOG(INFO, "values");
+    LOG(INFO) << "values";
     for (size_t i = 0; i < buckets.size(); i++) {
-      ABSL_INTERNAL_LOG(INFO, absl::StrCat(i, ": ", buckets[i]));
+      LOG(INFO) << i << ": " << buckets[i];
     }
-    ABSL_INTERNAL_LOG(INFO,
-                      absl::StrFormat("trials=%d\n"
-                                      "%s(data, %d) = %f (%f)\n"
-                                      "%s @ 0.98 = %f",
-                                      trials, kChiSquared, dof, chi_square, p,
-                                      kChiSquared, threshold));
+    LOG(INFO) << "trials=" << trials << "\n"
+              << kChiSquared << "(data, " << dof << ") = " << chi_square << " ("
+              << p << ")\n"
+              << kChiSquared << " @ 0.98 = " << threshold;
   }
   return p;
 }
diff --git a/third_party/abseil-cpp/absl/random/poisson_distribution_test.cc b/third_party/abseil-cpp/absl/random/poisson_distribution_test.cc
index 4f585b9..5475596 100644
--- a/third_party/abseil-cpp/absl/random/poisson_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/poisson_distribution_test.cc
@@ -25,9 +25,9 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
 #include "absl/container/flat_hash_map.h"
+#include "absl/log/log.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/distribution_test_util.h"
 #include "absl/random/internal/pcg_engine.h"
@@ -134,8 +134,8 @@
       if (sample < sample_min) sample_min = sample;
     }
 
-    ABSL_INTERNAL_LOG(INFO, absl::StrCat("Range {", param.mean(), "}: ",
-                                         +sample_min, ", ", +sample_max));
+    LOG(INFO) << "Range {" << param.mean() << "}: " << sample_min << ", "
+              << sample_max;
 
     // Validate stream serialization.
     std::stringstream ss;
@@ -188,10 +188,9 @@
   }
 
   void LogCDF() {
-    ABSL_INTERNAL_LOG(INFO, absl::StrCat("CDF (mean = ", mean_, ")"));
+    LOG(INFO) << "CDF (mean = " << mean_ << ")";
     for (const auto c : cdf_) {
-      ABSL_INTERNAL_LOG(INFO,
-                        absl::StrCat(c.index, ": pmf=", c.pmf, " cdf=", c.cdf));
+      LOG(INFO) << c.index << ": pmf=" << c.pmf << " cdf=" << c.cdf;
     }
   }
 
@@ -286,16 +285,15 @@
   const bool pass = absl::random_internal::Near("z", z, 0.0, max_err);
 
   if (!pass) {
-    ABSL_INTERNAL_LOG(
-        INFO, absl::StrFormat("p=%f max_err=%f\n"
-                              " mean=%f vs. %f\n"
-                              " stddev=%f vs. %f\n"
-                              " skewness=%f vs. %f\n"
-                              " kurtosis=%f vs. %f\n"
-                              " z=%f",
-                              p, max_err, m.mean, mean(), std::sqrt(m.variance),
-                              stddev(), m.skewness, skew(), m.kurtosis,
-                              kurtosis(), z));
+    // clang-format off
+    LOG(INFO)
+        << "p=" << p << " max_err=" << max_err << "\n"
+           " mean=" << m.mean << " vs. " << mean() << "\n"
+           " stddev=" << std::sqrt(m.variance) << " vs. " << stddev() << "\n"
+           " skewness=" << m.skewness << " vs. " << skew() << "\n"
+           " kurtosis=" << m.kurtosis << " vs. " << kurtosis() << "\n"
+           " z=" << z;
+    // clang-format on
   }
   return pass;
 }
@@ -439,17 +437,16 @@
   if (chi_square > threshold) {
     LogCDF();
 
-    ABSL_INTERNAL_LOG(INFO, absl::StrCat("VALUES  buckets=", counts.size(),
-                                         "  samples=", kSamples));
+    LOG(INFO) << "VALUES  buckets=" << counts.size()
+              << "  samples=" << kSamples;
     for (size_t i = 0; i < counts.size(); i++) {
-      ABSL_INTERNAL_LOG(
-          INFO, absl::StrCat(cutoffs_[i], ": ", counts[i], " vs. E=", e[i]));
+      LOG(INFO) << cutoffs_[i] << ": " << counts[i] << " vs. E=" << e[i];
     }
 
-    ABSL_INTERNAL_LOG(
-        INFO,
-        absl::StrCat(kChiSquared, "(data, dof=", dof, ") = ", chi_square, " (",
-                     p, ")\n", " vs.\n", kChiSquared, " @ 0.98 = ", threshold));
+    LOG(INFO) << kChiSquared << "(data, dof=" << dof << ") = " << chi_square
+              << " (" << p << ")\n"
+              << " vs.\n"
+              << kChiSquared << " @ 0.98 = " << threshold;
   }
   return p;
 }
diff --git a/third_party/abseil-cpp/absl/random/uniform_int_distribution_test.cc b/third_party/abseil-cpp/absl/random/uniform_int_distribution_test.cc
index a830117a..b40d6185 100644
--- a/third_party/abseil-cpp/absl/random/uniform_int_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/uniform_int_distribution_test.cc
@@ -24,7 +24,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/distribution_test_util.h"
 #include "absl/random/internal/pcg_engine.h"
@@ -107,8 +107,7 @@
         sample_min = sample;
       }
     }
-    std::string msg = absl::StrCat("Range: ", +sample_min, ", ", +sample_max);
-    ABSL_RAW_LOG(INFO, "%s", msg.c_str());
+    LOG(INFO) << "Range: " << sample_min << ", " << sample_max;
   }
 }
 
@@ -210,7 +209,7 @@
     absl::StrAppend(&msg, kChiSquared, " p-value ", p_value, "\n");
     absl::StrAppend(&msg, "High ", kChiSquared, " value: ", chi_square, " > ",
                     kThreshold);
-    ABSL_RAW_LOG(INFO, "%s", msg.c_str());
+    LOG(INFO) << msg;
     FAIL() << msg;
   }
 }
diff --git a/third_party/abseil-cpp/absl/random/uniform_real_distribution_test.cc b/third_party/abseil-cpp/absl/random/uniform_real_distribution_test.cc
index 07f199d..260aac9 100644
--- a/third_party/abseil-cpp/absl/random/uniform_real_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/uniform_real_distribution_test.cc
@@ -26,7 +26,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/numeric/internal/representation.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/distribution_test_util.h"
@@ -182,9 +182,8 @@
 
     if (!std::is_same<real_type, long double>::value) {
       // static_cast<double>(long double) can overflow.
-      std::string msg = absl::StrCat("Range: ", static_cast<double>(sample_min),
-                                     ", ", static_cast<double>(sample_max));
-      ABSL_RAW_LOG(INFO, "%s", msg.c_str());
+      LOG(INFO) << "Range: " << static_cast<double>(sample_min) << ", "
+                << static_cast<double>(sample_max);
     }
   }
 }
@@ -324,7 +323,7 @@
       absl::StrAppend(&msg, kChiSquared, " p-value ", p_value, "\n");
       absl::StrAppend(&msg, "High ", kChiSquared, " value: ", chi_square, " > ",
                       kThreshold);
-      ABSL_RAW_LOG(INFO, "%s", msg.c_str());
+      LOG(INFO) << msg;
       FAIL() << msg;
     }
   }
diff --git a/third_party/abseil-cpp/absl/random/zipf_distribution_test.cc b/third_party/abseil-cpp/absl/random/zipf_distribution_test.cc
index c8bb89db..801ec4f 100644
--- a/third_party/abseil-cpp/absl/random/zipf_distribution_test.cc
+++ b/third_party/abseil-cpp/absl/random/zipf_distribution_test.cc
@@ -25,7 +25,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/random/internal/chi_square.h"
 #include "absl/random/internal/pcg_engine.h"
 #include "absl/random/internal/sequence_urbg.h"
@@ -102,8 +102,7 @@
       if (sample > sample_max) sample_max = sample;
       if (sample < sample_min) sample_min = sample;
     }
-    ABSL_INTERNAL_LOG(INFO,
-                      absl::StrCat("Range: ", +sample_min, ", ", +sample_max));
+    LOG(INFO) << "Range: " << sample_min << ", " << sample_max;
   }
 }
 
@@ -303,18 +302,15 @@
 
   // Log if the chi_squared value is above the threshold.
   if (chi_square > threshold) {
-    ABSL_INTERNAL_LOG(INFO, "values");
+    LOG(INFO) << "values";
     for (size_t i = 0; i < expected.size(); i++) {
-      ABSL_INTERNAL_LOG(INFO, absl::StrCat(points[i], ": ", buckets[i],
-                                           " vs. E=", expected[i]));
+      LOG(INFO) << points[i] << ": " << buckets[i] << " vs. E=" << expected[i];
     }
-    ABSL_INTERNAL_LOG(INFO, absl::StrCat("trials ", trials));
-    ABSL_INTERNAL_LOG(INFO,
-                      absl::StrCat("mean ", avg, " vs. expected ", mean()));
-    ABSL_INTERNAL_LOG(INFO, absl::StrCat(kChiSquared, "(data, ", dof, ") = ",
-                                         chi_square, " (", p_actual, ")"));
-    ABSL_INTERNAL_LOG(INFO,
-                      absl::StrCat(kChiSquared, " @ 0.9995 = ", threshold));
+    LOG(INFO) << "trials " << trials;
+    LOG(INFO) << "mean " << avg << " vs. expected " << mean();
+    LOG(INFO) << kChiSquared << "(data, " << dof << ") = " << chi_square << " ("
+              << p_actual << ")";
+    LOG(INFO) << kChiSquared << " @ 0.9995 = " << threshold;
     FAIL() << kChiSquared << " value of " << chi_square
            << " is above the threshold.";
   }
diff --git a/third_party/abseil-cpp/absl/strings/BUILD.bazel b/third_party/abseil-cpp/absl/strings/BUILD.bazel
index e48a9a0a..bd33c533b 100644
--- a/third_party/abseil-cpp/absl/strings/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/strings/BUILD.bazel
@@ -774,10 +774,10 @@
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:endian",
-        "//absl/base:raw_logging_internal",
         "//absl/container:fixed_array",
         "//absl/hash",
         "//absl/log",
+        "//absl/log:check",
         "//absl/random",
         "@com_google_googletest//:gtest_main",
     ],
@@ -1019,7 +1019,7 @@
         ":pow10_helper",
         ":strings",
         "//absl/base:config",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/random",
         "//absl/random:distributions",
         "@com_google_googletest//:gtest_main",
@@ -1096,7 +1096,7 @@
     deps = [
         ":strings",
         "//absl/base:config",
-        "//absl/base:raw_logging_internal",
+        "//absl/log:check",
         "@com_google_googletest//:gtest_main",
     ],
 )
@@ -1253,6 +1253,7 @@
         ":strings",
         "//absl/base:core_headers",
         "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/types:optional",
         "@com_google_googletest//:gtest_main",
     ],
diff --git a/third_party/abseil-cpp/absl/strings/BUILD.gn b/third_party/abseil-cpp/absl/strings/BUILD.gn
index 8d43c76..07c53f8a 100644
--- a/third_party/abseil-cpp/absl/strings/BUILD.gn
+++ b/third_party/abseil-cpp/absl/strings/BUILD.gn
@@ -480,10 +480,10 @@
 #     "//third_party/abseil-cpp/absl/base:config",
 #     "//third_party/abseil-cpp/absl/base:core_headers",
 #     "//third_party/abseil-cpp/absl/base:endian",
-#     "//third_party/abseil-cpp/absl/base:raw_logging_internal",
 #     "//third_party/abseil-cpp/absl/container:fixed_array",
 #     "//third_party/abseil-cpp/absl/hash",
 #     "//third_party/abseil-cpp/absl/log",
+#     "//third_party/abseil-cpp/absl/log:check",
 #     "//third_party/abseil-cpp/absl/random",
 #   ]
 # }
diff --git a/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/third_party/abseil-cpp/absl/strings/CMakeLists.txt
index d2928bd..9aaa7932 100644
--- a/third_party/abseil-cpp/absl/strings/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/strings/CMakeLists.txt
@@ -317,7 +317,7 @@
     absl::core_headers
     absl::pow10_helper
     absl::config
-    absl::raw_logging_internal
+    absl::log
     absl::random_random
     absl::random_distributions
     absl::strings_internal
@@ -372,9 +372,9 @@
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
-    absl::strings
+    absl::check
     absl::config
-    absl::raw_logging_internal
+    absl::strings
     GTest::gmock_main
 )
 
@@ -516,6 +516,7 @@
     absl::strings
     absl::str_format_internal
     absl::core_headers
+    absl::log
     absl::raw_logging_internal
     absl::int128
     GTest::gmock_main
@@ -960,19 +961,20 @@
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
-    absl::cord
-    absl::str_format
-    absl::strings
     absl::base
+    absl::check
     absl::config
+    absl::cord
     absl::cord_test_helpers
     absl::cordz_test_helpers
     absl::core_headers
     absl::endian
-    absl::hash
-    absl::random_random
-    absl::raw_logging_internal
     absl::fixed_array
+    absl::hash
+    absl::log
+    absl::random_random
+    absl::str_format
+    absl::strings
     GTest::gmock_main
 )
 
diff --git a/third_party/abseil-cpp/absl/strings/cord_test.cc b/third_party/abseil-cpp/absl/strings/cord_test.cc
index 3fe3967..55412c7 100644
--- a/third_party/abseil-cpp/absl/strings/cord_test.cc
+++ b/third_party/abseil-cpp/absl/strings/cord_test.cc
@@ -30,10 +30,11 @@
 #include "gtest/gtest.h"
 #include "absl/base/config.h"
 #include "absl/base/internal/endian.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
 #include "absl/container/fixed_array.h"
 #include "absl/hash/hash.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/random/random.h"
 #include "absl/strings/cord_test_helpers.h"
 #include "absl/strings/cordz_test_helpers.h"
@@ -210,9 +211,8 @@
   }
 
   static Cord MakeSubstring(Cord src, size_t offset, size_t length) {
-    ABSL_RAW_CHECK(src.contents_.is_tree(), "Can not be inlined");
-    ABSL_RAW_CHECK(src.ExpectedChecksum() == absl::nullopt,
-                   "Can not be hardened");
+    CHECK(src.contents_.is_tree()) << "Can not be inlined";
+    CHECK(!src.ExpectedChecksum().has_value()) << "Can not be hardened";
     Cord cord;
     auto* tree = cord_internal::SkipCrcNode(src.contents_.tree());
     auto* rep = CordRepSubstring::Create(CordRep::Ref(tree), offset, length);
@@ -374,7 +374,7 @@
   for (int i = 0; i < 1024; ++i) {
     c.Append(from);
   }
-  ABSL_RAW_LOG(INFO, "Made a Cord with %zu bytes!", c.size());
+  LOG(INFO) << "Made a Cord with " << c.size() << " bytes!";
   // Note: on a 32-bit build, this comes out to   2,818,048,000 bytes.
   // Note: on a 64-bit build, this comes out to 171,932,385,280 bytes.
 }
@@ -1247,15 +1247,15 @@
 // Splice block into cord.
 absl::Cord SpliceCord(const absl::Cord& blob, int64_t offset,
                       const absl::Cord& block) {
-  ABSL_RAW_CHECK(offset >= 0, "");
-  ABSL_RAW_CHECK(offset + block.size() <= blob.size(), "");
+  CHECK_GE(offset, 0);
+  CHECK_LE(static_cast<size_t>(offset) + block.size(), blob.size());
   absl::Cord result(blob);
   result.RemoveSuffix(blob.size() - offset);
   result.Append(block);
   absl::Cord suffix(blob);
   suffix.RemovePrefix(offset + block.size());
   result.Append(suffix);
-  ABSL_RAW_CHECK(blob.size() == result.size(), "");
+  CHECK_EQ(blob.size(), result.size());
   return result;
 }
 
@@ -1855,7 +1855,7 @@
   // windows DLL, we may have ODR like effects on the flag, meaning the DLL
   // code will run with the picked up default.
   if (!absl::CordTestPeer::Tree(cord1)->IsBtree()) {
-    ABSL_RAW_LOG(WARNING, "Cord library code not respecting btree flag");
+    LOG(WARNING) << "Cord library code not respecting btree flag";
     return;
   }
 
@@ -1940,8 +1940,7 @@
   std::string value;
   absl::CopyCordToString(cord, &value);
   EXPECT_EQ(value, expected);
-  ABSL_RAW_LOG(INFO, "Diabolical size allocated = %zu",
-               cord.EstimatedMemoryUsage());
+  LOG(INFO) << "Diabolical size allocated = " << cord.EstimatedMemoryUsage();
 }
 
 // The following tests check support for >4GB cords in 64-bit binaries, and
diff --git a/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc b/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc
index bc2d111..2b7b082 100644
--- a/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc
+++ b/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc
@@ -19,7 +19,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/check.h"
 #include "absl/strings/str_cat.h"
 
 using absl::chars_format;
@@ -56,14 +56,14 @@
     begin_subrange = static_cast<int>(open_bracket_pos);
     s.replace(open_bracket_pos, 1, "");
     std::string::size_type close_bracket_pos = s.find(']');
-    ABSL_RAW_CHECK(close_bracket_pos != absl::string_view::npos,
-                   "Test input contains [ without matching ]");
+    CHECK_NE(close_bracket_pos, absl::string_view::npos)
+        << "Test input contains [ without matching ]";
     end_subrange = static_cast<int>(close_bracket_pos);
     s.replace(close_bracket_pos, 1, "");
   }
   const std::string::size_type expected_characters_matched = s.find('$');
-  ABSL_RAW_CHECK(expected_characters_matched != std::string::npos,
-                 "Input string must contain $");
+  CHECK_NE(expected_characters_matched, std::string::npos)
+      << "Input string must contain $";
   s.replace(expected_characters_matched, 1, "");
 
   ParsedFloat parsed =
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h b/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
index e3e27fcd..27c4b21eb 100644
--- a/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
+++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
@@ -120,8 +120,16 @@
     // Round size up so it matches a size we can exactly express in a tag.
     const size_t size = RoundUpForTag(len + kFlatOverhead);
     void* const raw_rep = ::operator new(size);
+    // GCC 13 has a false-positive -Wstringop-overflow warning here.
+    #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(13, 0)
+    #pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wstringop-overflow"
+    #endif
     CordRepFlat* rep = new (raw_rep) CordRepFlat();
     rep->tag = AllocatedSizeToTag(size);
+    #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(13, 0)
+    #pragma GCC diagnostic pop
+    #endif
     return rep;
   }
 
diff --git a/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc b/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc
index 8b5a27ed..16ff987 100644
--- a/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc
+++ b/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc
@@ -26,6 +26,7 @@
 #include "gtest/gtest.h"
 #include "absl/base/attributes.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/strings/internal/str_format/bind.h"
 #include "absl/strings/match.h"
 #include "absl/types/optional.h"
@@ -264,7 +265,7 @@
   }
   void* parsed = nullptr;
   if (sscanf(arg.c_str(), "%p", &parsed) != 1) {
-    ABSL_RAW_LOG(FATAL, "Could not parse %s", arg.c_str());
+    LOG(FATAL) << "Could not parse " << arg;
   }
   return ptr == parsed;
 }
diff --git a/third_party/abseil-cpp/absl/strings/numbers.cc b/third_party/abseil-cpp/absl/strings/numbers.cc
index c2b861ae..7dc8922 100644
--- a/third_party/abseil-cpp/absl/strings/numbers.cc
+++ b/third_party/abseil-cpp/absl/strings/numbers.cc
@@ -31,7 +31,9 @@
 #include <utility>
 
 #include "absl/base/attributes.h"
+#include "absl/base/internal/endian.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/base/optimization.h"
 #include "absl/numeric/bits.h"
 #include "absl/strings/ascii.h"
 #include "absl/strings/charconv.h"
@@ -136,82 +138,123 @@
 
 namespace {
 
-// Used to optimize printing a decimal number's final digit.
-const char one_ASCII_final_digits[10][2] {
-  {'0', 0}, {'1', 0}, {'2', 0}, {'3', 0}, {'4', 0},
-  {'5', 0}, {'6', 0}, {'7', 0}, {'8', 0}, {'9', 0},
-};
+// Various routines to encode integers to strings.
+
+// We split data encodings into a group of 2 digits, 4 digits, 8 digits as
+// it's easier to combine powers of two into scalar arithmetic.
+
+// Previous implementation used a lookup table of 200 bytes for every 2 bytes
+// and it was memory bound, any L1 cache miss would result in a much slower
+// result. When benchmarking with a cache eviction rate of several percent,
+// this implementation proved to be better.
+
+// These constants represent '00', '0000' and '00000000' as ascii strings in
+// integers. We can add these numbers if we encode to bytes from 0 to 9. as
+// 'i' = '0' + i for 0 <= i <= 9.
+constexpr uint32_t kTwoZeroBytes = 0x0101 * '0';
+constexpr uint64_t kFourZeroBytes = 0x01010101 * '0';
+constexpr uint64_t kEightZeroBytes = 0x0101010101010101ull * '0';
+
+// * 103 / 1024 is a division by 10 for values from 0 to 99. It's also a
+// division of a structure [k takes 2 bytes][m takes 2 bytes], then * 103 / 1024
+// will be [k / 10][m / 10]. It allows parallel division.
+constexpr uint64_t kDivisionBy10Mul = 103u;
+constexpr uint64_t kDivisionBy10Div = 1 << 10;
+
+// * 10486 / 1048576 is a division by 100 for values from 0 to 9999.
+constexpr uint64_t kDivisionBy100Mul = 10486u;
+constexpr uint64_t kDivisionBy100Div = 1 << 20;
+
+// Encode functions write the ASCII output of input `n` to `out_str`.
+inline char* EncodeHundred(uint32_t n, char* out_str) {
+  int num_digits = static_cast<int>(n - 10) >> 8;
+  uint32_t base = kTwoZeroBytes;
+  uint32_t div10 = (n * kDivisionBy10Mul) / kDivisionBy10Div;
+  uint32_t mod10 = n - 10u * div10;
+  base += div10 + (mod10 << 8);
+  base >>= num_digits & 8;
+  little_endian::Store16(out_str, static_cast<uint16_t>(base));
+  return out_str + 2 + num_digits;
+}
+
+inline char* EncodeTenThousand(uint32_t n, char* out_str) {
+  // We split lower 2 digits and upper 2 digits of n into 2 byte consecutive
+  // blocks. 123 ->  [\0\1][\0\23]. We divide by 10 both blocks
+  // (it's 1 division + zeroing upper bits), and compute modulo 10 as well "in
+  // parallel". Then we combine both results to have both ASCII digits,
+  // strip trailing zeros, add ASCII '0000' and return.
+  uint32_t div100 = (n * kDivisionBy100Mul) / kDivisionBy100Div;
+  uint32_t mod100 = n - 100ull * div100;
+  uint32_t hundreds = (mod100 << 16) + div100;
+  uint32_t tens = (hundreds * kDivisionBy10Mul) / kDivisionBy10Div;
+  tens &= (0xFull << 16) | 0xFull;
+  tens += (hundreds - 10ull * tens) << 8;
+  ABSL_ASSUME(tens != 0);
+  // The result can contain trailing zero bits, we need to strip them to a first
+  // significant byte in a final representation. For example, for n = 123, we
+  // have tens to have representation \0\1\2\3. We do `& -8` to round
+  // to a multiple to 8 to strip zero bytes, not all zero bits.
+  // countr_zero to help.
+  // 0 minus 8 to make MSVC happy.
+  uint32_t zeroes = static_cast<uint32_t>(absl::countr_zero(tens)) & (0 - 8ull);
+  tens += kFourZeroBytes;
+  tens >>= zeroes;
+  little_endian::Store32(out_str, tens);
+  return out_str + sizeof(tens) - zeroes / 8;
+}
+
+// Prepare functions return an integer that should be written to out_str
+// (but possibly include trailing zeros).
+// For hi < 10000, lo < 10000 returns uint64_t as encoded in ASCII with
+// possibly trailing zeroes of the number hi * 10000 + lo.
+inline uint64_t PrepareTenThousands(uint64_t hi, uint64_t lo) {
+  uint64_t merged = hi | (lo << 32);
+  uint64_t div100 = ((merged * kDivisionBy100Mul) / kDivisionBy100Div) &
+                    ((0x7Full << 32) | 0x7Full);
+  uint64_t mod100 = merged - 100ull * div100;
+  uint64_t hundreds = (mod100 << 16) + div100;
+  uint64_t tens = (hundreds * kDivisionBy10Mul) / kDivisionBy10Div;
+  tens &= (0xFull << 48) | (0xFull << 32) | (0xFull << 16) | 0xFull;
+  tens += (hundreds - 10ull * tens) << 8;
+  return tens;
+}
+
+inline char* EncodeFullU32(uint32_t n, char* out_str) {
+  if (n < 100'000'000) {
+    uint64_t bottom = PrepareTenThousands(n / 10000, n % 10000);
+    ABSL_ASSUME(bottom != 0);
+    // 0 minus 8 to make MSVC happy.
+    uint32_t zeroes = static_cast<uint32_t>(absl::countr_zero(bottom))
+        & (0 - 8ull);
+    uint64_t bottom_res = bottom + kEightZeroBytes;
+    bottom_res >>= zeroes;
+    little_endian::Store64(out_str, bottom_res);
+    return out_str + sizeof(bottom) - zeroes / 8;
+  }
+  uint32_t top = n / 100'000'000;
+  n %= 100'000'000;
+  uint64_t bottom = PrepareTenThousands(n / 10000, n % 10000);
+  uint64_t bottom_res = bottom + kEightZeroBytes;
+  out_str = EncodeHundred(top, out_str);
+  little_endian::Store64(out_str, bottom_res);
+  return out_str + sizeof(bottom);
+}
 
 }  // namespace
 
-char* numbers_internal::FastIntToBuffer(uint32_t i, char* buffer) {
-  uint32_t digits;
-  // The idea of this implementation is to trim the number of divides to as few
-  // as possible, and also reducing memory stores and branches, by going in
-  // steps of two digits at a time rather than one whenever possible.
-  // The huge-number case is first, in the hopes that the compiler will output
-  // that case in one branch-free block of code, and only output conditional
-  // branches into it from below.
-  if (i >= 1000000000) {     // >= 1,000,000,000
-    digits = i / 100000000;  //      100,000,000
-    i -= digits * 100000000;
-    PutTwoDigits(digits, buffer);
-    buffer += 2;
-  lt100_000_000:
-    digits = i / 1000000;  // 1,000,000
-    i -= digits * 1000000;
-    PutTwoDigits(digits, buffer);
-    buffer += 2;
-  lt1_000_000:
-    digits = i / 10000;  // 10,000
-    i -= digits * 10000;
-    PutTwoDigits(digits, buffer);
-    buffer += 2;
-  lt10_000:
-    digits = i / 100;
-    i -= digits * 100;
-    PutTwoDigits(digits, buffer);
-    buffer += 2;
- lt100:
-    digits = i;
-    PutTwoDigits(digits, buffer);
-    buffer += 2;
-    *buffer = 0;
-    return buffer;
+char* numbers_internal::FastIntToBuffer(uint32_t n, char* out_str) {
+  if (n < 100) {
+    out_str = EncodeHundred(n, out_str);
+    goto set_last_zero;
   }
-
-  if (i < 100) {
-    digits = i;
-    if (i >= 10) goto lt100;
-    memcpy(buffer, one_ASCII_final_digits[i], 2);
-    return buffer + 1;
+  if (n < 10000) {
+    out_str = EncodeTenThousand(n, out_str);
+    goto set_last_zero;
   }
-  if (i < 10000) {  //    10,000
-    if (i >= 1000) goto lt10_000;
-    digits = i / 100;
-    i -= digits * 100;
-    *buffer++ = '0' + static_cast<char>(digits);
-    goto lt100;
-  }
-  if (i < 1000000) {  //    1,000,000
-    if (i >= 100000) goto lt1_000_000;
-    digits = i / 10000;  //    10,000
-    i -= digits * 10000;
-    *buffer++ = '0' + static_cast<char>(digits);
-    goto lt10_000;
-  }
-  if (i < 100000000) {  //    100,000,000
-    if (i >= 10000000) goto lt100_000_000;
-    digits = i / 1000000;  //   1,000,000
-    i -= digits * 1000000;
-    *buffer++ = '0' + static_cast<char>(digits);
-    goto lt1_000_000;
-  }
-  // we already know that i < 1,000,000,000
-  digits = i / 100000000;  //   100,000,000
-  i -= digits * 100000000;
-  *buffer++ = '0' + static_cast<char>(digits);
-  goto lt100_000_000;
+  out_str = EncodeFullU32(n, out_str);
+set_last_zero:
+  *out_str = '\0';
+  return out_str;
 }
 
 char* numbers_internal::FastIntToBuffer(int32_t i, char* buffer) {
@@ -230,41 +273,40 @@
   uint32_t u32 = static_cast<uint32_t>(i);
   if (u32 == i) return numbers_internal::FastIntToBuffer(u32, buffer);
 
-  // Here we know i has at least 10 decimal digits.
-  uint64_t top_1to11 = i / 1000000000;
-  u32 = static_cast<uint32_t>(i - top_1to11 * 1000000000);
-  uint32_t top_1to11_32 = static_cast<uint32_t>(top_1to11);
-
-  if (top_1to11_32 == top_1to11) {
-    buffer = numbers_internal::FastIntToBuffer(top_1to11_32, buffer);
-  } else {
-    // top_1to11 has more than 32 bits too; print it in two steps.
-    uint32_t top_8to9 = static_cast<uint32_t>(top_1to11 / 100);
-    uint32_t mid_2 = static_cast<uint32_t>(top_1to11 - top_8to9 * 100);
-    buffer = numbers_internal::FastIntToBuffer(top_8to9, buffer);
-    PutTwoDigits(mid_2, buffer);
-    buffer += 2;
+  // 10**9 < 2**32 <= i < 10**10, we can do 2+8
+  uint64_t div08 = i / 100'000'000ull;
+  uint64_t mod08 = i % 100'000'000ull;
+  uint64_t mod_result =
+      PrepareTenThousands(mod08 / 10000, mod08 % 10000) + kEightZeroBytes;
+  if (i < 10'000'000'000ull) {
+    buffer = EncodeHundred(static_cast<uint32_t>(div08), buffer);
+    little_endian::Store64(buffer, mod_result);
+    buffer += 8;
+    goto set_last_zero;
   }
 
-  // We have only 9 digits now, again the maximum uint32_t can handle fully.
-  uint32_t digits = u32 / 10000000;  // 10,000,000
-  u32 -= digits * 10000000;
-  PutTwoDigits(digits, buffer);
-  buffer += 2;
-  digits = u32 / 100000;  // 100,000
-  u32 -= digits * 100000;
-  PutTwoDigits(digits, buffer);
-  buffer += 2;
-  digits = u32 / 1000;  // 1,000
-  u32 -= digits * 1000;
-  PutTwoDigits(digits, buffer);
-  buffer += 2;
-  digits = u32 / 10;
-  u32 -= digits * 10;
-  PutTwoDigits(digits, buffer);
-  buffer += 2;
-  memcpy(buffer, one_ASCII_final_digits[u32], 2);
-  return buffer + 1;
+  // i < 10**16, in this case 8+8
+  if (i < 10'000'000'000'000'000ull) {
+    buffer = EncodeFullU32(static_cast<uint32_t>(div08), buffer);
+    little_endian::Store64(buffer, mod_result);
+    buffer += 8;
+    goto set_last_zero;
+  } else {
+    // 4 + 8 + 8
+    uint64_t div016 = i / 10'000'000'000'000'000ull;
+    buffer = EncodeTenThousand(static_cast<uint32_t>(div016), buffer);
+    uint64_t mid_result = div08 - div016 * 100'000'000ull;
+    mid_result = PrepareTenThousands(mid_result / 10000, mid_result % 10000) +
+                 kEightZeroBytes;
+    little_endian::Store64(buffer, mid_result);
+    buffer += 8;
+    little_endian::Store64(buffer, mod_result);
+    buffer += 8;
+    goto set_last_zero;
+  }
+set_last_zero:
+  *buffer = '\0';
+  return buffer;
 }
 
 char* numbers_internal::FastIntToBuffer(int64_t i, char* buffer) {
diff --git a/third_party/abseil-cpp/absl/strings/numbers_test.cc b/third_party/abseil-cpp/absl/strings/numbers_test.cc
index b3c098d1..2864bda2 100644
--- a/third_party/abseil-cpp/absl/strings/numbers_test.cc
+++ b/third_party/abseil-cpp/absl/strings/numbers_test.cc
@@ -37,7 +37,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/random/distributions.h"
 #include "absl/random/random.h"
 #include "absl/strings/internal/numbers_test_common.h"
@@ -1337,11 +1337,9 @@
     if (strcmp(sixdigitsbuf, snprintfbuf) != 0) {
       mismatches.push_back(d);
       if (mismatches.size() < 10) {
-        ABSL_RAW_LOG(ERROR, "%s",
-                     absl::StrCat("Six-digit failure with double.  ", "d=", d,
-                                  "=", d, " sixdigits=", sixdigitsbuf,
-                                  " printf(%g)=", snprintfbuf)
-                         .c_str());
+        LOG(ERROR) << "Six-digit failure with double.  d=" << d
+                   << " sixdigits=" << sixdigitsbuf
+                   << " printf(%g)=" << snprintfbuf;
       }
     }
   };
@@ -1389,12 +1387,10 @@
       if (kFloatNumCases >= 1e9) {
         // The exhaustive test takes a very long time, so log progress.
         char buf[kSixDigitsToBufferSize];
-        ABSL_RAW_LOG(
-            INFO, "%s",
-            absl::StrCat("Exp ", exponent, " powten=", powten, "(", powten,
-                         ") (",
-                         std::string(buf, SixDigitsToBuffer(powten, buf)), ")")
-                .c_str());
+        LOG(INFO) << "Exp " << exponent << " powten=" << powten << "(" << powten
+                  << ") ("
+                  << absl::string_view(buf, SixDigitsToBuffer(powten, buf))
+                  << ")";
       }
       for (int digits : digit_testcases) {
         if (exponent == 308 && digits >= 179769) break;  // don't overflow!
@@ -1419,20 +1415,17 @@
       double before = nextafter(d, 0.0);
       double after = nextafter(d, 1.7976931348623157e308);
       char b1[32], b2[kSixDigitsToBufferSize];
-      ABSL_RAW_LOG(
-          ERROR, "%s",
-          absl::StrCat(
-              "Mismatch #", i, "  d=", d, " (", ToNineDigits(d), ")",
-              " sixdigits='", sixdigitsbuf, "'", " snprintf='", snprintfbuf,
-              "'", " Before.=", PerfectDtoa(before), " ",
-              (SixDigitsToBuffer(before, b2), b2),
-              " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", before), b1),
-              " Perfect=", PerfectDtoa(d), " ", (SixDigitsToBuffer(d, b2), b2),
-              " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", d), b1),
-              " After.=.", PerfectDtoa(after), " ",
-              (SixDigitsToBuffer(after, b2), b2),
-              " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", after), b1))
-              .c_str());
+      LOG(ERROR) << "Mismatch #" << i << "  d=" << d << " (" << ToNineDigits(d)
+                 << ") sixdigits='" << sixdigitsbuf << "' snprintf='"
+                 << snprintfbuf << "' Before.=" << PerfectDtoa(before) << " "
+                 << (SixDigitsToBuffer(before, b2), b2) << " vs snprintf="
+                 << (snprintf(b1, sizeof(b1), "%g", before), b1)
+                 << " Perfect=" << PerfectDtoa(d) << " "
+                 << (SixDigitsToBuffer(d, b2), b2)
+                 << " vs snprintf=" << (snprintf(b1, sizeof(b1), "%g", d), b1)
+                 << " After.=." << PerfectDtoa(after) << " "
+                 << (SixDigitsToBuffer(after, b2), b2) << " vs snprintf="
+                 << (snprintf(b1, sizeof(b1), "%g", after), b1);
     }
   }
 }
diff --git a/third_party/abseil-cpp/absl/synchronization/BUILD.bazel b/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
index 5074044..3d405df 100644
--- a/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
@@ -198,7 +198,8 @@
     deps = [
         ":graphcycles_internal",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
+        "//absl/log:check",
         "@com_google_googletest//:gtest_main",
     ],
 )
@@ -247,7 +248,8 @@
         "//absl/base",
         "//absl/base:config",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
+        "//absl/log:check",
         "//absl/memory",
         "//absl/time",
         "@com_google_googletest//:gtest_main",
@@ -376,6 +378,6 @@
     deps = [
         ":synchronization",
         "//absl/base:core_headers",
-        "//absl/base:raw_logging_internal",
+        "//absl/log:check",
     ],
 )
diff --git a/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt b/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt
index 86278349..a0f64e5cea 100644
--- a/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt
@@ -151,9 +151,10 @@
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
-    absl::graphcycles_internal
+    absl::check
     absl::core_headers
-    absl::raw_logging_internal
+    absl::graphcycles_internal
+    absl::log
     GTest::gmock_main
 )
 
@@ -183,10 +184,11 @@
     absl::synchronization
     absl::thread_pool
     absl::base
+    absl::check
     absl::config
     absl::core_headers
+    absl::log
     absl::memory
-    absl::raw_logging_internal
     absl::time
     GTest::gmock_main
 )
@@ -278,5 +280,5 @@
   DEPS
     absl::synchronization
     absl::core_headers
-    absl::raw_logging_internal
+    absl::check
 )
diff --git a/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc b/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc
index 74eaffe..3c6ef79 100644
--- a/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc
+++ b/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc
@@ -21,8 +21,9 @@
 #include <vector>
 
 #include "gtest/gtest.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -65,51 +66,51 @@
 }
 
 static void PrintEdges(Edges *edges) {
-  ABSL_RAW_LOG(INFO, "EDGES (%zu)", edges->size());
+  LOG(INFO) << "EDGES (" << edges->size() << ")";
   for (const auto &edge : *edges) {
     int a = edge.from;
     int b = edge.to;
-    ABSL_RAW_LOG(INFO, "%d %d", a, b);
+    LOG(INFO) << a << " " << b;
   }
-  ABSL_RAW_LOG(INFO, "---");
+  LOG(INFO) << "---";
 }
 
 static void PrintGCEdges(Nodes *nodes, const IdMap &id, GraphCycles *gc) {
-  ABSL_RAW_LOG(INFO, "GC EDGES");
+  LOG(INFO) << "GC EDGES";
   for (int a : *nodes) {
     for (int b : *nodes) {
       if (gc->HasEdge(Get(id, a), Get(id, b))) {
-        ABSL_RAW_LOG(INFO, "%d %d", a, b);
+        LOG(INFO) << a << " " << b;
       }
     }
   }
-  ABSL_RAW_LOG(INFO, "---");
+  LOG(INFO) << "---";
 }
 
 static void PrintTransitiveClosure(Nodes *nodes, Edges *edges) {
-  ABSL_RAW_LOG(INFO, "Transitive closure");
+  LOG(INFO) << "Transitive closure";
   for (int a : *nodes) {
     for (int b : *nodes) {
       std::unordered_set<int> seen;
       if (IsReachable(edges, a, b, &seen)) {
-        ABSL_RAW_LOG(INFO, "%d %d", a, b);
+        LOG(INFO) << a << " " << b;
       }
     }
   }
-  ABSL_RAW_LOG(INFO, "---");
+  LOG(INFO) << "---";
 }
 
 static void PrintGCTransitiveClosure(Nodes *nodes, const IdMap &id,
                                      GraphCycles *gc) {
-  ABSL_RAW_LOG(INFO, "GC Transitive closure");
+  LOG(INFO) << "GC Transitive closure";
   for (int a : *nodes) {
     for (int b : *nodes) {
       if (gc->IsReachable(Get(id, a), Get(id, b))) {
-        ABSL_RAW_LOG(INFO, "%d %d", a, b);
+        LOG(INFO) << a << " " << b;
       }
     }
   }
-  ABSL_RAW_LOG(INFO, "---");
+  LOG(INFO) << "---";
 }
 
 static void CheckTransitiveClosure(Nodes *nodes, Edges *edges, const IdMap &id,
@@ -125,9 +126,8 @@
         PrintGCEdges(nodes, id, gc);
         PrintTransitiveClosure(nodes, edges);
         PrintGCTransitiveClosure(nodes, id, gc);
-        ABSL_RAW_LOG(FATAL, "gc_reachable %s reachable %s a %d b %d",
-                     gc_reachable ? "true" : "false",
-                     reachable ? "true" : "false", a, b);
+        LOG(FATAL) << "gc_reachable " << gc_reachable << " reachable "
+                   << reachable << " a " << a << " b " << b;
       }
     }
   }
@@ -142,7 +142,7 @@
     if (!gc->HasEdge(Get(id, a), Get(id, b))) {
       PrintEdges(edges);
       PrintGCEdges(nodes, id, gc);
-      ABSL_RAW_LOG(FATAL, "!gc->HasEdge(%d, %d)", a, b);
+      LOG(FATAL) << "!gc->HasEdge(" << a << ", " << b << ")";
     }
   }
   for (const auto &a : *nodes) {
@@ -155,13 +155,12 @@
   if (count != edges->size()) {
     PrintEdges(edges);
     PrintGCEdges(nodes, id, gc);
-    ABSL_RAW_LOG(FATAL, "edges->size() %zu  count %d", edges->size(), count);
+    LOG(FATAL) << "edges->size() " << edges->size() << "  count " << count;
   }
 }
 
 static void CheckInvariants(const GraphCycles &gc) {
-  if (ABSL_PREDICT_FALSE(!gc.CheckInvariants()))
-    ABSL_RAW_LOG(FATAL, "CheckInvariants");
+  CHECK(gc.CheckInvariants()) << "CheckInvariants";
 }
 
 // Returns the index of a randomly chosen node in *nodes.
@@ -309,7 +308,7 @@
       break;
 
     default:
-      ABSL_RAW_LOG(FATAL, "op %d", op);
+      LOG(FATAL) << "op " << op;
     }
 
     // Very rarely, test graph expansion by adding then removing many nodes.
diff --git a/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc b/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc
index e627423..d5ce35a 100644
--- a/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc
+++ b/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc
@@ -18,8 +18,8 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/const_init.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/thread_annotations.h"
+#include "absl/log/check.h"
 #include "absl/synchronization/mutex.h"
 #include "absl/synchronization/notification.h"
 
@@ -35,20 +35,20 @@
 // Thread two waits on 'notification', then sets 'state' inside the 'mutex',
 // signalling the change via 'condvar'.
 //
-// These tests use ABSL_RAW_CHECK to validate invariants, rather than EXPECT or
-// ASSERT from gUnit, because we need to invoke them during global destructors,
-// when gUnit teardown would have already begun.
+// These tests use CHECK to validate invariants, rather than EXPECT or ASSERT
+// from gUnit, because we need to invoke them during global destructors, when
+// gUnit teardown would have already begun.
 void ThreadOne(absl::Mutex* mutex, absl::CondVar* condvar,
                absl::Notification* notification, bool* state) {
   // Test that the notification is in a valid initial state.
-  ABSL_RAW_CHECK(!notification->HasBeenNotified(), "invalid Notification");
-  ABSL_RAW_CHECK(*state == false, "*state not initialized");
+  CHECK(!notification->HasBeenNotified()) << "invalid Notification";
+  CHECK(!*state) << "*state not initialized";
 
   {
     absl::MutexLock lock(mutex);
 
     notification->Notify();
-    ABSL_RAW_CHECK(notification->HasBeenNotified(), "invalid Notification");
+    CHECK(notification->HasBeenNotified()) << "invalid Notification";
 
     while (*state == false) {
       condvar->Wait(mutex);
@@ -58,11 +58,11 @@
 
 void ThreadTwo(absl::Mutex* mutex, absl::CondVar* condvar,
                absl::Notification* notification, bool* state) {
-  ABSL_RAW_CHECK(*state == false, "*state not initialized");
+  CHECK(!*state) << "*state not initialized";
 
   // Wake thread one
   notification->WaitForNotification();
-  ABSL_RAW_CHECK(notification->HasBeenNotified(), "invalid Notification");
+  CHECK(notification->HasBeenNotified()) << "invalid Notification";
   {
     absl::MutexLock lock(mutex);
     *state = true;
diff --git a/third_party/abseil-cpp/absl/synchronization/mutex_test.cc b/third_party/abseil-cpp/absl/synchronization/mutex_test.cc
index ec039a7..4ae4d7e 100644
--- a/third_party/abseil-cpp/absl/synchronization/mutex_test.cc
+++ b/third_party/abseil-cpp/absl/synchronization/mutex_test.cc
@@ -32,8 +32,9 @@
 #include "gtest/gtest.h"
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/base/internal/sysinfo.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/memory/memory.h"
 #include "absl/synchronization/internal/thread_pool.h"
 #include "absl/time/clock.h"
@@ -87,7 +88,7 @@
 
 static void CheckSumG0G1(void *v) {
   TestContext *cxt = static_cast<TestContext *>(v);
-  ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in CheckSumG0G1");
+  CHECK_EQ(cxt->g0, -cxt->g1) << "Error in CheckSumG0G1";
   SetInvariantChecked(true);
 }
 
@@ -132,7 +133,7 @@
   } else {
     for (int i = 0; i != cxt->iterations; i++) {
       absl::ReaderMutexLock l(&cxt->mu);
-      ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in TestRW");
+      CHECK_EQ(cxt->g0, -cxt->g1) << "Error in TestRW";
       cxt->mu.AssertReaderHeld();
     }
   }
@@ -157,7 +158,7 @@
   cxt->mu.AssertHeld();
   while (cxt->g0 < cxt->iterations) {
     cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn));
-    ABSL_RAW_CHECK(mc.MyTurn(), "Error in TestAwait");
+    CHECK(mc.MyTurn()) << "Error in TestAwait";
     cxt->mu.AssertHeld();
     if (cxt->g0 < cxt->iterations) {
       int a = cxt->g0 + 1;
@@ -185,7 +186,7 @@
 }
 
 static void TestSignal(TestContext *cxt, int c) {
-  ABSL_RAW_CHECK(cxt->threads == 2, "TestSignal should use 2 threads");
+  CHECK_EQ(cxt->threads, 2) << "TestSignal should use 2 threads";
   int target = c;
   absl::MutexLock l(&cxt->mu);
   cxt->mu.AssertHeld();
@@ -222,8 +223,8 @@
 static bool G0GE2(TestContext *cxt) { return cxt->g0 >= 2; }
 
 static void TestTime(TestContext *cxt, int c, bool use_cv) {
-  ABSL_RAW_CHECK(cxt->iterations == 1, "TestTime should only use 1 iteration");
-  ABSL_RAW_CHECK(cxt->threads > 2, "TestTime should use more than 2 threads");
+  CHECK_EQ(cxt->iterations, 1) << "TestTime should only use 1 iteration";
+  CHECK_GT(cxt->threads, 2) << "TestTime should use more than 2 threads";
   const bool kFalse = false;
   absl::Condition false_cond(&kFalse);
   absl::Condition g0ge2(G0GE2, cxt);
@@ -234,26 +235,24 @@
     if (use_cv) {
       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
     } else {
-      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
-                     "TestTime failed");
+      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
+          << "TestTime failed";
     }
     absl::Duration elapsed = absl::Now() - start;
-    ABSL_RAW_CHECK(
-        absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
-        "TestTime failed");
-    ABSL_RAW_CHECK(cxt->g0 == 1, "TestTime failed");
+    CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
+        << "TestTime failed";
+    CHECK_EQ(cxt->g0, 1) << "TestTime failed";
 
     start = absl::Now();
     if (use_cv) {
       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
     } else {
-      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
-                     "TestTime failed");
+      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
+          << "TestTime failed";
     }
     elapsed = absl::Now() - start;
-    ABSL_RAW_CHECK(
-        absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
-        "TestTime failed");
+    CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
+        << "TestTime failed";
     cxt->g0++;
     if (use_cv) {
       cxt->cv.Signal();
@@ -263,26 +262,24 @@
     if (use_cv) {
       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(4));
     } else {
-      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)),
-                     "TestTime failed");
+      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)))
+          << "TestTime failed";
     }
     elapsed = absl::Now() - start;
-    ABSL_RAW_CHECK(
-        absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0),
-        "TestTime failed");
-    ABSL_RAW_CHECK(cxt->g0 >= 3, "TestTime failed");
+    CHECK(absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0))
+        << "TestTime failed";
+    CHECK_GE(cxt->g0, 3) << "TestTime failed";
 
     start = absl::Now();
     if (use_cv) {
       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
     } else {
-      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
-                     "TestTime failed");
+      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
+          << "TestTime failed";
     }
     elapsed = absl::Now() - start;
-    ABSL_RAW_CHECK(
-        absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
-        "TestTime failed");
+    CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
+        << "TestTime failed";
     if (use_cv) {
       cxt->cv.SignalAll();
     }
@@ -291,14 +288,13 @@
     if (use_cv) {
       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
     } else {
-      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
-                     "TestTime failed");
+      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
+          << "TestTime failed";
     }
     elapsed = absl::Now() - start;
-    ABSL_RAW_CHECK(
-        absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
-        "TestTime failed");
-    ABSL_RAW_CHECK(cxt->g0 == cxt->threads, "TestTime failed");
+    CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
+        << "TestTime failed";
+    CHECK_EQ(cxt->g0, cxt->threads) << "TestTime failed";
 
   } else if (c == 1) {
     absl::MutexLock l(&cxt->mu);
@@ -306,14 +302,12 @@
     if (use_cv) {
       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500));
     } else {
-      ABSL_RAW_CHECK(
-          !cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)),
-          "TestTime failed");
+      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)))
+          << "TestTime failed";
     }
     const absl::Duration elapsed = absl::Now() - start;
-    ABSL_RAW_CHECK(
-        absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9),
-        "TestTime failed");
+    CHECK(absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9))
+        << "TestTime failed";
     cxt->g0++;
   } else if (c == 2) {
     absl::MutexLock l(&cxt->mu);
@@ -322,8 +316,8 @@
         cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
       }
     } else {
-      ABSL_RAW_CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)),
-                     "TestTime failed");
+      CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)))
+          << "TestTime failed";
     }
     cxt->g0++;
   } else {
@@ -400,7 +394,7 @@
   TestContext cxt;
   cxt.mu.EnableInvariantDebugging(invariant, &cxt);
   int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
-  ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked");
+  CHECK(GetInvariantChecked()) << "Invariant not checked";
   absl::EnableMutexInvariantDebugging(false);  // Restore.
   return ret;
 }
@@ -1093,7 +1087,7 @@
                                absl::Milliseconds(100));
     x->mu1.Unlock();
   }
-  ABSL_RAW_CHECK(x->value < 4, "should not be invoked a fourth time");
+  CHECK_LT(x->value, 4) << "should not be invoked a fourth time";
 
   // We arrange for the condition to return true on only the 2nd and 3rd calls.
   return x->value == 2 || x->value == 3;
@@ -1340,11 +1334,9 @@
   // different clock than absl::Now(), but these cases should be handled by the
   // the retry mechanism in each TimeoutTest.
   if (actual_delay < expected_delay) {
-    ABSL_RAW_LOG(WARNING,
-                 "Actual delay %s was too short, expected %s (difference %s)",
-                 absl::FormatDuration(actual_delay).c_str(),
-                 absl::FormatDuration(expected_delay).c_str(),
-                 absl::FormatDuration(actual_delay - expected_delay).c_str());
+    LOG(WARNING) << "Actual delay " << actual_delay
+                 << " was too short, expected " << expected_delay
+                 << " (difference " << actual_delay - expected_delay << ")";
     pass = false;
   }
   // If the expected delay is <= zero then allow a small error tolerance, since
@@ -1355,11 +1347,9 @@
                                  ? absl::Milliseconds(10)
                                  : TimeoutTestAllowedSchedulingDelay();
   if (actual_delay > expected_delay + tolerance) {
-    ABSL_RAW_LOG(WARNING,
-                 "Actual delay %s was too long, expected %s (difference %s)",
-                 absl::FormatDuration(actual_delay).c_str(),
-                 absl::FormatDuration(expected_delay).c_str(),
-                 absl::FormatDuration(actual_delay - expected_delay).c_str());
+    LOG(WARNING) << "Actual delay " << actual_delay
+                 << " was too long, expected " << expected_delay
+                 << " (difference " << actual_delay - expected_delay << ")";
     pass = false;
   }
   return pass;
@@ -1409,12 +1399,6 @@
             << " expected_delay: " << param.expected_delay;
 }
 
-std::string FormatString(const TimeoutTestParam &param) {
-  std::ostringstream os;
-  os << param;
-  return os.str();
-}
-
 // Like `thread::Executor::ScheduleAt` except:
 // a) Delays zero or negative are executed immediately in the current thread.
 // b) Infinite delays are never scheduled.
@@ -1544,13 +1528,13 @@
 
 TEST_P(TimeoutTest, Await) {
   const TimeoutTestParam params = GetParam();
-  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
+  LOG(INFO) << "Params: " << params;
 
   // Because this test asserts bounds on scheduling delays it is flaky.  To
   // compensate it loops forever until it passes.  Failures express as test
   // timeouts, in which case the test log can be used to diagnose the issue.
   for (int attempt = 1;; ++attempt) {
-    ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
+    LOG(INFO) << "Attempt " << attempt;
 
     absl::Mutex mu;
     bool value = false;  // condition value (under mu)
@@ -1578,13 +1562,13 @@
 
 TEST_P(TimeoutTest, LockWhen) {
   const TimeoutTestParam params = GetParam();
-  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
+  LOG(INFO) << "Params: " << params;
 
   // Because this test asserts bounds on scheduling delays it is flaky.  To
   // compensate it loops forever until it passes.  Failures express as test
   // timeouts, in which case the test log can be used to diagnose the issue.
   for (int attempt = 1;; ++attempt) {
-    ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
+    LOG(INFO) << "Attempt " << attempt;
 
     absl::Mutex mu;
     bool value = false;  // condition value (under mu)
@@ -1613,13 +1597,13 @@
 
 TEST_P(TimeoutTest, ReaderLockWhen) {
   const TimeoutTestParam params = GetParam();
-  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
+  LOG(INFO) << "Params: " << params;
 
   // Because this test asserts bounds on scheduling delays it is flaky.  To
   // compensate it loops forever until it passes.  Failures express as test
   // timeouts, in which case the test log can be used to diagnose the issue.
   for (int attempt = 0;; ++attempt) {
-    ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
+    LOG(INFO) << "Attempt " << attempt;
 
     absl::Mutex mu;
     bool value = false;  // condition value (under mu)
@@ -1649,13 +1633,13 @@
 
 TEST_P(TimeoutTest, Wait) {
   const TimeoutTestParam params = GetParam();
-  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
+  LOG(INFO) << "Params: " << params;
 
   // Because this test asserts bounds on scheduling delays it is flaky.  To
   // compensate it loops forever until it passes.  Failures express as test
   // timeouts, in which case the test log can be used to diagnose the issue.
   for (int attempt = 0;; ++attempt) {
-    ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
+    LOG(INFO) << "Attempt " << attempt;
 
     absl::Mutex mu;
     bool value = false;  // condition value (under mu)
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc
index f1f79a2..4a6c71f1 100644
--- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc
+++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc
@@ -64,10 +64,13 @@
 template <typename D>
 void TestFormatSpecifier(time_point<D> tp, time_zone tz, const std::string& fmt,
                          const std::string& ans) {
-  EXPECT_EQ(ans, format(fmt, tp, tz)) << fmt;
-  EXPECT_EQ("xxx " + ans, format("xxx " + fmt, tp, tz));
-  EXPECT_EQ(ans + " yyy", format(fmt + " yyy", tp, tz));
-  EXPECT_EQ("xxx " + ans + " yyy", format("xxx " + fmt + " yyy", tp, tz));
+  EXPECT_EQ(ans, absl::time_internal::cctz::format(fmt, tp, tz)) << fmt;
+  EXPECT_EQ("xxx " + ans,
+            absl::time_internal::cctz::format("xxx " + fmt, tp, tz));
+  EXPECT_EQ(ans + " yyy",
+            absl::time_internal::cctz::format(fmt + " yyy", tp, tz));
+  EXPECT_EQ("xxx " + ans + " yyy",
+            absl::time_internal::cctz::format("xxx " + fmt + " yyy", tp, tz));
 }
 
 }  // namespace
@@ -83,26 +86,29 @@
       chrono::system_clock::from_time_t(1420167845) +
       chrono::milliseconds(123) + chrono::microseconds(456) +
       chrono::nanoseconds(789);
-  EXPECT_EQ(
-      "03:04:05.123456789",
-      format(kFmt, chrono::time_point_cast<chrono::nanoseconds>(t0), utc));
-  EXPECT_EQ(
-      "03:04:05.123456",
-      format(kFmt, chrono::time_point_cast<chrono::microseconds>(t0), utc));
-  EXPECT_EQ(
-      "03:04:05.123",
-      format(kFmt, chrono::time_point_cast<chrono::milliseconds>(t0), utc));
+  EXPECT_EQ("03:04:05.123456789",
+            absl::time_internal::cctz::format(
+                kFmt, chrono::time_point_cast<chrono::nanoseconds>(t0), utc));
+  EXPECT_EQ("03:04:05.123456",
+            absl::time_internal::cctz::format(
+                kFmt, chrono::time_point_cast<chrono::microseconds>(t0), utc));
+  EXPECT_EQ("03:04:05.123",
+            absl::time_internal::cctz::format(
+                kFmt, chrono::time_point_cast<chrono::milliseconds>(t0), utc));
   EXPECT_EQ("03:04:05",
-            format(kFmt, chrono::time_point_cast<chrono::seconds>(t0), utc));
+            absl::time_internal::cctz::format(
+                kFmt, chrono::time_point_cast<chrono::seconds>(t0), utc));
   EXPECT_EQ(
       "03:04:05",
-      format(kFmt,
-             chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0),
-             utc));
+      absl::time_internal::cctz::format(
+          kFmt, chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0),
+          utc));
   EXPECT_EQ("03:04:00",
-            format(kFmt, chrono::time_point_cast<chrono::minutes>(t0), utc));
+            absl::time_internal::cctz::format(
+                kFmt, chrono::time_point_cast<chrono::minutes>(t0), utc));
   EXPECT_EQ("03:00:00",
-            format(kFmt, chrono::time_point_cast<chrono::hours>(t0), utc));
+            absl::time_internal::cctz::format(
+                kFmt, chrono::time_point_cast<chrono::hours>(t0), utc));
 }
 
 TEST(Format, TimePointExtendedResolution) {
@@ -137,24 +143,28 @@
   time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0);
 
   // Starts with a couple basic edge cases.
-  EXPECT_EQ("", format("", tp, tz));
-  EXPECT_EQ(" ", format(" ", tp, tz));
-  EXPECT_EQ("  ", format("  ", tp, tz));
-  EXPECT_EQ("xxx", format("xxx", tp, tz));
+  EXPECT_EQ("", absl::time_internal::cctz::format("", tp, tz));
+  EXPECT_EQ(" ", absl::time_internal::cctz::format(" ", tp, tz));
+  EXPECT_EQ("  ", absl::time_internal::cctz::format("  ", tp, tz));
+  EXPECT_EQ("xxx", absl::time_internal::cctz::format("xxx", tp, tz));
   std::string big(128, 'x');
-  EXPECT_EQ(big, format(big, tp, tz));
+  EXPECT_EQ(big, absl::time_internal::cctz::format(big, tp, tz));
   // Cause the 1024-byte buffer to grow.
   std::string bigger(100000, 'x');
-  EXPECT_EQ(bigger, format(bigger, tp, tz));
+  EXPECT_EQ(bigger, absl::time_internal::cctz::format(bigger, tp, tz));
 
   tp += chrono::hours(13) + chrono::minutes(4) + chrono::seconds(5);
   tp += chrono::milliseconds(6) + chrono::microseconds(7) +
         chrono::nanoseconds(8);
-  EXPECT_EQ("1970-01-01", format("%Y-%m-%d", tp, tz));
-  EXPECT_EQ("13:04:05", format("%H:%M:%S", tp, tz));
-  EXPECT_EQ("13:04:05.006", format("%H:%M:%E3S", tp, tz));
-  EXPECT_EQ("13:04:05.006007", format("%H:%M:%E6S", tp, tz));
-  EXPECT_EQ("13:04:05.006007008", format("%H:%M:%E9S", tp, tz));
+  EXPECT_EQ("1970-01-01",
+            absl::time_internal::cctz::format("%Y-%m-%d", tp, tz));
+  EXPECT_EQ("13:04:05", absl::time_internal::cctz::format("%H:%M:%S", tp, tz));
+  EXPECT_EQ("13:04:05.006",
+            absl::time_internal::cctz::format("%H:%M:%E3S", tp, tz));
+  EXPECT_EQ("13:04:05.006007",
+            absl::time_internal::cctz::format("%H:%M:%E6S", tp, tz));
+  EXPECT_EQ("13:04:05.006007008",
+            absl::time_internal::cctz::format("%H:%M:%E9S", tp, tz));
 }
 
 TEST(Format, PosixConversions) {
@@ -211,7 +221,8 @@
   TestFormatSpecifier(tp, tz, "%B", "January");
 
   // %c should at least produce the numeric year and time-of-day.
-  const std::string s = format("%c", tp, utc_time_zone());
+  const std::string s =
+      absl::time_internal::cctz::format("%c", tp, utc_time_zone());
   EXPECT_THAT(s, testing::HasSubstr("1970"));
   EXPECT_THAT(s, testing::HasSubstr("00:00:00"));
 
@@ -277,49 +288,61 @@
   // No subseconds.
   time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0);
   tp += chrono::seconds(5);
-  EXPECT_EQ("05", format("%E*S", tp, tz));
-  EXPECT_EQ("05", format("%E0S", tp, tz));
-  EXPECT_EQ("05.0", format("%E1S", tp, tz));
-  EXPECT_EQ("05.00", format("%E2S", tp, tz));
-  EXPECT_EQ("05.000", format("%E3S", tp, tz));
-  EXPECT_EQ("05.0000", format("%E4S", tp, tz));
-  EXPECT_EQ("05.00000", format("%E5S", tp, tz));
-  EXPECT_EQ("05.000000", format("%E6S", tp, tz));
-  EXPECT_EQ("05.0000000", format("%E7S", tp, tz));
-  EXPECT_EQ("05.00000000", format("%E8S", tp, tz));
-  EXPECT_EQ("05.000000000", format("%E9S", tp, tz));
-  EXPECT_EQ("05.0000000000", format("%E10S", tp, tz));
-  EXPECT_EQ("05.00000000000", format("%E11S", tp, tz));
-  EXPECT_EQ("05.000000000000", format("%E12S", tp, tz));
-  EXPECT_EQ("05.0000000000000", format("%E13S", tp, tz));
-  EXPECT_EQ("05.00000000000000", format("%E14S", tp, tz));
-  EXPECT_EQ("05.000000000000000", format("%E15S", tp, tz));
+  EXPECT_EQ("05", absl::time_internal::cctz::format("%E*S", tp, tz));
+  EXPECT_EQ("05", absl::time_internal::cctz::format("%E0S", tp, tz));
+  EXPECT_EQ("05.0", absl::time_internal::cctz::format("%E1S", tp, tz));
+  EXPECT_EQ("05.00", absl::time_internal::cctz::format("%E2S", tp, tz));
+  EXPECT_EQ("05.000", absl::time_internal::cctz::format("%E3S", tp, tz));
+  EXPECT_EQ("05.0000", absl::time_internal::cctz::format("%E4S", tp, tz));
+  EXPECT_EQ("05.00000", absl::time_internal::cctz::format("%E5S", tp, tz));
+  EXPECT_EQ("05.000000", absl::time_internal::cctz::format("%E6S", tp, tz));
+  EXPECT_EQ("05.0000000", absl::time_internal::cctz::format("%E7S", tp, tz));
+  EXPECT_EQ("05.00000000", absl::time_internal::cctz::format("%E8S", tp, tz));
+  EXPECT_EQ("05.000000000", absl::time_internal::cctz::format("%E9S", tp, tz));
+  EXPECT_EQ("05.0000000000",
+            absl::time_internal::cctz::format("%E10S", tp, tz));
+  EXPECT_EQ("05.00000000000",
+            absl::time_internal::cctz::format("%E11S", tp, tz));
+  EXPECT_EQ("05.000000000000",
+            absl::time_internal::cctz::format("%E12S", tp, tz));
+  EXPECT_EQ("05.0000000000000",
+            absl::time_internal::cctz::format("%E13S", tp, tz));
+  EXPECT_EQ("05.00000000000000",
+            absl::time_internal::cctz::format("%E14S", tp, tz));
+  EXPECT_EQ("05.000000000000000",
+            absl::time_internal::cctz::format("%E15S", tp, tz));
 
   // With subseconds.
   tp += chrono::milliseconds(6) + chrono::microseconds(7) +
         chrono::nanoseconds(8);
-  EXPECT_EQ("05.006007008", format("%E*S", tp, tz));
-  EXPECT_EQ("05", format("%E0S", tp, tz));
-  EXPECT_EQ("05.0", format("%E1S", tp, tz));
-  EXPECT_EQ("05.00", format("%E2S", tp, tz));
-  EXPECT_EQ("05.006", format("%E3S", tp, tz));
-  EXPECT_EQ("05.0060", format("%E4S", tp, tz));
-  EXPECT_EQ("05.00600", format("%E5S", tp, tz));
-  EXPECT_EQ("05.006007", format("%E6S", tp, tz));
-  EXPECT_EQ("05.0060070", format("%E7S", tp, tz));
-  EXPECT_EQ("05.00600700", format("%E8S", tp, tz));
-  EXPECT_EQ("05.006007008", format("%E9S", tp, tz));
-  EXPECT_EQ("05.0060070080", format("%E10S", tp, tz));
-  EXPECT_EQ("05.00600700800", format("%E11S", tp, tz));
-  EXPECT_EQ("05.006007008000", format("%E12S", tp, tz));
-  EXPECT_EQ("05.0060070080000", format("%E13S", tp, tz));
-  EXPECT_EQ("05.00600700800000", format("%E14S", tp, tz));
-  EXPECT_EQ("05.006007008000000", format("%E15S", tp, tz));
+  EXPECT_EQ("05.006007008", absl::time_internal::cctz::format("%E*S", tp, tz));
+  EXPECT_EQ("05", absl::time_internal::cctz::format("%E0S", tp, tz));
+  EXPECT_EQ("05.0", absl::time_internal::cctz::format("%E1S", tp, tz));
+  EXPECT_EQ("05.00", absl::time_internal::cctz::format("%E2S", tp, tz));
+  EXPECT_EQ("05.006", absl::time_internal::cctz::format("%E3S", tp, tz));
+  EXPECT_EQ("05.0060", absl::time_internal::cctz::format("%E4S", tp, tz));
+  EXPECT_EQ("05.00600", absl::time_internal::cctz::format("%E5S", tp, tz));
+  EXPECT_EQ("05.006007", absl::time_internal::cctz::format("%E6S", tp, tz));
+  EXPECT_EQ("05.0060070", absl::time_internal::cctz::format("%E7S", tp, tz));
+  EXPECT_EQ("05.00600700", absl::time_internal::cctz::format("%E8S", tp, tz));
+  EXPECT_EQ("05.006007008", absl::time_internal::cctz::format("%E9S", tp, tz));
+  EXPECT_EQ("05.0060070080",
+            absl::time_internal::cctz::format("%E10S", tp, tz));
+  EXPECT_EQ("05.00600700800",
+            absl::time_internal::cctz::format("%E11S", tp, tz));
+  EXPECT_EQ("05.006007008000",
+            absl::time_internal::cctz::format("%E12S", tp, tz));
+  EXPECT_EQ("05.0060070080000",
+            absl::time_internal::cctz::format("%E13S", tp, tz));
+  EXPECT_EQ("05.00600700800000",
+            absl::time_internal::cctz::format("%E14S", tp, tz));
+  EXPECT_EQ("05.006007008000000",
+            absl::time_internal::cctz::format("%E15S", tp, tz));
 
   // Times before the Unix epoch.
   tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1);
   EXPECT_EQ("1969-12-31 23:59:59.999999",
-            format("%Y-%m-%d %H:%M:%E*S", tp, tz));
+            absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%E*S", tp, tz));
 
   // Here is a "%E*S" case we got wrong for a while.  While the first
   // instant below is correctly rendered as "...:07.333304", the second
@@ -327,10 +350,10 @@
   tp = chrono::system_clock::from_time_t(0) +
        chrono::microseconds(1395024427333304);
   EXPECT_EQ("2014-03-17 02:47:07.333304",
-            format("%Y-%m-%d %H:%M:%E*S", tp, tz));
+            absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%E*S", tp, tz));
   tp += chrono::microseconds(1);
   EXPECT_EQ("2014-03-17 02:47:07.333305",
-            format("%Y-%m-%d %H:%M:%E*S", tp, tz));
+            absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%E*S", tp, tz));
 }
 
 TEST(Format, ExtendedSubeconds) {
@@ -339,60 +362,69 @@
   // No subseconds.
   time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0);
   tp += chrono::seconds(5);
-  EXPECT_EQ("0", format("%E*f", tp, tz));
-  EXPECT_EQ("", format("%E0f", tp, tz));
-  EXPECT_EQ("0", format("%E1f", tp, tz));
-  EXPECT_EQ("00", format("%E2f", tp, tz));
-  EXPECT_EQ("000", format("%E3f", tp, tz));
-  EXPECT_EQ("0000", format("%E4f", tp, tz));
-  EXPECT_EQ("00000", format("%E5f", tp, tz));
-  EXPECT_EQ("000000", format("%E6f", tp, tz));
-  EXPECT_EQ("0000000", format("%E7f", tp, tz));
-  EXPECT_EQ("00000000", format("%E8f", tp, tz));
-  EXPECT_EQ("000000000", format("%E9f", tp, tz));
-  EXPECT_EQ("0000000000", format("%E10f", tp, tz));
-  EXPECT_EQ("00000000000", format("%E11f", tp, tz));
-  EXPECT_EQ("000000000000", format("%E12f", tp, tz));
-  EXPECT_EQ("0000000000000", format("%E13f", tp, tz));
-  EXPECT_EQ("00000000000000", format("%E14f", tp, tz));
-  EXPECT_EQ("000000000000000", format("%E15f", tp, tz));
+  EXPECT_EQ("0", absl::time_internal::cctz::format("%E*f", tp, tz));
+  EXPECT_EQ("", absl::time_internal::cctz::format("%E0f", tp, tz));
+  EXPECT_EQ("0", absl::time_internal::cctz::format("%E1f", tp, tz));
+  EXPECT_EQ("00", absl::time_internal::cctz::format("%E2f", tp, tz));
+  EXPECT_EQ("000", absl::time_internal::cctz::format("%E3f", tp, tz));
+  EXPECT_EQ("0000", absl::time_internal::cctz::format("%E4f", tp, tz));
+  EXPECT_EQ("00000", absl::time_internal::cctz::format("%E5f", tp, tz));
+  EXPECT_EQ("000000", absl::time_internal::cctz::format("%E6f", tp, tz));
+  EXPECT_EQ("0000000", absl::time_internal::cctz::format("%E7f", tp, tz));
+  EXPECT_EQ("00000000", absl::time_internal::cctz::format("%E8f", tp, tz));
+  EXPECT_EQ("000000000", absl::time_internal::cctz::format("%E9f", tp, tz));
+  EXPECT_EQ("0000000000", absl::time_internal::cctz::format("%E10f", tp, tz));
+  EXPECT_EQ("00000000000", absl::time_internal::cctz::format("%E11f", tp, tz));
+  EXPECT_EQ("000000000000", absl::time_internal::cctz::format("%E12f", tp, tz));
+  EXPECT_EQ("0000000000000",
+            absl::time_internal::cctz::format("%E13f", tp, tz));
+  EXPECT_EQ("00000000000000",
+            absl::time_internal::cctz::format("%E14f", tp, tz));
+  EXPECT_EQ("000000000000000",
+            absl::time_internal::cctz::format("%E15f", tp, tz));
 
   // With subseconds.
   tp += chrono::milliseconds(6) + chrono::microseconds(7) +
         chrono::nanoseconds(8);
-  EXPECT_EQ("006007008", format("%E*f", tp, tz));
-  EXPECT_EQ("", format("%E0f", tp, tz));
-  EXPECT_EQ("0", format("%E1f", tp, tz));
-  EXPECT_EQ("00", format("%E2f", tp, tz));
-  EXPECT_EQ("006", format("%E3f", tp, tz));
-  EXPECT_EQ("0060", format("%E4f", tp, tz));
-  EXPECT_EQ("00600", format("%E5f", tp, tz));
-  EXPECT_EQ("006007", format("%E6f", tp, tz));
-  EXPECT_EQ("0060070", format("%E7f", tp, tz));
-  EXPECT_EQ("00600700", format("%E8f", tp, tz));
-  EXPECT_EQ("006007008", format("%E9f", tp, tz));
-  EXPECT_EQ("0060070080", format("%E10f", tp, tz));
-  EXPECT_EQ("00600700800", format("%E11f", tp, tz));
-  EXPECT_EQ("006007008000", format("%E12f", tp, tz));
-  EXPECT_EQ("0060070080000", format("%E13f", tp, tz));
-  EXPECT_EQ("00600700800000", format("%E14f", tp, tz));
-  EXPECT_EQ("006007008000000", format("%E15f", tp, tz));
+  EXPECT_EQ("006007008", absl::time_internal::cctz::format("%E*f", tp, tz));
+  EXPECT_EQ("", absl::time_internal::cctz::format("%E0f", tp, tz));
+  EXPECT_EQ("0", absl::time_internal::cctz::format("%E1f", tp, tz));
+  EXPECT_EQ("00", absl::time_internal::cctz::format("%E2f", tp, tz));
+  EXPECT_EQ("006", absl::time_internal::cctz::format("%E3f", tp, tz));
+  EXPECT_EQ("0060", absl::time_internal::cctz::format("%E4f", tp, tz));
+  EXPECT_EQ("00600", absl::time_internal::cctz::format("%E5f", tp, tz));
+  EXPECT_EQ("006007", absl::time_internal::cctz::format("%E6f", tp, tz));
+  EXPECT_EQ("0060070", absl::time_internal::cctz::format("%E7f", tp, tz));
+  EXPECT_EQ("00600700", absl::time_internal::cctz::format("%E8f", tp, tz));
+  EXPECT_EQ("006007008", absl::time_internal::cctz::format("%E9f", tp, tz));
+  EXPECT_EQ("0060070080", absl::time_internal::cctz::format("%E10f", tp, tz));
+  EXPECT_EQ("00600700800", absl::time_internal::cctz::format("%E11f", tp, tz));
+  EXPECT_EQ("006007008000", absl::time_internal::cctz::format("%E12f", tp, tz));
+  EXPECT_EQ("0060070080000",
+            absl::time_internal::cctz::format("%E13f", tp, tz));
+  EXPECT_EQ("00600700800000",
+            absl::time_internal::cctz::format("%E14f", tp, tz));
+  EXPECT_EQ("006007008000000",
+            absl::time_internal::cctz::format("%E15f", tp, tz));
 
   // Times before the Unix epoch.
   tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1);
-  EXPECT_EQ("1969-12-31 23:59:59.999999",
-            format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
+  EXPECT_EQ(
+      "1969-12-31 23:59:59.999999",
+      absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
 
   // Here is a "%E*S" case we got wrong for a while.  While the first
   // instant below is correctly rendered as "...:07.333304", the second
   // one used to appear as "...:07.33330499999999999".
   tp = chrono::system_clock::from_time_t(0) +
        chrono::microseconds(1395024427333304);
-  EXPECT_EQ("2014-03-17 02:47:07.333304",
-            format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
+  EXPECT_EQ(
+      "2014-03-17 02:47:07.333304",
+      absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
   tp += chrono::microseconds(1);
-  EXPECT_EQ("2014-03-17 02:47:07.333305",
-            format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
+  EXPECT_EQ(
+      "2014-03-17 02:47:07.333305",
+      absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
 }
 
 TEST(Format, CompareExtendSecondsVsSubseconds) {
@@ -408,15 +440,17 @@
   time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0);
   tp += chrono::seconds(5);
   // ... %E*S and %S.%E*f are different.
-  EXPECT_EQ("05", format(fmt_A("*"), tp, tz));
-  EXPECT_EQ("05.0", format(fmt_B("*"), tp, tz));
+  EXPECT_EQ("05", absl::time_internal::cctz::format(fmt_A("*"), tp, tz));
+  EXPECT_EQ("05.0", absl::time_internal::cctz::format(fmt_B("*"), tp, tz));
   // ... %E0S and %S.%E0f are different.
-  EXPECT_EQ("05", format(fmt_A("0"), tp, tz));
-  EXPECT_EQ("05.", format(fmt_B("0"), tp, tz));
+  EXPECT_EQ("05", absl::time_internal::cctz::format(fmt_A("0"), tp, tz));
+  EXPECT_EQ("05.", absl::time_internal::cctz::format(fmt_B("0"), tp, tz));
   // ... %E<prec>S and %S.%E<prec>f are the same for prec in [1:15].
   for (int prec = 1; prec <= 15; ++prec) {
-    const std::string a = format(fmt_A(std::to_string(prec)), tp, tz);
-    const std::string b = format(fmt_B(std::to_string(prec)), tp, tz);
+    const std::string a =
+        absl::time_internal::cctz::format(fmt_A(std::to_string(prec)), tp, tz);
+    const std::string b =
+        absl::time_internal::cctz::format(fmt_B(std::to_string(prec)), tp, tz);
     EXPECT_EQ(a, b) << "prec=" << prec;
   }
 
@@ -424,15 +458,19 @@
   // ... %E*S and %S.%E*f are the same.
   tp += chrono::milliseconds(6) + chrono::microseconds(7) +
         chrono::nanoseconds(8);
-  EXPECT_EQ("05.006007008", format(fmt_A("*"), tp, tz));
-  EXPECT_EQ("05.006007008", format(fmt_B("*"), tp, tz));
+  EXPECT_EQ("05.006007008",
+            absl::time_internal::cctz::format(fmt_A("*"), tp, tz));
+  EXPECT_EQ("05.006007008",
+            absl::time_internal::cctz::format(fmt_B("*"), tp, tz));
   // ... %E0S and %S.%E0f are different.
-  EXPECT_EQ("05", format(fmt_A("0"), tp, tz));
-  EXPECT_EQ("05.", format(fmt_B("0"), tp, tz));
+  EXPECT_EQ("05", absl::time_internal::cctz::format(fmt_A("0"), tp, tz));
+  EXPECT_EQ("05.", absl::time_internal::cctz::format(fmt_B("0"), tp, tz));
   // ... %E<prec>S and %S.%E<prec>f are the same for prec in [1:15].
   for (int prec = 1; prec <= 15; ++prec) {
-    const std::string a = format(fmt_A(std::to_string(prec)), tp, tz);
-    const std::string b = format(fmt_B(std::to_string(prec)), tp, tz);
+    const std::string a =
+        absl::time_internal::cctz::format(fmt_A(std::to_string(prec)), tp, tz);
+    const std::string b =
+        absl::time_internal::cctz::format(fmt_B(std::to_string(prec)), tp, tz);
     EXPECT_EQ(a, b) << "prec=" << prec;
   }
 }
@@ -605,31 +643,31 @@
 
   // %E4Y zero-pads the year to produce at least 4 chars, including the sign.
   auto tp = convert(civil_second(-999, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("-9991127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("-9991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(-99, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("-0991127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("-0991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(-9, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("-0091127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("-0091127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(-1, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("-0011127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("-0011127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(0, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("00001127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("00001127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(1, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("00011127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("00011127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(9, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("00091127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("00091127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(99, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("00991127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("00991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(999, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("09991127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("09991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(9999, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("99991127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("99991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
 
   // When the year is outside [-999:9999], more than 4 chars are produced.
   tp = convert(civil_second(-1000, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("-10001127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("-10001127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
   tp = convert(civil_second(10000, 11, 27, 0, 0, 0), utc);
-  EXPECT_EQ("100001127", format(e4y_fmt, tp, utc));
+  EXPECT_EQ("100001127", absl::time_internal::cctz::format(e4y_fmt, tp, utc));
 }
 
 TEST(Format, RFC3339Format) {
@@ -638,45 +676,64 @@
 
   time_point<chrono::nanoseconds> tp =
       convert(civil_second(1977, 6, 28, 9, 8, 7), tz);
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::milliseconds(100);
-  EXPECT_EQ("1977-06-28T09:08:07.1-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07.1-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::milliseconds(20);
-  EXPECT_EQ("1977-06-28T09:08:07.12-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07.12-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::milliseconds(3);
-  EXPECT_EQ("1977-06-28T09:08:07.123-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07.123-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::microseconds(400);
-  EXPECT_EQ("1977-06-28T09:08:07.1234-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07.1234-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::microseconds(50);
-  EXPECT_EQ("1977-06-28T09:08:07.12345-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07.12345-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::microseconds(6);
-  EXPECT_EQ("1977-06-28T09:08:07.123456-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07.123456-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::nanoseconds(700);
-  EXPECT_EQ("1977-06-28T09:08:07.1234567-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07.1234567-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::nanoseconds(80);
-  EXPECT_EQ("1977-06-28T09:08:07.12345678-07:00", format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07.12345678-07:00",
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 
   tp += chrono::nanoseconds(9);
   EXPECT_EQ("1977-06-28T09:08:07.123456789-07:00",
-            format(RFC3339_full, tp, tz));
-  EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
+            absl::time_internal::cctz::format(RFC3339_full, tp, tz));
+  EXPECT_EQ("1977-06-28T09:08:07-07:00",
+            absl::time_internal::cctz::format(RFC3339_sec, tp, tz));
 }
 
 TEST(Format, RFC1123Format) {  // locale specific
@@ -684,36 +741,50 @@
   EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz));
 
   auto tp = convert(civil_second(1977, 6, 28, 9, 8, 7), tz);
-  EXPECT_EQ("Tue, 28 Jun 1977 09:08:07 -0700", format(RFC1123_full, tp, tz));
-  EXPECT_EQ("28 Jun 1977 09:08:07 -0700", format(RFC1123_no_wday, tp, tz));
+  EXPECT_EQ("Tue, 28 Jun 1977 09:08:07 -0700",
+            absl::time_internal::cctz::format(RFC1123_full, tp, tz));
+  EXPECT_EQ("28 Jun 1977 09:08:07 -0700",
+            absl::time_internal::cctz::format(RFC1123_no_wday, tp, tz));
 }
 
 TEST(Format, Week) {
   const time_zone utc = utc_time_zone();
 
   auto tp = convert(civil_second(2017, 1, 1, 0, 0, 0), utc);
-  EXPECT_EQ("2017-01-7", format("%Y-%U-%u", tp, utc));
-  EXPECT_EQ("2017-00-0", format("%Y-%W-%w", tp, utc));
+  EXPECT_EQ("2017-01-7",
+            absl::time_internal::cctz::format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2017-00-0",
+            absl::time_internal::cctz::format("%Y-%W-%w", tp, utc));
 
   tp = convert(civil_second(2017, 12, 31, 0, 0, 0), utc);
-  EXPECT_EQ("2017-53-7", format("%Y-%U-%u", tp, utc));
-  EXPECT_EQ("2017-52-0", format("%Y-%W-%w", tp, utc));
+  EXPECT_EQ("2017-53-7",
+            absl::time_internal::cctz::format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2017-52-0",
+            absl::time_internal::cctz::format("%Y-%W-%w", tp, utc));
 
   tp = convert(civil_second(2018, 1, 1, 0, 0, 0), utc);
-  EXPECT_EQ("2018-00-1", format("%Y-%U-%u", tp, utc));
-  EXPECT_EQ("2018-01-1", format("%Y-%W-%w", tp, utc));
+  EXPECT_EQ("2018-00-1",
+            absl::time_internal::cctz::format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2018-01-1",
+            absl::time_internal::cctz::format("%Y-%W-%w", tp, utc));
 
   tp = convert(civil_second(2018, 12, 31, 0, 0, 0), utc);
-  EXPECT_EQ("2018-52-1", format("%Y-%U-%u", tp, utc));
-  EXPECT_EQ("2018-53-1", format("%Y-%W-%w", tp, utc));
+  EXPECT_EQ("2018-52-1",
+            absl::time_internal::cctz::format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2018-53-1",
+            absl::time_internal::cctz::format("%Y-%W-%w", tp, utc));
 
   tp = convert(civil_second(2019, 1, 1, 0, 0, 0), utc);
-  EXPECT_EQ("2019-00-2", format("%Y-%U-%u", tp, utc));
-  EXPECT_EQ("2019-00-2", format("%Y-%W-%w", tp, utc));
+  EXPECT_EQ("2019-00-2",
+            absl::time_internal::cctz::format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2019-00-2",
+            absl::time_internal::cctz::format("%Y-%W-%w", tp, utc));
 
   tp = convert(civil_second(2019, 12, 31, 0, 0, 0), utc);
-  EXPECT_EQ("2019-52-2", format("%Y-%U-%u", tp, utc));
-  EXPECT_EQ("2019-52-2", format("%Y-%W-%w", tp, utc));
+  EXPECT_EQ("2019-52-2",
+            absl::time_internal::cctz::format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2019-52-2",
+            absl::time_internal::cctz::format("%Y-%W-%w", tp, utc));
 }
 
 //
@@ -726,39 +797,46 @@
 
   time_point<chrono::nanoseconds> tp_ns;
   EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_ns));
-  EXPECT_EQ("03:04:05.123456789", format(kFmt, tp_ns, utc));
+  EXPECT_EQ("03:04:05.123456789",
+            absl::time_internal::cctz::format(kFmt, tp_ns, utc));
   EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ns));
-  EXPECT_EQ("03:04:05.123456", format(kFmt, tp_ns, utc));
+  EXPECT_EQ("03:04:05.123456",
+            absl::time_internal::cctz::format(kFmt, tp_ns, utc));
 
   time_point<chrono::microseconds> tp_us;
   EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_us));
-  EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc));
+  EXPECT_EQ("03:04:05.123456",
+            absl::time_internal::cctz::format(kFmt, tp_us, utc));
   EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_us));
-  EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc));
+  EXPECT_EQ("03:04:05.123456",
+            absl::time_internal::cctz::format(kFmt, tp_us, utc));
   EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_us));
-  EXPECT_EQ("03:04:05.123", format(kFmt, tp_us, utc));
+  EXPECT_EQ("03:04:05.123",
+            absl::time_internal::cctz::format(kFmt, tp_us, utc));
 
   time_point<chrono::milliseconds> tp_ms;
   EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ms));
-  EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc));
+  EXPECT_EQ("03:04:05.123",
+            absl::time_internal::cctz::format(kFmt, tp_ms, utc));
   EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_ms));
-  EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc));
+  EXPECT_EQ("03:04:05.123",
+            absl::time_internal::cctz::format(kFmt, tp_ms, utc));
   EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_ms));
-  EXPECT_EQ("03:04:05", format(kFmt, tp_ms, utc));
+  EXPECT_EQ("03:04:05", absl::time_internal::cctz::format(kFmt, tp_ms, utc));
 
   time_point<chrono::seconds> tp_s;
   EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_s));
-  EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc));
+  EXPECT_EQ("03:04:05", absl::time_internal::cctz::format(kFmt, tp_s, utc));
   EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_s));
-  EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc));
+  EXPECT_EQ("03:04:05", absl::time_internal::cctz::format(kFmt, tp_s, utc));
 
   time_point<chrono::minutes> tp_m;
   EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_m));
-  EXPECT_EQ("03:04:00", format(kFmt, tp_m, utc));
+  EXPECT_EQ("03:04:00", absl::time_internal::cctz::format(kFmt, tp_m, utc));
 
   time_point<chrono::hours> tp_h;
   EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_h));
-  EXPECT_EQ("03:00:00", format(kFmt, tp_h, utc));
+  EXPECT_EQ("03:00:00", absl::time_internal::cctz::format(kFmt, tp_h, utc));
 }
 
 TEST(Parse, TimePointExtendedResolution) {
@@ -1550,7 +1628,7 @@
       parse(RFC3339_full, "2262-04-11T23:47:16.8547758079+00:00", utc, &tp));
   EXPECT_EQ(tp, time_point<D>::max());
   EXPECT_EQ("2262-04-11T23:47:16.854775807+00:00",
-            format(RFC3339_full, tp, utc));
+            absl::time_internal::cctz::format(RFC3339_full, tp, utc));
 #if 0
   // TODO(#199): Will fail until cctz::parse() properly detects overflow.
   EXPECT_FALSE(
@@ -1559,7 +1637,7 @@
       parse(RFC3339_full, "1677-09-21T00:12:43.1452241920+00:00", utc, &tp));
   EXPECT_EQ(tp, time_point<D>::min());
   EXPECT_EQ("1677-09-21T00:12:43.145224192+00:00",
-            format(RFC3339_full, tp, utc));
+            absl::time_internal::cctz::format(RFC3339_full, tp, utc));
   EXPECT_FALSE(
       parse(RFC3339_full, "1677-09-21T00:12:43.1452241919+00:00", utc, &tp));
 #endif
@@ -1569,12 +1647,14 @@
 
   EXPECT_TRUE(parse(RFC3339_full, "1970-01-01T00:02:07.9+00:00", utc, &stp));
   EXPECT_EQ(stp, time_point<DS>::max());
-  EXPECT_EQ("1970-01-01T00:02:07+00:00", format(RFC3339_full, stp, utc));
+  EXPECT_EQ("1970-01-01T00:02:07+00:00",
+            absl::time_internal::cctz::format(RFC3339_full, stp, utc));
   EXPECT_FALSE(parse(RFC3339_full, "1970-01-01T00:02:08+00:00", utc, &stp));
 
   EXPECT_TRUE(parse(RFC3339_full, "1969-12-31T23:57:52+00:00", utc, &stp));
   EXPECT_EQ(stp, time_point<DS>::min());
-  EXPECT_EQ("1969-12-31T23:57:52+00:00", format(RFC3339_full, stp, utc));
+  EXPECT_EQ("1969-12-31T23:57:52+00:00",
+            absl::time_internal::cctz::format(RFC3339_full, stp, utc));
   EXPECT_FALSE(parse(RFC3339_full, "1969-12-31T23:57:51.9+00:00", utc, &stp));
 
   using DM = chrono::duration<std::int8_t, chrono::minutes::period>;
@@ -1582,12 +1662,14 @@
 
   EXPECT_TRUE(parse(RFC3339_full, "1970-01-01T02:07:59+00:00", utc, &mtp));
   EXPECT_EQ(mtp, time_point<DM>::max());
-  EXPECT_EQ("1970-01-01T02:07:00+00:00", format(RFC3339_full, mtp, utc));
+  EXPECT_EQ("1970-01-01T02:07:00+00:00",
+            absl::time_internal::cctz::format(RFC3339_full, mtp, utc));
   EXPECT_FALSE(parse(RFC3339_full, "1970-01-01T02:08:00+00:00", utc, &mtp));
 
   EXPECT_TRUE(parse(RFC3339_full, "1969-12-31T21:52:00+00:00", utc, &mtp));
   EXPECT_EQ(mtp, time_point<DM>::min());
-  EXPECT_EQ("1969-12-31T21:52:00+00:00", format(RFC3339_full, mtp, utc));
+  EXPECT_EQ("1969-12-31T21:52:00+00:00",
+            absl::time_internal::cctz::format(RFC3339_full, mtp, utc));
   EXPECT_FALSE(parse(RFC3339_full, "1969-12-31T21:51:59+00:00", utc, &mtp));
 }
 
@@ -1601,7 +1683,7 @@
       parse(RFC3339_full, "294247-01-10T04:00:54.7758079+00:00", utc, &tp));
   EXPECT_EQ(tp, time_point<D>::max());
   EXPECT_EQ("294247-01-10T04:00:54.775807+00:00",
-            format(RFC3339_full, tp, utc));
+            absl::time_internal::cctz::format(RFC3339_full, tp, utc));
 #if 0
   // TODO(#199): Will fail until cctz::parse() properly detects overflow.
   EXPECT_FALSE(
@@ -1610,7 +1692,7 @@
       parse(RFC3339_full, "-290308-12-21T19:59:05.2241920+00:00", utc, &tp));
   EXPECT_EQ(tp, time_point<D>::min());
   EXPECT_EQ("-290308-12-21T19:59:05.224192+00:00",
-            format(RFC3339_full, tp, utc));
+            absl::time_internal::cctz::format(RFC3339_full, tp, utc));
   EXPECT_FALSE(
       parse(RFC3339_full, "-290308-12-21T19:59:05.2241919+00:00", utc, &tp));
 #endif
@@ -1629,7 +1711,8 @@
   // RFC3339, which renders subseconds.
   {
     time_point<chrono::nanoseconds> out;
-    const std::string s = format(RFC3339_full, in + subseconds, lax);
+    const std::string s =
+        absl::time_internal::cctz::format(RFC3339_full, in + subseconds, lax);
     EXPECT_TRUE(parse(RFC3339_full, s, lax, &out)) << s;
     EXPECT_EQ(in + subseconds, out);  // RFC3339_full includes %Ez
   }
@@ -1637,7 +1720,8 @@
   // RFC1123, which only does whole seconds.
   {
     time_point<chrono::nanoseconds> out;
-    const std::string s = format(RFC1123_full, in, lax);
+    const std::string s =
+        absl::time_internal::cctz::format(RFC1123_full, in, lax);
     EXPECT_TRUE(parse(RFC1123_full, s, lax, &out)) << s;
     EXPECT_EQ(in, out);  // RFC1123_full includes %z
   }
@@ -1655,7 +1739,7 @@
   {
     time_point<chrono::nanoseconds> out;
     time_zone utc = utc_time_zone();
-    const std::string s = format("%c", in, utc);
+    const std::string s = absl::time_internal::cctz::format("%c", in, utc);
     EXPECT_TRUE(parse("%c", s, utc, &out)) << s;
     EXPECT_EQ(in, out);
   }
@@ -1666,7 +1750,8 @@
   const time_zone utc = utc_time_zone();
   const time_point<absl::time_internal::cctz::seconds> in =
       time_point<absl::time_internal::cctz::seconds>::max();
-  const std::string s = format(RFC3339_full, in, utc);
+  const std::string s =
+      absl::time_internal::cctz::format(RFC3339_full, in, utc);
   time_point<absl::time_internal::cctz::seconds> out;
   EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s;
   EXPECT_EQ(in, out);
@@ -1676,7 +1761,8 @@
   const time_zone utc = utc_time_zone();
   const time_point<absl::time_internal::cctz::seconds> in =
       time_point<absl::time_internal::cctz::seconds>::min();
-  const std::string s = format(RFC3339_full, in, utc);
+  const std::string s =
+      absl::time_internal::cctz::format(RFC3339_full, in, utc);
   time_point<absl::time_internal::cctz::seconds> out;
   EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s;
   EXPECT_EQ(in, out);
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc
index f6983ae..9a30ba5 100644
--- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc
+++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc
@@ -35,6 +35,19 @@
 #include <zircon/types.h>
 #endif
 
+#if defined(_WIN32)
+#include <sdkddkver.h>
+// Include only when the SDK is for Windows 10 (and later), and the binary is
+// targeted for Windows XP and later.
+#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
+#include <roapi.h>
+#include <tchar.h>
+#include <wchar.h>
+#include <windows.globalization.h>
+#include <windows.h>
+#endif
+#endif
+
 #include <cstdlib>
 #include <cstring>
 #include <string>
@@ -47,8 +60,8 @@
 namespace time_internal {
 namespace cctz {
 
-#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21
 namespace {
+#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21
 // Android 'L' removes __system_property_get() from the NDK, however
 // it is still a hidden symbol in libc so we use dlsym() to access it.
 // See Chromium's base/sys_info_android.cc for a similar example.
@@ -72,10 +85,85 @@
   static property_get_func system_property_get = LoadSystemPropertyGet();
   return system_property_get ? system_property_get(name, value) : -1;
 }
-
-}  // namespace
 #endif
 
+#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
+// Calls the WinRT Calendar.GetTimeZone method to obtain the IANA ID of the
+// local time zone. Returns an empty vector in case of an error.
+std::string win32_local_time_zone(const HMODULE combase) {
+  std::string result;
+  const auto ro_activate_instance =
+      reinterpret_cast<decltype(&RoActivateInstance)>(
+          GetProcAddress(combase, "RoActivateInstance"));
+  if (!ro_activate_instance) {
+    return result;
+  }
+  const auto windows_create_string_reference =
+      reinterpret_cast<decltype(&WindowsCreateStringReference)>(
+          GetProcAddress(combase, "WindowsCreateStringReference"));
+  if (!windows_create_string_reference) {
+    return result;
+  }
+  const auto windows_delete_string =
+      reinterpret_cast<decltype(&WindowsDeleteString)>(
+          GetProcAddress(combase, "WindowsDeleteString"));
+  if (!windows_delete_string) {
+    return result;
+  }
+  const auto windows_get_string_raw_buffer =
+      reinterpret_cast<decltype(&WindowsGetStringRawBuffer)>(
+          GetProcAddress(combase, "WindowsGetStringRawBuffer"));
+  if (!windows_get_string_raw_buffer) {
+    return result;
+  }
+
+  // The string returned by WindowsCreateStringReference doesn't need to be
+  // deleted.
+  HSTRING calendar_class_id;
+  HSTRING_HEADER calendar_class_id_header;
+  HRESULT hr = windows_create_string_reference(
+      RuntimeClass_Windows_Globalization_Calendar,
+      sizeof(RuntimeClass_Windows_Globalization_Calendar) / sizeof(wchar_t) - 1,
+      &calendar_class_id_header, &calendar_class_id);
+  if (FAILED(hr)) {
+    return result;
+  }
+
+  IInspectable* calendar;
+  hr = ro_activate_instance(calendar_class_id, &calendar);
+  if (FAILED(hr)) {
+    return result;
+  }
+
+  ABI::Windows::Globalization::ITimeZoneOnCalendar* time_zone;
+  hr = calendar->QueryInterface(IID_PPV_ARGS(&time_zone));
+  if (FAILED(hr)) {
+    calendar->Release();
+    return result;
+  }
+
+  HSTRING tz_hstr;
+  hr = time_zone->GetTimeZone(&tz_hstr);
+  if (SUCCEEDED(hr)) {
+    UINT32 wlen;
+    const PCWSTR tz_wstr = windows_get_string_raw_buffer(tz_hstr, &wlen);
+    if (tz_wstr) {
+      const int size =
+          WideCharToMultiByte(CP_UTF8, 0, tz_wstr, static_cast<int>(wlen),
+                              nullptr, 0, nullptr, nullptr);
+      result.resize(static_cast<size_t>(size));
+      WideCharToMultiByte(CP_UTF8, 0, tz_wstr, static_cast<int>(wlen),
+                          &result[0], size, nullptr, nullptr);
+    }
+    windows_delete_string(tz_hstr);
+  }
+  time_zone->Release();
+  calendar->Release();
+  return result;
+}
+#endif
+}  // namespace
+
 std::string time_zone::name() const { return effective_impl().Name(); }
 
 time_zone::absolute_lookup time_zone::lookup(
@@ -190,6 +278,39 @@
     zone = primary_tz.c_str();
   }
 #endif
+#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
+  // Use the WinRT Calendar class to get the local time zone. This feature is
+  // available on Windows 10 and later. The library is dynamically linked to
+  // maintain binary compatibility with Windows XP - Windows 7. On Windows 8,
+  // The combase.dll API functions are available but the RoActivateInstance
+  // call will fail for the Calendar class.
+  std::string winrt_tz;
+  const HMODULE combase =
+      LoadLibraryEx(_T("combase.dll"), nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+  if (combase) {
+    const auto ro_initialize = reinterpret_cast<decltype(&::RoInitialize)>(
+        GetProcAddress(combase, "RoInitialize"));
+    const auto ro_uninitialize = reinterpret_cast<decltype(&::RoUninitialize)>(
+        GetProcAddress(combase, "RoUninitialize"));
+    if (ro_initialize && ro_uninitialize) {
+      const HRESULT hr = ro_initialize(RO_INIT_MULTITHREADED);
+      // RPC_E_CHANGED_MODE means that a previous RoInitialize call specified
+      // a different concurrency model. The WinRT runtime is initialized and
+      // should work for our purpose here, but we should *not* call
+      // RoUninitialize because it's a failure.
+      if (SUCCEEDED(hr) || hr == RPC_E_CHANGED_MODE) {
+        winrt_tz = win32_local_time_zone(combase);
+        if (SUCCEEDED(hr)) {
+          ro_uninitialize();
+        }
+      }
+    }
+    FreeLibrary(combase);
+  }
+  if (!winrt_tz.empty()) {
+    zone = winrt_tz.c_str();
+  }
+#endif
 
   // Allow ${TZ} to override to default zone.
   char* tz_env = nullptr;
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
index ab461f0..4b093b3 100644
--- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -911,19 +911,19 @@
   const time_zone utc = utc_time_zone();
   const time_point<chrono::nanoseconds> tp_ns =
       convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
-  EXPECT_EQ("04:05", format("%M:%E*S", tp_ns, utc));
+  EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_ns, utc));
   const time_point<chrono::microseconds> tp_us =
       convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
-  EXPECT_EQ("04:05", format("%M:%E*S", tp_us, utc));
+  EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_us, utc));
   const time_point<chrono::milliseconds> tp_ms =
       convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
-  EXPECT_EQ("04:05", format("%M:%E*S", tp_ms, utc));
+  EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_ms, utc));
   const time_point<chrono::seconds> tp_s =
       convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
-  EXPECT_EQ("04:05", format("%M:%E*S", tp_s, utc));
+  EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_s, utc));
   const time_point<absl::time_internal::cctz::seconds> tp_s64 =
       convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
-  EXPECT_EQ("04:05", format("%M:%E*S", tp_s64, utc));
+  EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_s64, utc));
 
   // These next two require chrono::time_point_cast because the conversion
   // from a resolution of seconds (the return value of convert()) to a
@@ -931,10 +931,10 @@
   const time_point<chrono::minutes> tp_m =
       chrono::time_point_cast<chrono::minutes>(
           convert(civil_second(2015, 1, 2, 3, 4, 5), utc));
-  EXPECT_EQ("04:00", format("%M:%E*S", tp_m, utc));
+  EXPECT_EQ("04:00", absl::time_internal::cctz::format("%M:%E*S", tp_m, utc));
   const time_point<chrono::hours> tp_h = chrono::time_point_cast<chrono::hours>(
       convert(civil_second(2015, 1, 2, 3, 4, 5), utc));
-  EXPECT_EQ("00:00", format("%M:%E*S", tp_h, utc));
+  EXPECT_EQ("00:00", absl::time_internal::cctz::format("%M:%E*S", tp_h, utc));
 }
 
 TEST(MakeTime, Normalization) {
@@ -960,9 +960,11 @@
 
   // Approach the maximal time_point<cctz::seconds> value from below.
   tp = convert(civil_second(292277026596, 12, 4, 15, 30, 6), utc);
-  EXPECT_EQ("292277026596-12-04T15:30:06+00:00", format(RFC3339, tp, utc));
+  EXPECT_EQ("292277026596-12-04T15:30:06+00:00",
+            absl::time_internal::cctz::format(RFC3339, tp, utc));
   tp = convert(civil_second(292277026596, 12, 4, 15, 30, 7), utc);
-  EXPECT_EQ("292277026596-12-04T15:30:07+00:00", format(RFC3339, tp, utc));
+  EXPECT_EQ("292277026596-12-04T15:30:07+00:00",
+            absl::time_internal::cctz::format(RFC3339, tp, utc));
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
   tp = convert(civil_second(292277026596, 12, 4, 15, 30, 8), utc);
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
@@ -971,7 +973,8 @@
 
   // Checks that we can also get the maximal value for a far-east zone.
   tp = convert(civil_second(292277026596, 12, 5, 5, 30, 7), east);
-  EXPECT_EQ("292277026596-12-05T05:30:07+14:00", format(RFC3339, tp, east));
+  EXPECT_EQ("292277026596-12-05T05:30:07+14:00",
+            absl::time_internal::cctz::format(RFC3339, tp, east));
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
   tp = convert(civil_second(292277026596, 12, 5, 5, 30, 8), east);
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
@@ -980,7 +983,8 @@
 
   // Checks that we can also get the maximal value for a far-west zone.
   tp = convert(civil_second(292277026596, 12, 4, 1, 30, 7), west);
-  EXPECT_EQ("292277026596-12-04T01:30:07-14:00", format(RFC3339, tp, west));
+  EXPECT_EQ("292277026596-12-04T01:30:07-14:00",
+            absl::time_internal::cctz::format(RFC3339, tp, west));
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
   tp = convert(civil_second(292277026596, 12, 4, 7, 30, 8), west);
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
@@ -989,9 +993,11 @@
 
   // Approach the minimal time_point<cctz::seconds> value from above.
   tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 53), utc);
-  EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", format(RFC3339, tp, utc));
+  EXPECT_EQ("-292277022657-01-27T08:29:53+00:00",
+            absl::time_internal::cctz::format(RFC3339, tp, utc));
   tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 52), utc);
-  EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", format(RFC3339, tp, utc));
+  EXPECT_EQ("-292277022657-01-27T08:29:52+00:00",
+            absl::time_internal::cctz::format(RFC3339, tp, utc));
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
   tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 51), utc);
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
@@ -1000,7 +1006,8 @@
 
   // Checks that we can also get the minimal value for a far-east zone.
   tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 52), east);
-  EXPECT_EQ("-292277022657-01-27T22:29:52+14:00", format(RFC3339, tp, east));
+  EXPECT_EQ("-292277022657-01-27T22:29:52+14:00",
+            absl::time_internal::cctz::format(RFC3339, tp, east));
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
   tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 51), east);
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
@@ -1009,7 +1016,8 @@
 
   // Checks that we can also get the minimal value for a far-west zone.
   tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 52), west);
-  EXPECT_EQ("-292277022657-01-26T18:29:52-14:00", format(RFC3339, tp, west));
+  EXPECT_EQ("-292277022657-01-26T18:29:52-14:00",
+            absl::time_internal::cctz::format(RFC3339, tp, west));
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
   tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 51), west);
   EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
@@ -1029,14 +1037,16 @@
 #if defined(__FreeBSD__) || defined(__OpenBSD__)
     // The BSD gmtime_r() fails on extreme positive tm_year values.
 #else
-    EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, cut));
+    EXPECT_EQ("2147485547-12-31T23:59:59+00:00",
+              absl::time_internal::cctz::format(RFC3339, tp, cut));
 #endif
     const year_t min_tm_year = year_t{std::numeric_limits<int>::min()} + 1900;
     tp = convert(civil_second(min_tm_year, 1, 1, 0, 0, 0), cut);
 #if defined(__Fuchsia__)
     // Fuchsia's gmtime_r() fails on extreme negative values (fxbug.dev/78527).
 #else
-    EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, cut));
+    EXPECT_EQ("-2147481748-01-01T00:00:00+00:00",
+              absl::time_internal::cctz::format(RFC3339, tp, cut));
 #endif
 #endif
   }
diff --git a/third_party/abseil-cpp/absl/time/time.cc b/third_party/abseil-cpp/absl/time/time.cc
index a11e8e9b..d983c12 100644
--- a/third_party/abseil-cpp/absl/time/time.cc
+++ b/third_party/abseil-cpp/absl/time/time.cc
@@ -66,6 +66,7 @@
              : q - 1;
 }
 
+ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
 inline absl::Time::Breakdown InfiniteFutureBreakdown() {
   absl::Time::Breakdown bd;
   bd.year = std::numeric_limits<int64_t>::max();
@@ -99,6 +100,7 @@
   bd.zone_abbr = "-00";
   return bd;
 }
+ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
 
 inline absl::TimeZone::CivilInfo InfiniteFutureCivilInfo() {
   TimeZone::CivilInfo ci;
@@ -120,6 +122,7 @@
   return ci;
 }
 
+ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
 inline absl::TimeConversion InfiniteFutureTimeConversion() {
   absl::TimeConversion tc;
   tc.pre = tc.trans = tc.post = absl::InfiniteFuture();
@@ -135,6 +138,7 @@
   tc.normalized = true;
   return tc;
 }
+ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
 
 // Makes a Time from sec, overflowing to InfiniteFuture/InfinitePast as
 // necessary. If sec is min/max, then consult cs+tz to check for overflow.
@@ -203,6 +207,7 @@
 // Time
 //
 
+ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
 absl::Time::Breakdown Time::In(absl::TimeZone tz) const {
   if (*this == absl::InfiniteFuture()) return InfiniteFutureBreakdown();
   if (*this == absl::InfinitePast()) return InfinitePastBreakdown();
@@ -227,6 +232,7 @@
   bd.zone_abbr = al.abbr;
   return bd;
 }
+ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
 
 //
 // Conversions from/to other time types.
@@ -398,7 +404,7 @@
 //
 // Conversions involving time zones.
 //
-
+ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
 absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour,
                                      int min, int sec, TimeZone tz) {
   // Avoids years that are too extreme for CivilSecond to normalize.
@@ -430,6 +436,7 @@
   }
   return tc;
 }
+ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
 
 absl::Time FromTM(const struct tm& tm, absl::TimeZone tz) {
   civil_year_t tm_year = tm.tm_year;
diff --git a/third_party/abseil-cpp/absl/time/time.h b/third_party/abseil-cpp/absl/time/time.h
index 29178c7..37580805 100644
--- a/third_party/abseil-cpp/absl/time/time.h
+++ b/third_party/abseil-cpp/absl/time/time.h
@@ -802,8 +802,7 @@
   // `absl::TimeZone`.
   //
   // Deprecated. Use `absl::TimeZone::CivilInfo`.
-  struct
-      Breakdown {
+  struct ABSL_DEPRECATED("Use `absl::TimeZone::CivilInfo`.") Breakdown {
     int64_t year;        // year (e.g., 2013)
     int month;           // month of year [1:12]
     int day;             // day of month [1:31]
@@ -829,7 +828,10 @@
   // Returns the breakdown of this instant in the given TimeZone.
   //
   // Deprecated. Use `absl::TimeZone::At(Time)`.
+  ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
+  ABSL_DEPRECATED("Use `absl::TimeZone::At(Time)`.")
   Breakdown In(TimeZone tz) const;
+  ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
 
   template <typename H>
   friend H AbslHashValue(H h, Time t) {
@@ -1323,8 +1325,7 @@
 // `absl::ConvertDateTime()`. Legacy version of `absl::TimeZone::TimeInfo`.
 //
 // Deprecated. Use `absl::TimeZone::TimeInfo`.
-struct
-    TimeConversion {
+struct ABSL_DEPRECATED("Use `absl::TimeZone::TimeInfo`.") TimeConversion {
   Time pre;    // time calculated using the pre-transition offset
   Time trans;  // when the civil-time discontinuity occurred
   Time post;   // time calculated using the post-transition offset
@@ -1358,8 +1359,11 @@
 //   // absl::ToCivilDay(tc.pre, tz).day() == 1
 //
 // Deprecated. Use `absl::TimeZone::At(CivilSecond)`.
+ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
+ABSL_DEPRECATED("Use `absl::TimeZone::At(CivilSecond)`.")
 TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour,
                                int min, int sec, TimeZone tz);
+ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
 
 // FromDateTime()
 //
@@ -1376,9 +1380,12 @@
 // Deprecated. Use `absl::FromCivil(CivilSecond, TimeZone)`. Note that the
 // behavior of `FromCivil()` differs from `FromDateTime()` for skipped civil
 // times. If you care about that see `absl::TimeZone::At(absl::CivilSecond)`.
-inline Time FromDateTime(int64_t year, int mon, int day, int hour,
-                         int min, int sec, TimeZone tz) {
+ABSL_DEPRECATED("Use `absl::FromCivil(CivilSecond, TimeZone)`.")
+inline Time FromDateTime(int64_t year, int mon, int day, int hour, int min,
+                         int sec, TimeZone tz) {
+  ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
   return ConvertDateTime(year, mon, day, hour, min, sec, tz).pre;
+  ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
 }
 
 // FromTM()
diff --git a/third_party/abseil-cpp/absl/types/BUILD.bazel b/third_party/abseil-cpp/absl/types/BUILD.bazel
index bb80101..b57d3b9 100644
--- a/third_party/abseil-cpp/absl/types/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/types/BUILD.bazel
@@ -77,8 +77,8 @@
         ":any",
         "//absl/base:config",
         "//absl/base:exception_testing",
-        "//absl/base:raw_logging_internal",
         "//absl/container:test_instance_tracker",
+        "//absl/log",
         "@com_google_googletest//:gtest_main",
     ],
 )
@@ -185,7 +185,7 @@
     deps = [
         ":optional",
         "//absl/base:config",
-        "//absl/base:raw_logging_internal",
+        "//absl/log",
         "//absl/meta:type_traits",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
diff --git a/third_party/abseil-cpp/absl/types/BUILD.gn b/third_party/abseil-cpp/absl/types/BUILD.gn
index 210cdbf..a7ab0ab2 100644
--- a/third_party/abseil-cpp/absl/types/BUILD.gn
+++ b/third_party/abseil-cpp/absl/types/BUILD.gn
@@ -96,7 +96,7 @@
   deps = [
     ":optional",
     "//third_party/abseil-cpp/absl/base:config",
-    "//third_party/abseil-cpp/absl/base:raw_logging_internal",
+    "//third_party/abseil-cpp/absl/log",
     "//third_party/abseil-cpp/absl/meta:type_traits",
     "//third_party/abseil-cpp/absl/strings",
   ]
diff --git a/third_party/abseil-cpp/absl/types/CMakeLists.txt b/third_party/abseil-cpp/absl/types/CMakeLists.txt
index 830953ae..c0dcee7 100644
--- a/third_party/abseil-cpp/absl/types/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/types/CMakeLists.txt
@@ -68,7 +68,7 @@
     absl::any
     absl::config
     absl::exception_testing
-    absl::raw_logging_internal
+    absl::log
     absl::test_instance_tracker
     GTest::gmock_main
 )
@@ -220,7 +220,7 @@
   DEPS
     absl::optional
     absl::config
-    absl::raw_logging_internal
+    absl::log
     absl::strings
     absl::type_traits
     GTest::gmock_main
diff --git a/third_party/abseil-cpp/absl/types/any_test.cc b/third_party/abseil-cpp/absl/types/any_test.cc
index d382b92..666ea5b6 100644
--- a/third_party/abseil-cpp/absl/types/any_test.cc
+++ b/third_party/abseil-cpp/absl/types/any_test.cc
@@ -25,8 +25,8 @@
 #include "gtest/gtest.h"
 #include "absl/base/config.h"
 #include "absl/base/internal/exception_testing.h"
-#include "absl/base/internal/raw_logging.h"
 #include "absl/container/internal/test_instance_tracker.h"
+#include "absl/log/log.h"
 
 namespace {
 using absl::test_internal::CopyableOnlyInstance;
@@ -704,7 +704,7 @@
 #ifdef ABSL_HAVE_EXCEPTIONS
     throw BadCopy();
 #else
-    ABSL_RAW_LOG(FATAL, "Bad copy");
+    LOG(FATAL) << "Bad copy";
 #endif
   }
 };
diff --git a/third_party/abseil-cpp/absl/types/optional_test.cc b/third_party/abseil-cpp/absl/types/optional_test.cc
index bd5fe08..5da297b 100644
--- a/third_party/abseil-cpp/absl/types/optional_test.cc
+++ b/third_party/abseil-cpp/absl/types/optional_test.cc
@@ -23,7 +23,7 @@
 
 #include "gtest/gtest.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
 #include "absl/meta/type_traits.h"
 #include "absl/strings/string_view.h"
 
@@ -1542,8 +1542,7 @@
 struct MoveMeNoThrow {
   MoveMeNoThrow() : x(0) {}
   [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {
-    ABSL_RAW_LOG(FATAL, "Should not be called.");
-    abort();
+    LOG(FATAL) << "Should not be called.";
   }
   MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}
   int x;
diff --git a/third_party/abseil-cpp/ci/linux_docker_containers.sh b/third_party/abseil-cpp/ci/linux_docker_containers.sh
index dcaf18b..4dfa317 100644
--- a/third_party/abseil-cpp/ci/linux_docker_containers.sh
+++ b/third_party/abseil-cpp/ci/linux_docker_containers.sh
@@ -17,5 +17,5 @@
 
 readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20201026"
 readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20230217"
-readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20230217"
+readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20230517"
 readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20230120"
diff --git a/third_party/abseil-cpp/symbols_arm64_dbg.def b/third_party/abseil-cpp/symbols_arm64_dbg.def
index 0109cab1..c35120b0 100644
--- a/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -1015,6 +1015,7 @@
     ??$copy@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@__Cr@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEBV234@0PEAV234@@Z
     ??$copy@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@__Cr@std@@YA?AV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@01@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@01@0V201@@Z
     ??$countl_zero@_K@absl@@YAH_K@Z
+    ??$countr_zero@I@absl@@YAHI@Z
     ??$countr_zero@_K@absl@@YAH_K@Z
     ??$destroy@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@XX@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$destroy@PEAUCordRep@cord_internal@absl@@XX@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@__Cr@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@@Z
@@ -2523,6 +2524,8 @@
     ?FromChrono@absl@@YA?AVDuration@1@AEBV?$duration@_JV?$ratio@$00$0PECEA@@__Cr@std@@@chrono@__Cr@std@@@Z
     ?FromChrono@absl@@YA?AVTime@1@AEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$0PECEA@@__Cr@std@@@234@@chrono@__Cr@std@@@Z
     ?FromCivil@absl@@YA?AVTime@1@V?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@1@VTimeZone@1@@Z
+    ?FromHost16@little_endian@absl@@YAGG@Z
+    ?FromHost32@little_endian@absl@@YAII@Z
     ?FromHost64@little_endian@absl@@YA_K_K@Z
     ?FromInt64@time_internal@absl@@YA?AVDuration@2@_JV?$ratio@$0DM@$00@__Cr@std@@@Z
     ?FromInt64@time_internal@absl@@YA?AVDuration@2@_JV?$ratio@$0OBA@$00@__Cr@std@@@Z
@@ -3150,6 +3153,8 @@
     ?StatusMessageAsCStr@absl@@YAPEBDAEBVStatus@1@@Z
     ?StderrThreshold@absl@@YA?AW4LogSeverityAtLeast@1@XZ
     ?SteadyClockNow@KernelTimeout@synchronization_internal@absl@@CA_JXZ
+    ?Store16@little_endian@absl@@YAXPEAXG@Z
+    ?Store32@little_endian@absl@@YAXPEAXI@Z
     ?Store64@little_endian@absl@@YAXPEAX_K@Z
     ?Store@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBVCord@2@@Z@base_internal@absl@@QEAAXP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@3@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBVCord@3@@Z@Z
     ?Store@?$AtomicHook@P6AXPEBDH000@Z@base_internal@absl@@QEAAXP6AXPEBDH000@Z@Z
@@ -3298,6 +3303,8 @@
     ?UnalignedLoad16@base_internal@absl@@YAGPEBX@Z
     ?UnalignedLoad32@base_internal@absl@@YAIPEBX@Z
     ?UnalignedLoad64@base_internal@absl@@YA_KPEBX@Z
+    ?UnalignedStore16@base_internal@absl@@YAXPEAXG@Z
+    ?UnalignedStore32@base_internal@absl@@YAXPEAXI@Z
     ?UnalignedStore64@base_internal@absl@@YAXPEAX_K@Z
     ?UnauthenticatedError@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ?UnavailableError@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
diff --git a/third_party/abseil-cpp/symbols_x64_dbg.def b/third_party/abseil-cpp/symbols_x64_dbg.def
index 8f6c6b5..c9096f2 100644
--- a/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -1016,6 +1016,7 @@
     ??$countl_zero@I@absl@@YAHI@Z
     ??$countl_zero@_K@absl@@YAH_K@Z
     ??$countr_zero@I@absl@@YAHI@Z
+    ??$countr_zero@_K@absl@@YAH_K@Z
     ??$destroy@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@XX@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$destroy@PEAUCordRep@cord_internal@absl@@XX@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@__Cr@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@@Z
     ??$destroy@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@XX@?$allocator_traits@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@SAXAEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
@@ -2523,6 +2524,8 @@
     ?FromChrono@absl@@YA?AVDuration@1@AEBV?$duration@_JV?$ratio@$00$0PECEA@@__Cr@std@@@chrono@__Cr@std@@@Z
     ?FromChrono@absl@@YA?AVTime@1@AEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$0PECEA@@__Cr@std@@@234@@chrono@__Cr@std@@@Z
     ?FromCivil@absl@@YA?AVTime@1@V?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@1@VTimeZone@1@@Z
+    ?FromHost16@little_endian@absl@@YAGG@Z
+    ?FromHost32@little_endian@absl@@YAII@Z
     ?FromHost64@little_endian@absl@@YA_K_K@Z
     ?FromInt64@time_internal@absl@@YA?AVDuration@2@_JV?$ratio@$0DM@$00@__Cr@std@@@Z
     ?FromInt64@time_internal@absl@@YA?AVDuration@2@_JV?$ratio@$0OBA@$00@__Cr@std@@@Z
@@ -3150,6 +3153,9 @@
     ?StatusMessageAsCStr@absl@@YAPEBDAEBVStatus@1@@Z
     ?StderrThreshold@absl@@YA?AW4LogSeverityAtLeast@1@XZ
     ?SteadyClockNow@KernelTimeout@synchronization_internal@absl@@CA_JXZ
+    ?Store16@little_endian@absl@@YAXPEAXG@Z
+    ?Store32@little_endian@absl@@YAXPEAXI@Z
+    ?Store64@little_endian@absl@@YAXPEAX_K@Z
     ?Store@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBVCord@2@@Z@base_internal@absl@@QEAAXP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@3@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBVCord@3@@Z@Z
     ?Store@?$AtomicHook@P6AXPEBDH000@Z@base_internal@absl@@QEAAXP6AXPEBDH000@Z@Z
     ?Store@?$AtomicHook@P6AXPEBDPEBX@Z@base_internal@absl@@QEAAXP6AXPEBDPEBX@Z@Z
@@ -3297,6 +3303,9 @@
     ?UnalignedLoad16@base_internal@absl@@YAGPEBX@Z
     ?UnalignedLoad32@base_internal@absl@@YAIPEBX@Z
     ?UnalignedLoad64@base_internal@absl@@YA_KPEBX@Z
+    ?UnalignedStore16@base_internal@absl@@YAXPEAXG@Z
+    ?UnalignedStore32@base_internal@absl@@YAXPEAXI@Z
+    ?UnalignedStore64@base_internal@absl@@YAXPEAX_K@Z
     ?UnauthenticatedError@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ?UnavailableError@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ?UnextendByZeroes@CRC32@crc_internal@absl@@UEBAXPEAI_K@Z
diff --git a/third_party/abseil-cpp/symbols_x86_dbg.def b/third_party/abseil-cpp/symbols_x86_dbg.def
index 5bab869..2d4be5c 100644
--- a/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -1012,6 +1012,7 @@
     ??$countl_zero@I@absl@@YAHI@Z
     ??$countl_zero@_K@absl@@YAH_K@Z
     ??$countr_zero@I@absl@@YAHI@Z
+    ??$countr_zero@_K@absl@@YAH_K@Z
     ??$destroy@PAPBVImpl@time_zone@cctz@time_internal@absl@@XX@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@SAXAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$destroy@PAUCordRep@cord_internal@absl@@XX@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@__Cr@std@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PAPAUCordRep@cord_internal@absl@@@Z
     ??$destroy@PAUPrefixCrc@CrcCordState@crc_internal@absl@@XX@?$allocator_traits@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@SAXAAV?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
@@ -2513,6 +2514,8 @@
     ?FromChrono@absl@@YA?AVDuration@1@ABV?$duration@_JV?$ratio@$00$0PECEA@@__Cr@std@@@chrono@__Cr@std@@@Z
     ?FromChrono@absl@@YA?AVTime@1@ABV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$0PECEA@@__Cr@std@@@234@@chrono@__Cr@std@@@Z
     ?FromCivil@absl@@YA?AVTime@1@V?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@1@VTimeZone@1@@Z
+    ?FromHost16@little_endian@absl@@YAGG@Z
+    ?FromHost32@little_endian@absl@@YAII@Z
     ?FromHost64@little_endian@absl@@YA_K_K@Z
     ?FromInt64@time_internal@absl@@YA?AVDuration@2@_JV?$ratio@$0DM@$00@__Cr@std@@@Z
     ?FromInt64@time_internal@absl@@YA?AVDuration@2@_JV?$ratio@$0OBA@$00@__Cr@std@@@Z
@@ -3140,6 +3143,9 @@
     ?StatusMessageAsCStr@absl@@YAPBDABVStatus@1@@Z
     ?StderrThreshold@absl@@YA?AW4LogSeverityAtLeast@1@XZ
     ?SteadyClockNow@KernelTimeout@synchronization_internal@absl@@CA_JXZ
+    ?Store16@little_endian@absl@@YAXPAXG@Z
+    ?Store32@little_endian@absl@@YAXPAXI@Z
+    ?Store64@little_endian@absl@@YAXPAX_K@Z
     ?Store@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABVCord@2@@Z@base_internal@absl@@QAEXP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@3@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABVCord@3@@Z@Z
     ?Store@?$AtomicHook@P6AXPBDH000@Z@base_internal@absl@@QAEXP6AXPBDH000@Z@Z
     ?Store@?$AtomicHook@P6AXPBDPBX@Z@base_internal@absl@@QAEXP6AXPBDPBX@Z@Z
@@ -3287,6 +3293,9 @@
     ?UnalignedLoad16@base_internal@absl@@YAGPBX@Z
     ?UnalignedLoad32@base_internal@absl@@YAIPBX@Z
     ?UnalignedLoad64@base_internal@absl@@YA_KPBX@Z
+    ?UnalignedStore16@base_internal@absl@@YAXPAXG@Z
+    ?UnalignedStore32@base_internal@absl@@YAXPAXI@Z
+    ?UnalignedStore64@base_internal@absl@@YAXPAX_K@Z
     ?UnauthenticatedError@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ?UnavailableError@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ?UnextendByZeroes@CRC32@crc_internal@absl@@UBEXPAII@Z
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn
index ca3eb09..5a22582 100644
--- a/third_party/blink/common/BUILD.gn
+++ b/third_party/blink/common/BUILD.gn
@@ -269,6 +269,7 @@
     "scheme_registry.cc",
     "security/address_space_feature.cc",
     "service_worker/service_worker_loader_helpers.cc",
+    "service_worker/service_worker_router_rule_mojom_traits.cc",
     "service_worker/service_worker_scope_match.cc",
     "service_worker/service_worker_status_code.cc",
     "service_worker/service_worker_type_converters.cc",
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 1810e107..cd0b2a4 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -147,9 +147,9 @@
 // content.
 BASE_FEATURE(kExcludeLowEntropyImagesFromLCP,
              "ExcludeLowEntropyImagesFromLCP",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 const base::FeatureParam<double> kMinimumEntropyForLCP{
-    &kExcludeLowEntropyImagesFromLCP, "min_bpp", 2};
+    &kExcludeLowEntropyImagesFromLCP, "min_bpp", 0.05};
 
 BASE_FEATURE(kGMSCoreEmoji, "GMSCoreEmoji", base::FEATURE_ENABLED_BY_DEFAULT);
 
@@ -633,6 +633,81 @@
                                    ForceDarkImageClassifier::kUseBlinkSettings,
                                    &forcedark_image_classifier_policy_options};
 
+// Enable service worker warming-up feature. (https://crbug.com/1431792)
+BASE_FEATURE(kSpeculativeServiceWorkerWarmUp,
+             "SpeculativeServiceWorkerWarmUp",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+// If true, do not actually warm-up service workers.
+const base::FeatureParam<bool> kSpeculativeServiceWorkerWarmUpDryRun{
+    &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_dry_run", false};
+
+// kSpeculativeServiceWorkerWarmUp observes anchor events such as visibility,
+// pointerover, and pointerdown. These events could be triggered very often. To
+// reduce the frequency of processing, kSpeculativeServiceWorkerWarmUp uses a
+// timer to batch URL candidates together for this amount of duration.
+const base::FeatureParam<base::TimeDelta>
+    kSpeculativeServiceWorkerWarmUpBatchTimer{&kSpeculativeServiceWorkerWarmUp,
+                                              "sw_warm_up_batch_timer",
+                                              base::Milliseconds(100)};
+
+// kSpeculativeServiceWorkerWarmUp warms up service workers up to this max
+// count.
+const base::FeatureParam<int> kSpeculativeServiceWorkerWarmUpMaxCount{
+    &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_max_count", 10};
+
+// kSpeculativeServiceWorkerWarmUp remembers recent warm-up requests to prevent
+// excessive duplicate warm-up. The following cache size is the cache size for
+// duplicated request checks.
+const base::FeatureParam<int> kSpeculativeServiceWorkerWarmUpRequestCacheSize{
+    &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_request_cache_size", 1000};
+
+// kSpeculativeServiceWorkerWarmUp enqueues navigation candidate URLs. This is
+// the queue length of the candidate URLs.
+const base::FeatureParam<int> kSpeculativeServiceWorkerWarmUpRequestQueueLength{
+    &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_request_queue_length", 1000};
+
+// kSpeculativeServiceWorkerWarmUp accept requests of navigation candidate URLs.
+// This is the request count limit per document.
+const base::FeatureParam<int> kSpeculativeServiceWorkerWarmUpRequestLimit{
+    &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_request_limit", 1000};
+
+// Duration to keep worker warmed-up.
+const base::FeatureParam<base::TimeDelta>
+    kSpeculativeServiceWorkerWarmUpDuration{&kSpeculativeServiceWorkerWarmUp,
+                                            "sw_warm_up_duration",
+                                            base::Minutes(10)};
+// Duration to re-warmup service worker. This duration must be shorter than
+// sw_warm_up_duration.
+const base::FeatureParam<base::TimeDelta>
+    kSpeculativeServiceWorkerWarmUpReWarmUpThreshold{
+        &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_re_warm_up_threshold",
+        base::Minutes(7)};
+
+// Enable IntersectionObserver to detect anchor's visibility.
+const base::FeatureParam<bool>
+    kSpeculativeServiceWorkerWarmUpIntersectionObserver{
+        &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_intersection_observer",
+        true};
+
+// Duration from previous IntersectionObserver event to the next event.
+const base::FeatureParam<int>
+    kSpeculativeServiceWorkerWarmUpIntersectionObserverDelay{
+        &kSpeculativeServiceWorkerWarmUp,
+        "sw_warm_up_intersection_observer_delay", 100};
+
+// Warms up service workers when the anchor becomes visible.
+const base::FeatureParam<bool> kSpeculativeServiceWorkerWarmUpOnVisible{
+    &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_on_visible", true};
+
+// Warms up service workers when a pointerover event is triggered on an anchor.
+const base::FeatureParam<bool> kSpeculativeServiceWorkerWarmUpOnPointerover{
+    &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_on_pointerover", true};
+
+// Warms up service workers when a pointerdown event is triggered on an anchor.
+const base::FeatureParam<bool> kSpeculativeServiceWorkerWarmUpOnPointerdown{
+    &kSpeculativeServiceWorkerWarmUp, "sw_warm_up_on_pointerdown", true};
+
 // Instructs WebRTC to honor the Min/Max Video Encode Accelerator dimensions.
 BASE_FEATURE(kWebRtcUseMinMaxVEADimensions,
              "WebRtcUseMinMaxVEADimensions",
diff --git a/third_party/blink/common/input/web_coalesced_input_event_mojom_traits.cc b/third_party/blink/common/input/web_coalesced_input_event_mojom_traits.cc
index 1adbb11..75880d5 100644
--- a/third_party/blink/common/input/web_coalesced_input_event_mojom_traits.cc
+++ b/third_party/blink/common/input/web_coalesced_input_event_mojom_traits.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/containers/contains.h"
-#include "base/i18n/char_iterator.h"
+#include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "mojo/public/cpp/base/time_mojom_traits.h"
 #include "third_party/blink/public/common/input/web_gesture_event.h"
@@ -19,16 +19,6 @@
 namespace mojo {
 namespace {
 
-void CopyString(char16_t* dst, const std::u16string& text) {
-  size_t pos = 0;
-  for (base::i18n::UTF16CharIterator iter(text);
-       !iter.end() && pos < blink::WebKeyboardEvent::kTextLengthCap - 1;
-       iter.Advance()) {
-    dst[pos++] = iter.get();
-  }
-  dst[pos] = '\0';
-}
-
 blink::mojom::PointerDataPtr PointerDataFromPointerProperties(
     const blink::WebPointerProperties& pointer,
     blink::mojom::MouseDataPtr mouse_data) {
@@ -118,8 +108,11 @@
     key_event->dom_key = key_data->dom_key;
     key_event->is_system_key = key_data->is_system_key;
     key_event->is_browser_shortcut = key_data->is_browser_shortcut;
-    CopyString(key_event->text, key_data->text);
-    CopyString(key_event->unmodified_text, key_data->unmodified_text);
+    base::u16cstrlcpy(key_event->text, key_data->text.c_str(),
+                      blink::WebKeyboardEvent::kTextLengthCap);
+    base::u16cstrlcpy(key_event->unmodified_text,
+                      key_data->unmodified_text.c_str(),
+                      blink::WebKeyboardEvent::kTextLengthCap);
   } else if (blink::WebInputEvent::IsGestureEventType(type)) {
     blink::mojom::GestureDataPtr gesture_data;
     if (!event.ReadGestureData<blink::mojom::GestureDataPtr>(&gesture_data))
diff --git a/third_party/blink/common/origin_trials/persistent_origin_trials.cc b/third_party/blink/common/origin_trials/persistent_origin_trials.cc
index 71026a0..4c1c0bb 100644
--- a/third_party/blink/common/origin_trials/persistent_origin_trials.cc
+++ b/third_party/blink/common/origin_trials/persistent_origin_trials.cc
@@ -19,6 +19,7 @@
       // tests.
       "FrobulatePersistent",
       "FrobulatePersistentExpiryGracePeriod",
+      "FrobulatePersistentInvalidOS",
       "FrobulatePersistentThirdPartyDeprecation",
       // Production persistent origin trials follow below:
       "WebViewXRequestedWithDeprecation",
diff --git a/third_party/blink/common/origin_trials/trial_token_validator.cc b/third_party/blink/common/origin_trials/trial_token_validator.cc
index 73c89d2..60c7e0e9 100644
--- a/third_party/blink/common/origin_trials/trial_token_validator.cc
+++ b/third_party/blink/common/origin_trials/trial_token_validator.cc
@@ -13,6 +13,7 @@
 #include "net/http/http_response_headers.h"
 #include "net/url_request/url_request.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/common/origin_trials/origin_trial_policy.h"
 #include "third_party/blink/public/common/origin_trials/origin_trials.h"
 #include "third_party/blink/public/common/origin_trials/trial_token.h"
@@ -309,6 +310,29 @@
   return status == OriginTrialTokenStatus::kSuccess;
 }
 
+std::vector<OriginTrialFeature> TrialTokenValidator::FeaturesEnabledByTrial(
+    base::StringPiece trial_name) {
+  std::vector<OriginTrialFeature> enabled_features;
+  base::span<const OriginTrialFeature> features =
+      origin_trials::FeaturesForTrial(trial_name);
+  for (const OriginTrialFeature feature : features) {
+    if (origin_trials::FeatureEnabledForOS(feature)) {
+      enabled_features.push_back(feature);
+      // Also add implied features
+      for (const OriginTrialFeature implied_feature :
+           origin_trials::GetImpliedFeatures(feature)) {
+        enabled_features.push_back(implied_feature);
+      }
+    }
+  }
+  return enabled_features;
+}
+
+bool TrialTokenValidator::TrialEnablesFeaturesForOS(
+    base::StringPiece trial_name) {
+  return !FeaturesEnabledByTrial(trial_name).empty();
+}
+
 bool TrialTokenValidator::RequestEnablesFeature(const net::URLRequest* request,
                                                 base::StringPiece feature_name,
                                                 base::Time current_time) const {
diff --git a/third_party/blink/common/permissions_policy/permissions_policy.cc b/third_party/blink/common/permissions_policy/permissions_policy.cc
index a026dcc..11c54337 100644
--- a/third_party/blink/common/permissions_policy/permissions_policy.cc
+++ b/third_party/blink/common/permissions_policy/permissions_policy.cc
@@ -468,45 +468,45 @@
   return IsFeatureEnabledForOriginImpl(feature, origin, opt_in_features);
 }
 
-// Implements Permissions Policy 9.7: Define an inherited policy for feature in
-// browsing context and 9.8: Define an inherited policy for feature in container
-// at origin.
+// Implements Permissions Policy 9.7: Define an inherited policy for
+// feature in container at origin.
+// Version https://www.w3.org/TR/2023/WD-permissions-policy-1-20230322/
 bool PermissionsPolicy::InheritedValueForFeature(
     const PermissionsPolicy* parent_policy,
     std::pair<mojom::PermissionsPolicyFeature, PermissionsPolicyFeatureDefault>
         feature,
     const ParsedPermissionsPolicy& container_policy) const {
-  // 9.7 2: Otherwise [If context is not a nested browsing context,] return
-  // "Enabled".
+  // 9.7 1: If container is null, return "Enabled".
   if (!parent_policy)
     return true;
 
-  // 9.8 2: If feature was inherited and (if declared) the allowlist for the
-  // feature does not match the parent's origin, then return "Disabled".
+  // 9.7 2: If the result of executing Is feature enabled in document for origin
+  // on feature, container’s node document, and container’s node document's
+  // origin is "Disabled", return "Disabled".
   if (!parent_policy->GetFeatureValueForOrigin(feature.first,
                                                parent_policy->origin_))
     return false;
 
-  // 9.8 3: If feature was inherited and (if declared) the allowlist for the
+  // 9.7 3: If feature was inherited and (if declared) the allowlist for the
   // feature does not match origin, then return "Disabled".
   if (!parent_policy->GetFeatureValueForOrigin(feature.first, origin_))
     return false;
 
   for (const auto& decl : container_policy) {
     if (decl.feature == feature.first) {
-      // 9.8 5.1: If the allowlist for feature in container policy matches
+      // 9.7 5.1: If the allowlist for feature in container policy matches
       // origin, return "Enabled".
-      // 9.8 5.2: Otherwise return "Disabled".
+      // 9.7 5.2: Otherwise return "Disabled".
       return AllowlistFromDeclaration(decl).Contains(origin_);
     }
   }
-  // 9.8 6: If feature’s default allowlist is *, return "Enabled".
+  // 9.7 6: If feature’s default allowlist is *, return "Enabled".
   if (feature.second == PermissionsPolicyFeatureDefault::EnableForAll)
     return true;
 
-  // 9.8 7: If feature’s default allowlist is 'self', and origin is same origin
+  // 9.7 7: If feature’s default allowlist is 'self', and origin is same origin
   // with container’s node document’s origin, return "Enabled".
-  // 9.8 8: Otherwise return "Disabled".
+  // 9.7 8: Otherwise return "Disabled".
   return origin_.IsSameOriginWith(parent_policy->origin_);
 }
 
diff --git a/third_party/blink/common/service_worker/OWNERS b/third_party/blink/common/service_worker/OWNERS
index c07cce4c..8622fb20 100644
--- a/third_party/blink/common/service_worker/OWNERS
+++ b/third_party/blink/common/service_worker/OWNERS
@@ -2,3 +2,5 @@
 
 per-file *_type_converter*.*=set noparent
 per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/common/service_worker/service_worker_router_rule_mojom_traits.cc b/third_party/blink/common/service_worker/service_worker_router_rule_mojom_traits.cc
new file mode 100644
index 0000000..f477e6ca
--- /dev/null
+++ b/third_party/blink/common/service_worker/service_worker_router_rule_mojom_traits.cc
@@ -0,0 +1,80 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/public/common/service_worker/service_worker_router_rule_mojom_traits.h"
+
+namespace mojo {
+
+blink::mojom::ServiceWorkerRouterConditionDataView::Tag
+UnionTraits<blink::mojom::ServiceWorkerRouterConditionDataView,
+            blink::ServiceWorkerRouterCondition>::
+    GetTag(const blink::ServiceWorkerRouterCondition& data) {
+  switch (data.type) {
+    case blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern:
+      return blink::mojom::ServiceWorkerRouterCondition::Tag::kUrlPattern;
+  }
+  NOTREACHED_NORETURN();
+}
+
+bool UnionTraits<blink::mojom::ServiceWorkerRouterConditionDataView,
+                 blink::ServiceWorkerRouterCondition>::
+    Read(blink::mojom::ServiceWorkerRouterConditionDataView data,
+         blink::ServiceWorkerRouterCondition* out) {
+  switch (data.tag()) {
+    case blink::mojom::ServiceWorkerRouterCondition::Tag::kUrlPattern:
+      if (!data.ReadUrlPattern(&out->url_pattern)) {
+        return false;
+      }
+      return true;
+  }
+
+  return false;
+}
+
+blink::mojom::ServiceWorkerRouterSourceDataView::Tag
+UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView,
+            blink::ServiceWorkerRouterSource>::
+    GetTag(const blink::ServiceWorkerRouterSource& data) {
+  switch (data.type) {
+    case blink::ServiceWorkerRouterSource::SourceType::kNetwork:
+      return blink::mojom::ServiceWorkerRouterSource::Tag::kNetworkSource;
+  }
+  NOTREACHED_NORETURN();
+}
+
+bool UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView,
+                 blink::ServiceWorkerRouterSource>::
+    Read(blink::mojom::ServiceWorkerRouterSourceDataView data,
+         blink::ServiceWorkerRouterSource* out) {
+  switch (data.tag()) {
+    case blink::mojom::ServiceWorkerRouterSource::Tag::kNetworkSource:
+      return true;
+  }
+  return false;
+}
+
+bool StructTraits<blink::mojom::ServiceWorkerRouterRuleDataView,
+                  blink::ServiceWorkerRouterRule>::
+    Read(blink::mojom::ServiceWorkerRouterRuleDataView data,
+         blink::ServiceWorkerRouterRule* out) {
+  if (!data.ReadConditions(&out->conditions)) {
+    return false;
+  }
+  if (!data.ReadSources(&out->sources)) {
+    return false;
+  }
+  return true;
+}
+
+bool StructTraits<blink::mojom::ServiceWorkerRouterRulesDataView,
+                  blink::ServiceWorkerRouterRules>::
+    Read(blink::mojom::ServiceWorkerRouterRulesDataView data,
+         blink::ServiceWorkerRouterRules* out) {
+  if (!data.ReadRules(&out->rules)) {
+    return false;
+  }
+  return true;
+}
+
+}  // namespace mojo
diff --git a/third_party/blink/perf_tests/MotionMark/OWNERS b/third_party/blink/perf_tests/MotionMark/OWNERS
new file mode 100644
index 0000000..6e76689f
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/OWNERS
@@ -0,0 +1,3 @@
+yiyix@chromium.org
+junov@chromium.org
+sky@chromium.org
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/MotionMark/README.md b/third_party/blink/perf_tests/MotionMark/README.md
new file mode 100644
index 0000000..4adab54
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/README.md
@@ -0,0 +1,7 @@
+This folder is copy from PerformanceTests folder in webkit's repo
+(https://github.com/WebKit/webkit/tree/master/PerformanceTests).
+
+Revision: 4b28b98d37306eb5ae9ab8bca504590295f64210
+This is a temporary solution for Chrome to contribute to MotionMark tests
+before Webkit moves it to a separate project. "no-check" is added to bypass
+Chromium PRESUBMIT.
diff --git a/third_party/blink/perf_tests/MotionMark/about.html b/third_party/blink/perf_tests/MotionMark/about.html
new file mode 100644
index 0000000..5881f7ab
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/about.html
@@ -0,0 +1,93 @@
+<!--
+  Copyright (C) 2015-2020 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no">
+
+    <title>About MotionMark</title>
+
+    <link rel="stylesheet" href="resources/runner/motionmark.css">
+
+    <script src="resources/strings.js"></script>
+</head>
+<body class="images-loaded">
+    <main>
+    <section id="about" class="selected">
+        <div class="logo"><svg><use xlink:href="resources/runner/logo.svg#root" /></svg></div>
+
+        <div class="body">
+            <h1>About MotionMark <span class="version"></span></h1>
+
+            <p>MotionMark is a web benchmark that focuses on graphics performance. It draws multiple rendering elements, each of which uses the same set of graphics primitives. An element could be an SVG node, an HTML element with CSS style, or a series of canvas operations. Slight variations among the elements avoid trivial caching optimizations by the browser. Although fairly simple, the effects were chosen to reflect techniques commonly used on the web. Tests are visually rich, being designed to stress the graphics system rather than JavaScript.</p>
+
+            <p>After an initial warm-up, each test runs for a fixed period of time. Based on measurements of the browser’s frame rate, MotionMark adjusts the number of elements to draw, and concentrates around a narrow range where the browser starts to fail animating at 60 frames per second (fps). A piecewise linear regression is applied to the data, and the change point is reported as the test's score. The confidence interval is calculated through <a href="https://en.wikipedia.org/wiki/Bootstrapping_(statistics)">bootstrapping</a>. MotionMark calculates the geometric mean of all of the tests’ scores to report the single score for the run.</p>
+
+            <p>MotionMark can be run on a wide variety of devices. Using the device’s screen dimensions it adjusts the drawing area into one of three sizes:</p>
+
+            <ol>
+                <li>Small (568 x 320), targeted at mobile phones</li>
+                <li>Medium (900 x 600), targeted at tablets and laptops</li>
+                <li>Large (1600 x 800), targeted at desktops</li>
+            </ol>
+
+            <p>The design of the benchmark is modular. This makes it easy to write new tests and use different controllers, which can assist a developer working on improving the performance of a web engine. For the purpose of a public benchmark, the MotionMark main suite tests a variety of drawing operations using techniques including CSS, SVG, and Canvas:</p> <!-- nocheck -->
+
+            <ul>
+                <li><strong>Multiply</strong>: CSS border radius, transforms, opacity</li>
+                <li><strong>Arcs and Fills</strong>: Canvas path fills and arcs</li>
+                <li><strong>Leaves</strong>: CSS-transformed elements, opacity</li>
+                <li><strong>Paths</strong>: Canvas line, quadratic, and Bezier paths</li>
+                <li><strong>Lines</strong>: Canvas line segments</li>
+                <li><strong>Focus</strong>: CSS blur filter, opacity</li>
+                <li><strong>Images</strong>: Canvas <code>getImageData()</code> and <code>putImageData()</code></li>
+                <li><strong>Design</strong>: HTML text rendering</li>
+                <li><strong>Suits</strong>: SVG clip paths, gradients and transforms</li>
+            </ul>
+
+            <p>To achieve consistent results on mobile devices, put the device in landscape orientation. On laptops and desktops, use the default display resolution and make the browser window fullscreen. Make sure that screen automatic display sleep is turned off or set to longer than 8 minutes.</p>
+
+            <h3>Version log</h3>
+
+            <ul id="log">
+                <li><strong>1.3</strong>: Add support for non-60Hz <code>requestAnimationFrame</code> rates to the <a href="developer.html">developer settings</a>.</li>
+                <li><strong>1.2</strong>: Fix <a href="https://bugs.webkit.org/show_bug.cgi?id=220847">bug</a>, <a href="https://bugs.webkit.org/show_bug.cgi?id=221075">bug</a>, and <a href="https://bugs.webkit.org/show_bug.cgi?id=219984">bug</a> to reduce test variance and sensitivity to individual long frames.</li>
+                <li><strong>1.1.1</strong>: Fix <a href="https://bugs.webkit.org/show_bug.cgi?id=210640">bug</a> in the calculation of timestamps used for animation during warm up phase of tests.</li>
+                <li><a href="https://webkit.org/blog/8434/motionmark-1-1/"><strong>1.1</strong></a>: Update Multiply test to increase max capacity and expand methods for hiding elements. Update Leaves test to use range of sizes and opacity.</li>
+                <li><a href="https://webkit.org/blog/6943/motionmark-a-new-graphics-benchmark/"><strong>1.0</strong></a>: Initial release.</li>
+            </ul>
+
+            <center><button onclick="location.href='./'">Return to homepage</button></center>
+        </div>
+        </section>
+    </main>
+
+    <script>
+        document.title = "About MotionMark " + Strings.version;
+        document.querySelector(".version").textContent = Strings.version;
+    </script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/developer.html b/third_party/blink/perf_tests/MotionMark/developer.html
new file mode 100644
index 0000000..e00d274d
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/developer.html
@@ -0,0 +1,210 @@
+<!--
+  Copyright (C) 2015-2020 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no">
+
+    <title>MotionMark developer</title>
+
+    <link rel="stylesheet" href="resources/runner/motionmark.css">
+    <link rel="stylesheet" href="resources/debug-runner/motionmark.css">
+
+    <script src="resources/strings.js"></script>
+    <script src="resources/extensions.js"></script>
+    <script src="resources/statistics.js"></script>
+
+    <script src="resources/runner/tests.js" charset="utf-8"></script>
+    <script src="resources/debug-runner/tests.js" charset="utf-8"></script>
+    <script src="resources/runner/motionmark.js"></script>
+    <script src="resources/debug-runner/motionmark.js" charset="utf-8"></script>
+
+    <script src="resources/runner/benchmark-runner.js"></script>
+    <script src="resources/debug-runner/d3.min.js"></script>
+    <script src="resources/debug-runner/graph.js" charset="utf-8"></script>
+</head>
+<body class="showing-intro">
+    <main>
+        <section id="intro" class="selected">
+            <header>
+                <h1>MotionMark</h1>
+                <h2>version <span class="version"></span></h2>
+            </header>
+            <div class="body">
+                <div>
+                    <div id="suites">
+                        <h2>Suites:</h2>
+                        <ul class="tree"></ul>
+                        <div><span id="drop-target">Drop results here</span></div>
+                    </div>
+                    <div id="options">
+                        <h2>Options:</h2>
+                        <form name="benchmark-options">
+                            <ul>
+                                <li>
+                                    <label>Warmup length: <input type="number" id="warmup-length" value="2000"> milliseconds</label>
+                                </li>
+                                <li>
+                                    <label>Warmup frame count: <input type="number" id="warmup-frame-count" value="30"> frames</label>
+                                </li>
+                                <li>
+                                    <label>First frame minimum length: <input type="number" id="first-frame-minimum-length" value="0"> ms</label>
+                                </li>
+                                <li>
+                                    <label>Test length: <input type="number" id="test-interval" value="30"> seconds each</label>
+                                </li>
+                                <li>
+                                    <h3>Display:</h3>
+                                    <ul>
+                                        <li><label><input name="display" type="radio" value="minimal" checked> Minimal</label></li>
+                                        <li><label><input name="display" type="radio" value="progress-bar"> Progress bar</label></li>
+                                    </ul>
+                                </li>
+                                <li>
+                                    <h3>Tiles:</h3>
+                                    <ul>
+                                        <li><label><input name="tiles" type="radio" value="big" checked> Big tiles</label></li>
+                                        <li><label><input name="tiles" type="radio" value="classic"> Classic tiles (512x512)</label></li>
+                                    </ul>
+                                </li>
+                                <li>
+                                    <h3>Adjusting the test complexity:</h3>
+                                    <ul>
+                                        <li><label><input name="controller" type="radio" value="ramp" checked> Ramp</label></li>
+                                        <li><label><input name="controller" type="radio" value="fixed"> Keep at a fixed complexity</label></li>
+                                        <li><label><input name="controller" type="radio" value="adaptive"> Maintain target FPS</label></li>
+                                    </ul>
+                                </li>
+                                <li>
+                                    <label>System frame rate: <input type="number" id="system-frame-rate" value="60"> FPS</label><br>
+                                    <label>Target frame rate: <input type="number" id="frame-rate" value="50"> FPS</label><br>
+                                    (Guide: should be about 5/6th of the system frame rate)
+                                </li>
+                                <li>
+                                    <h3>Time measurement method:</h3>
+                                    <ul>
+                                        <li><label><input name="time-measurement" type="radio" value="performance" checked> <code>performance.now()</code> (if available)</label></li>
+                                        <li><label><input name="time-measurement" type="radio" value="raf"> <code>requestAnimationFrame()</code> timestamp</label></li>
+                                        <li><label><input name="time-measurement" type="radio" value="date"> <code>Date.now()</code></label></li>
+                                    </ul>
+                                </li>
+                            </ul>
+                        </form>
+                    </div>
+                </div>
+                <p>
+                    For accurate results, please take the browser window full screen, or rotate the device to landscape orientation. Also,
+                    ensure that the target frame rate matches your system frame rate. Results cannot be compared between devices that
+                    use different frame rates.
+                </p>
+                <p id="frame-rate-detection">
+                    Attempting to detect system frame rate: <span>0</span> FPS (in progress).
+                </p>
+                <div class="start-benchmark">
+                    <p class="hidden">Please rotate the device to orientation before starting.</p>
+                    <button id="run-benchmark" onclick="benchmarkController.startBenchmark()">Run benchmark</button>
+                </div>
+            </div>
+        </section>
+
+        <section id="test-container">
+            <div id="running-test" class="frame-container"></div>
+            <div id="progress">
+                <div id="progress-completed"></div>
+            </div>
+        </section>
+
+        <section id="results">
+            <div class="body">
+                <h1>MotionMark score</h1>
+                <div class="detail">
+                    <span class="small">on a small screen (phone)</span>
+                    <span class="medium">on a medium screen (laptop, tablet)</span>
+                    <span class="large">on a large screen (desktop)</span>
+                </div>
+                <div>version <span class="version"></span></div>
+                <p class="score" onclick="benchmarkController.showDebugInfo()"></p>
+                <p class="confidence"></p>
+                <div id="results-tables" class="table-container">
+                    <div>
+                        <table id="results-score"></table>
+                        <table id="results-data"></table>
+                    </div>
+                    <table id="results-header"></table>
+                </div>
+                <button onclick="benchmarkController.restartBenchmark()">Test Again</button>
+                <p>
+                    'j': Show JSON results<br/>
+                    's': Select various results for copy/paste (use repeatedly to cycle)
+                </p>
+            </div>
+        </section>
+        <section id="test-graph">
+            <div class="body">
+                <header>
+                    <button onclick="benchmarkController.showResults()">&lt; Results</button>
+                    <h1>Graph:</h1>
+                    <p class="score"></p>
+                    <p class="confidence"></p>
+                </header>
+                <nav>
+                    <form name="graph-type">
+                        <ul>
+                            <li><label><input type="radio" name="graph-type" value="time"> Time graph</label></li>
+                            <li><label><input type="radio" name="graph-type" value="complexity" checked> Complexity graph</label></li>
+                        </ul>
+                    </form>
+                    <form name="time-graph-options">
+                        <ul>
+                            <li><label><input type="checkbox" name="markers" checked> Markers</label>
+                                <span>time: <span class="time"></span></span></li>
+                            <li><label><input type="checkbox" name="averages" checked> Averages</label></li>
+                            <li><label><input type="checkbox" name="complexity" checked> Complexity</label>
+                                <span class="complexity"></span></li>
+                            <li><label><input type="checkbox" name="rawFPS" checked> Raw FPS</label>
+                                <span class="rawFPS"></span></li>
+                            <li><label><input type="checkbox" name="filteredFPS" checked> Filtered FPS</label>
+                                <span class="filteredFPS"></span></li>
+                            <li><label><input type="checkbox" name="regressions" checked> Regressions</label></li>
+                        </ul>
+                    </form>
+                    <form name="complexity-graph-options">
+                        <ul class="series">
+                            <li><label><input type="checkbox" name="series-raw" checked> Series raw</label></li>
+                        </ul>
+                        <ul>
+                            <li><label><input type="checkbox" name="regression-time-score"> Controller score</label></li>
+                            <li><label><input type="checkbox" name="bootstrap-score" checked> Bootstrap score and histogram</label></li>
+                            <li><label><input type="checkbox" name="complexity-regression-aggregate-raw" checked> Regression, series raw</label><span id="complexity-regression-aggregate-raw"></span></li>
+                        </ul>
+                    </form>
+                </nav>
+                <div id="test-graph-data"></div>
+            </div>
+        </section>
+    </main>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/index.html b/third_party/blink/perf_tests/MotionMark/index.html
new file mode 100644
index 0000000..876e0de
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/index.html
@@ -0,0 +1,97 @@
+<!--
+  Copyright (C) 2015-2018 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no">
+
+    <title>MotionMark</title>
+
+    <link rel="stylesheet" href="resources/runner/motionmark.css">
+
+    <script src="resources/strings.js" defer></script>
+    <script src="resources/extensions.js" defer></script>
+    <script src="resources/statistics.js" defer></script>
+
+    <script src="resources/runner/tests.js" charset="utf-8" defer></script>
+    <script src="resources/runner/motionmark.js" defer></script>
+
+    <script src="resources/runner/benchmark-runner.js" defer></script>
+
+    <script>
+        window.addEventListener("load", function() {
+            // Start the fade in animation.
+            document.body.classList.add("images-loaded");
+        });
+    </script>
+</head>
+<body class="showing-intro">
+    <main>
+        <section id="intro" class="selected">
+            <div class="logo">
+              <svg><use xlink:href="resources/runner/logo.svg#root" /></svg>
+              <div>version <span class="version"></span></div>
+            </div>
+            <div class="body">
+                <p>MotionMark is a graphics benchmark that measures a browser’s capability to animate complex scenes at a target frame rate.</p>
+
+                <p><a href="about.html">More details</a> about the benchmark are available. Bigger scores are better.</p>
+                <p>For accurate results, please take your browser window full screen, or rotate your device to landscape orientation.</p>
+                <p class="portrait-orientation-check"><b>Please rotate your device.</b></p>
+                <button class="landscape-orientation-check" onclick="benchmarkController.startBenchmark()">Run Benchmark</button>
+            </div>
+        </section>
+
+        <section id="test-container" class="frame-container"></section>
+
+        <section id="results">
+            <div class="logo">
+              <svg><use xlink:href="resources/runner/logo.svg#root" /></svg>
+              <div>version <span class="version"></span></div>
+            </div>
+            <div class="body">
+                <div class="score-container">
+                    <div class="score"></div>
+                    <div class="confidence"></div>
+                    <div class="detail">
+                        <span class="small">on a small screen (phone)</span>
+                        <span class="medium">on a medium screen (laptop, tablet)</span>
+                        <span class="large">on a large screen (desktop)</span>
+                    </div>
+                </div>
+                <div class="table-container">
+                    <div>
+                        <table id="results-score"></table>
+                        <table id="results-data"></table>
+                    </div>
+                    <table id="results-header"></table>
+                </div>
+                <button onclick="benchmarkController.startBenchmark()">Test Again</button>
+            </div>
+        </section>
+    </main>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/resources/debug-runner/d3.min.js b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/d3.min.js
new file mode 100644
index 0000000..1a7ae90
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/d3.min.js
@@ -0,0 +1,5 @@
+!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null!=n&&!isNaN(n)}function e(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(t[i],e)<0?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;n(t[i],e)>0?u=i:r=i+1}return r}}}function r(n){return n.length}function u(n){for(var t=1;n*t%1;)t*=10;return t}function i(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function o(){}function a(n){return ia+n in this}function c(n){return n=ia+n,n in this&&delete this[n]}function s(){var n=[];return this.forEach(function(t){n.push(t)}),n}function l(){var n=0;for(var t in this)t.charCodeAt(0)===oa&&++n;return n}function f(){for(var n in this)if(n.charCodeAt(0)===oa)return!1;return!0}function h(){}function g(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function p(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=aa.length;r>e;++e){var u=aa[e]+t;if(u in n)return u}}function v(){}function d(){}function m(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 o;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 y(){Zo.event.preventDefault()}function x(){for(var n,t=Zo.event;n=t.sourceEvent;)t=n;return t}function M(n){for(var t=new d,e=0,r=arguments.length;++e<r;)t[arguments[e]]=m(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Zo.event;u.target=n,Zo.event=u,t[u.type].apply(e,r)}finally{Zo.event=i}}},t}function _(n){return sa(n,pa),n}function b(n){return"function"==typeof n?n:function(){return la(n,this)}}function w(n){return"function"==typeof n?n:function(){return fa(n,this)}}function S(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=Zo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function k(n){return n.trim().replace(/\s+/g," ")}function E(n){return new RegExp("(?:^|\\s+)"+Zo.requote(n)+"(?:\\s+|$)","g")}function A(n){return(n+"").trim().split(/^|\s+/)}function C(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=A(n).map(N);var u=n.length;return"function"==typeof t?r:e}function N(n){var t=E(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",k(u+" "+n))):e.setAttribute("class",k(u.replace(t," ")))}}function z(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 L(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 T(n){return"function"==typeof n?n:(n=Zo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function q(n){return{__data__:n}}function R(n){return function(){return ga(this,n)}}function D(t){return arguments.length||(t=n),function(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}}function P(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 U(n){return sa(n,da),n}function j(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 H(){var n=this.__transition__;n&&++n.active}function F(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Xo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Zo.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=O;a>0&&(n=n.substring(0,a));var s=ya.get(n);return s&&(n=s,c=Y),a?t?u:r:t?v:i}function O(n,t){return function(e){var r=Zo.event;Zo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Zo.event=r}}}function Y(n,t){var e=O(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function I(){var n=".dragsuppress-"+ ++Ma,t="click"+n,e=Zo.select(Wo).on("touchmove"+n,y).on("dragstart"+n,y).on("selectstart"+n,y);if(xa){var r=Bo.style,u=r[xa];r[xa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),xa&&(r[xa]=u),i&&(e.on(t,function(){y(),o()},!0),setTimeout(o,0))}}function Z(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>_a&&(Wo.scrollX||Wo.scrollY)){e=Zo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();_a=!(u.f||u.e),e.remove()}return _a?(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 V(){return Zo.event.changedTouches[0].identifier}function X(){return Zo.event.target}function $(){return Wo}function B(n){return n>0?1:0>n?-1:0}function W(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function J(n){return n>1?0:-1>n?ba:Math.acos(n)}function G(n){return n>1?Sa:-1>n?-Sa:Math.asin(n)}function K(n){return((n=Math.exp(n))-1/n)/2}function Q(n){return((n=Math.exp(n))+1/n)/2}function nt(n){return((n=Math.exp(2*n))-1)/(n+1)}function tt(n){return(n=Math.sin(n/2))*n}function et(){}function rt(n,t,e){return this instanceof rt?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof rt?new rt(n.h,n.s,n.l):mt(""+n,yt,rt):new rt(n,t,e)}function ut(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,new gt(u(n+120),u(n),u(n-120))}function it(n,t,e){return this instanceof it?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof it?new it(n.h,n.c,n.l):n instanceof at?st(n.l,n.a,n.b):st((n=xt((n=Zo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new it(n,t,e)}function ot(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new at(e,Math.cos(n*=Aa)*t,Math.sin(n)*t)}function at(n,t,e){return this instanceof at?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof at?new at(n.l,n.a,n.b):n instanceof it?ot(n.l,n.c,n.h):xt((n=gt(n)).r,n.g,n.b):new at(n,t,e)}function ct(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=lt(u)*ja,r=lt(r)*Ha,i=lt(i)*Fa,new gt(ht(3.2404542*u-1.5371385*r-.4985314*i),ht(-.969266*u+1.8760108*r+.041556*i),ht(.0556434*u-.2040259*r+1.0572252*i))}function st(n,t,e){return n>0?new it(Math.atan2(e,t)*Ca,Math.sqrt(t*t+e*e),n):new it(0/0,0/0,n)}function lt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function ft(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function ht(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function gt(n,t,e){return this instanceof gt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof gt?new gt(n.r,n.g,n.b):mt(""+n,gt,ut):new gt(n,t,e)}function pt(n){return new gt(n>>16,255&n>>8,255&n)}function vt(n){return pt(n)+""}function dt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(_t(u[0]),_t(u[1]),_t(u[2]))}return(i=Ia.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.substring(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function yt(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),new rt(r,u,c)}function xt(n,t,e){n=Mt(n),t=Mt(t),e=Mt(e);var r=ft((.4124564*n+.3575761*t+.1804375*e)/ja),u=ft((.2126729*n+.7151522*t+.072175*e)/Ha),i=ft((.0193339*n+.119192*t+.9503041*e)/Fa);return at(116*u-16,500*(r-u),200*(u-i))}function Mt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function _t(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function bt(n){return"function"==typeof n?n:function(){return n}}function wt(n){return n}function St(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),kt(t,e,n,r)}}function kt(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=Zo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Wo.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=Zo.event;Zo.event=n;try{o.progress.call(i,c)}finally{Zo.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(Xo(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},Zo.rebind(i,o,"on"),null==r?i:i.get(Et(r))}function Et(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function At(){var n=Ct(),t=Nt()-n;t>24?(isFinite(t)&&(clearTimeout($a),$a=setTimeout(At,t)),Xa=0):(Xa=1,Wa(At))}function Ct(){var n=Date.now();for(Ba=Za;Ba;)n>=Ba.t&&(Ba.f=Ba.c(n-Ba.t)),Ba=Ba.n;return n}function Nt(){for(var n,t=Za,e=1/0;t;)t.f?t=n?n.n=t.n:Za=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Va=n,e}function zt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*ua(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)}:wt;return function(n){var e=Ga.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=Ka.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=Zo.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 Rt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Dt(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 nc(e-1)),1),e}function i(n,e){return t(n=new nc(+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{nc=Rt;var r=new Rt;return r._=n,o(r,t,e)}finally{nc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Pt(n);return c.floor=c,c.round=Pt(r),c.ceil=Pt(u),c.offset=Pt(i),c.range=a,n}function Pt(n){return function(t,e){try{nc=Rt;var r=new Rt;return r._=t,n(r,e)._}finally{nc=Date}}}function Ut(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=ec[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&&nc!==Rt,o=new(i?Rt:nc);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 ec?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{nc=Rt;var t=new nc;return t._=n,r(t)}finally{nc=Date}}var r=t(n);return e.parse=function(n){try{nc=Rt;var t=r.parse(n);return t&&t._}finally{nc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=re;var x=Zo.map(),M=Ht(v),_=Ft(v),b=Ht(d),w=Ft(d),S=Ht(m),k=Ft(m),E=Ht(y),A=Ft(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 jt(n.getDate(),t,2)},e:function(n,t){return jt(n.getDate(),t,2)},H:function(n,t){return jt(n.getHours(),t,2)},I:function(n,t){return jt(n.getHours()%12||12,t,2)},j:function(n,t){return jt(1+Qa.dayOfYear(n),t,3)},L:function(n,t){return jt(n.getMilliseconds(),t,3)},m:function(n,t){return jt(n.getMonth()+1,t,2)},M:function(n,t){return jt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return jt(n.getSeconds(),t,2)},U:function(n,t){return jt(Qa.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return jt(Qa.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return jt(n.getFullYear()%100,t,2)},Y:function(n,t){return jt(n.getFullYear()%1e4,t,4)},Z:te,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Wt,e:Wt,H:Gt,I:Gt,j:Jt,L:ne,m:Bt,M:Kt,p:l,S:Qt,U:Yt,w:Ot,W:It,x:c,X:s,y:Vt,Y:Zt,Z:Xt,"%":ee};return t}function jt(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 Ht(n){return new RegExp("^(?:"+n.map(Zo.requote).join("|")+")","i")}function Ft(n){for(var t=new o,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ot(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Yt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function It(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function Zt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Vt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.y=$t(+r[0]),e+r[0].length):-1}function Xt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=-t,e+5):-1}function $t(n){return n+(n>68?1900:2e3)}function Bt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Wt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Jt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Gt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Kt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Qt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ne(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function te(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(ua(t)/60),u=ua(t)%60;return e+jt(r,"0",2)+jt(u,"0",2)}function ee(n,t,e){uc.lastIndex=0;var r=uc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function re(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 ue(){}function ie(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function oe(n,t){n&&cc.hasOwnProperty(n.type)&&cc[n.type](n,t)}function ae(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 ce(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)ae(n[e],t,1);t.polygonEnd()}function se(){function n(n,t){n*=Aa,t=t*Aa/2+ba/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);lc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;fc.point=function(o,a){fc.point=n,r=(t=o)*Aa,u=Math.cos(a=(e=a)*Aa/2+ba/4),i=Math.sin(a)},fc.lineEnd=function(){n(t,e)}}function le(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 fe(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function he(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 ge(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function pe(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function ve(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 de(n){return[Math.atan2(n[1],n[0]),G(n[2])]}function me(n,t){return ua(n[0]-t[0])<ka&&ua(n[1]-t[1])<ka}function ye(n,t){n*=Aa;var e=Math.cos(t*=Aa);xe(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function xe(n,t,e){++hc,pc+=(n-pc)/hc,vc+=(t-vc)/hc,dc+=(e-dc)/hc}function Me(){function n(n,u){n*=Aa;var i=Math.cos(u*=Aa),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);gc+=s,mc+=s*(t+(t=o)),yc+=s*(e+(e=a)),xc+=s*(r+(r=c)),xe(t,e,r)}var t,e,r;wc.point=function(u,i){u*=Aa;var o=Math.cos(i*=Aa);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),wc.point=n,xe(t,e,r)}}function _e(){wc.point=ye}function be(){function n(n,t){n*=Aa;var e=Math.cos(t*=Aa),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&&-J(g)/h,v=Math.atan2(h,g);Mc+=p*s,_c+=p*l,bc+=p*f,gc+=v,mc+=v*(r+(r=o)),yc+=v*(u+(u=a)),xc+=v*(i+(i=c)),xe(r,u,i)}var t,e,r,u,i;wc.point=function(o,a){t=o,e=a,wc.point=n,o*=Aa;var c=Math.cos(a*=Aa);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),xe(r,u,i)},wc.lineEnd=function(){n(t,e),wc.lineEnd=_e,wc.point=ye}}function we(){return!0}function Se(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(me(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 Ee(e,n,null,!0),s=new Ee(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Ee(r,n,null,!1),s=new Ee(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),ke(i),ke(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 ke(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 Ee(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 Ae(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;if(r>0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ce))}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=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Zo.merge(g);var n=Le(m,p);g.length?(_||(i.polygonStart(),_=!0),Se(g,ze,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ne(),M=t(x),_=!1;return y}}function Ce(n){return n.length>1}function Ne(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:v,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function ze(n,t){return((n=n.x)[0]<0?n[1]-Sa-ka:Sa-n[1])-((t=t.x)[0]<0?t[1]-Sa-ka:Sa-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;lc.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+ba/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+ba/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>ba,k=p*x;if(lc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*wa:_,S^h>=e^m>=e){var E=he(le(f),le(n));ve(E);var A=he(u,E);ve(A);var C=(S^_>=0?-1:1)*G(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(-ka>i||ka>i&&0>lc)^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?ba:-ba,c=ua(i-e);ua(c-ba)<ka?(n.point(e,r=(r+o)/2>0?Sa:-Sa),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=ba&&(ua(e-u)<ka&&(e-=u*ka),ua(i-a)<ka&&(i-=a*ka),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 ua(o)>ka?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 Re(n,t,e,r){var u;if(null==n)u=e*Sa,r.point(-ba,u),r.point(0,u),r.point(ba,u),r.point(ba,0),r.point(ba,-u),r.point(0,-u),r.point(-ba,-u),r.point(-ba,0),r.point(-ba,u);else if(ua(n[0]-t[0])>ka){var i=n[0]<t[0]?ba:-ba;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function De(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?ba:-ba),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(me(e,g)||me(p,g))&&(p[0]+=ka,p[1]+=ka,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&&me(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=le(n),u=le(t),o=[1,0,0],a=he(r,u),c=fe(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=he(o,a),p=pe(o,f),v=pe(a,h);ge(p,v);var d=g,m=fe(p,d),y=fe(d,d),x=m*m-y*(fe(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=pe(d,(-m-M)/y);if(ge(_,p),_=de(_),!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=ua(A-ba)<ka,N=C||ka>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ua(_[0]-w)<ka?k:E):k<=_[1]&&_[1]<=E:A>ba^(w<=_[0]&&_[0]<=S)){var z=pe(d,(-m+M)/y);return ge(z,p),[_,de(z)]}}}function u(t,e){var r=o?n:ba-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=ua(i)>ka,c=sr(n,6*Aa);return Ae(t,e,c,o?[0,-n]:[-ba,n-ba])}function Pe(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 Ue(n,t,e,r){function u(r,u){return ua(r[0]-n)<ka?u>0?0:3:ua(r[0]-e)<ka?u>0?2:1:ua(r[1]-t)<ka?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&&W(s,i,n)>0&&++t:i[1]<=r&&W(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(-kc,Math.min(kc,n)),t=Math.max(-kc,Math.min(kc,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=Ne(),C=Pe(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Zo.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&&Se(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function je(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 He(n){var t=0,e=ba/3,r=tr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ba/180,e=n[1]*ba/180):[180*(t/ba),180*(e/ba)]},u}function Fe(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,G((i-(n*n+e*e)*u*u)/(2*u))]},e}function Oe(){function n(n,t){Ac+=u*n-r*t,r=n,u=t}var t,e,r,u;Tc.point=function(i,o){Tc.point=n,t=r=i,e=u=o},Tc.lineEnd=function(){n(t,e)}}function Ye(n,t){Cc>n&&(Cc=n),n>zc&&(zc=n),Nc>t&&(Nc=t),t>Lc&&(Lc=t)}function Ie(){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=Ze(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=Ze(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ze(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ve(n,t){pc+=n,vc+=t,++dc}function Xe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);mc+=o*(t+n)/2,yc+=o*(e+r)/2,xc+=o,Ve(t=n,e=r)}var t,e;Rc.point=function(r,u){Rc.point=n,Ve(t=r,e=u)}}function $e(){Rc.point=Ve}function Be(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);mc+=o*(r+n)/2,yc+=o*(u+t)/2,xc+=o,o=u*n-r*t,Mc+=o*(r+n),_c+=o*(u+t),bc+=3*o,Ve(r=n,u=t)}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,Ve(t=r=i,e=u=o)},Rc.lineEnd=function(){n(t,e)}}function We(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,wa)}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:v};return a}function Je(n){function t(n){return(a?r:e)(n)}function e(t){return Qe(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=le([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=ua(ua(w)-1)<ka||ua(r-h)<ka?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],z=C-t,L=N-e,T=x*z-y*L;(T*T/M>i||ua((y*z+x*L)/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*Aa),a=16;
+return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Ge(n){var t=Je(function(t,e){return n([t*Ca,e*Ca])});return function(n){return er(t(n))}}function Ke(n){this.stream=n}function Qe(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 nr(n){return tr(function(){return n})()}function tr(n){function t(n){return n=a(n[0]*Aa,n[1]*Aa),[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]*Ca,n[1]*Ca]}function r(){a=je(o=ir(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=Je(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=Sc,_=wt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=er(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Sc):De((b=+n)*Aa),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Ue(n[0][0],n[0][1],n[1][0],n[1][1]):wt,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*Aa,d=n[1]%360*Aa,r()):[v*Ca,d*Ca]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Aa,y=n[1]%360*Aa,x=n.length>2?n[2]%360*Aa:0,r()):[m*Ca,y*Ca,x*Ca]},Zo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function er(n){return Qe(n,function(t,e){n.point(t*Aa,e*Aa)})}function rr(n,t){return[n,t]}function ur(n,t){return[n>ba?n-wa:-ba>n?n+wa:n,t]}function ir(n,t,e){return n?t||e?je(ar(n),cr(t,e)):ar(n):t||e?cr(t,e):ur}function or(n){return function(t,e){return t+=n,[t>ba?t-wa:-ba>t?t+wa:t,e]}}function ar(n){var t=or(n);return t.invert=or(-n),t}function cr(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),G(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),G(l*r-a*u)]},e}function sr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=lr(e,u),i=lr(e,i),(o>0?i>u:u>i)&&(u+=o*wa)):(u=n+o*wa,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=de([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function lr(n,t){var e=le(t);e[0]-=n,ve(e);var r=J(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-ka)%(2*Math.PI)}function fr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function hr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function gr(n){return n.source}function pr(n){return n.target}function vr(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(tt(r-t)+u*o*tt(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)*Ca,Math.atan2(o,Math.sqrt(r*r+u*u))*Ca]}:function(){return[n*Ca,t*Ca]};return p.distance=h,p}function dr(){function n(n,u){var i=Math.sin(u*=Aa),o=Math.cos(u),a=ua((n*=Aa)-t),c=Math.cos(a);Dc+=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;Pc.point=function(u,i){t=u*Aa,e=Math.sin(i*=Aa),r=Math.cos(i),Pc.point=n},Pc.lineEnd=function(){Pc.point=Pc.lineEnd=v}}function mr(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 yr(n,t){function e(n,t){o>0?-Sa+ka>t&&(t=-Sa+ka):t>Sa-ka&&(t=Sa-ka);var e=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(ba/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=B(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Sa]},e):Mr}function xr(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 ua(u)<ka?rr:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-B(u)*Math.sqrt(n*n+e*e)]},e)}function Mr(n,t){return[n,Math.log(Math.tan(ba/4+t/2))]}function _r(n){var t,e=nr(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=ba*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 br(n,t){return[Math.log(Math.tan(ba/4+t/2)),-n]}function wr(n){return n[0]}function Sr(n){return n[1]}function kr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&W(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function Er(n,t){return n[0]-t[0]||n[1]-t[1]}function Ar(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Cr(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 Nr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function zr(){Gr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Bc.pop()||new zr;return t.site=n,t}function Tr(n){Yr(n),Vc.remove(n),Bc.push(n),Gr(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&&ua(e-c.circle.x)<ka&&ua(r-c.circle.cy)<ka;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Yr(c);for(var s=o;s.circle&&ua(e-s.circle.x)<ka&&ua(r-s.circle.cy)<ka;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Yr(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],Br(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Xr(c.site,s.site,null,u),Or(c),Or(s)}function Rr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Vc._;a;)if(r=Dr(a,o)-i,r>ka)a=a.L;else{if(u=i-Pr(a,o),!(u>ka)){r>-ka?(t=a.P,e=a):u>-ka?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if(Vc.insert(t,c),t||e){if(t===e)return Yr(t),e=Lr(t.site),Vc.insert(c,e),c.edge=e.edge=Xr(t.site,c.site),Or(t),Or(e),void 0;if(!e)return c.edge=Xr(t.site,c.site),void 0;Yr(t),Yr(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};Br(e.edge,s,p,M),c.edge=Xr(s,n,null,M),e.edge=Xr(n,p,null,M),Or(t),Or(e)}}function Dr(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 Pr(n,t){var e=n.N;if(e)return Dr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ur(n){this.site=n,this.edges=[]}function jr(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=Zc,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,(ua(r-t)>ka||ua(u-e)>ka)&&(a.splice(o,0,new Wr($r(i.site,l,ua(r-f)<ka&&p-u>ka?{x:f,y:ua(t-f)<ka?e:p}:ua(u-p)<ka&&h-r>ka?{x:ua(e-p)<ka?t:h,y:p}:ua(r-h)<ka&&u-g>ka?{x:h,y:ua(t-h)<ka?e:g}:ua(u-g)<ka&&r-f>ka?{x:ua(e-g)<ka?t:f,y:g}:null),i.site,null)),++c)}function Hr(n,t){return t.angle-n.angle}function Fr(){Gr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Or(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>=-Ea)){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=Wc.pop()||new Fr;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=$c._;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}$c.insert(y,m),y||(Xc=m)}}}}function Yr(n){var t=n.circle;t&&(t.P||(Xc=t.N),$c.remove(t),Wc.push(t),Gr(t),n.circle=null)}function Ir(n){for(var t,e=Ic,r=Pe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Zr(t,n)||!r(t)||ua(t.a.x-t.b.x)<ka&&ua(t.a.y-t.b.y)<ka)&&(t.a=t.b=null,e.splice(u,1))}function Zr(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 Vr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Xr(n,t,e,r){var u=new Vr(n,t);return Ic.push(u),e&&Br(u,n,t,e),r&&Br(u,t,n,r),Zc[n.i].edges.push(new Wr(u,n,t)),Zc[t.i].edges.push(new Wr(u,t,n)),u}function $r(n,t,e){var r=new Vr(n,null);return r.a=t,r.b=e,Ic.push(r),r}function Br(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 Wr(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 Jr(){this._=null}function Gr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Kr(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 Qr(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 nu(n){for(;n.L;)n=n.L;return n}function tu(n,t){var e,r,u,i=n.sort(eu).pop();for(Ic=[],Zc=new Array(n.length),Vc=new Jr,$c=new Jr;;)if(u=Xc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Zc[i.i]=new Ur(i),Rr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Ir(t),jr(t));var o={cells:Zc,edges:Ic};return Vc=$c=Ic=Zc=null,o}function eu(n,t){return t.y-n.y||t.x-n.x}function ru(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function uu(n){return n.x}function iu(n){return n.y}function ou(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function au(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]&&au(n,c[0],e,r,o,a),c[1]&&au(n,c[1],o,r,u,a),c[2]&&au(n,c[2],e,a,o,i),c[3]&&au(n,c[3],o,a,u,i)}}function cu(n,t){n=Zo.rgb(n),t=Zo.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"#"+dt(Math.round(e+i*n))+dt(Math.round(r+o*n))+dt(Math.round(u+a*n))}}function su(n,t){var e,r={},u={};for(e in n)e in t?r[e]=hu(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 lu(n,t){return t-=n=+n,function(e){return n+t*e}}function fu(n,t){var e,r,u,i=Gc.lastIndex=Kc.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=Gc.exec(n))&&(r=Kc.exec(t));)(u=r.index)>i&&(u=t.substring(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:lu(e,r)})),i=Kc.lastIndex;return i<t.length&&(u=t.substring(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function hu(n,t){for(var e,r=Zo.interpolators.length;--r>=0&&!(e=Zo.interpolators[r](n,t)););return e}function gu(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(hu(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 pu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function vu(n){return function(t){return 1-n(1-t)}}function du(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function mu(n){return n*n}function yu(n){return n*n*n}function xu(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 Mu(n){return function(t){return Math.pow(t,n)}}function _u(n){return 1-Math.cos(n*Sa)}function bu(n){return Math.pow(2,10*(n-1))}function wu(n){return 1-Math.sqrt(1-n*n)}function Su(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/wa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*wa/t)}}function ku(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Eu(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 Au(n,t){n=Zo.hcl(n),t=Zo.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 ot(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Zo.hsl(n),t=Zo.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 ut(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){n=Zo.lab(n),t=Zo.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 ct(e+i*n,r+o*n,u+a*n)+""}}function zu(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(Ru(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]))*Ca,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Ca: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 Ru(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Du(n,t){var e,r=[],u=[],i=Zo.transform(n),o=Zo.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:lu(a[0],c[0])},{i:3,x:lu(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:lu(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:lu(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:lu(g[0],p[0])},{i:e-2,x:lu(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 Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Uu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function ju(n){for(var t=n.source,e=n.target,r=Fu(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 Hu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Fu(n,t){if(n===t)return n;for(var e=Hu(n),r=Hu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Ou(n){n.fixed|=2}function Yu(n){n.fixed&=-7}function Iu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Zu(n){n.fixed&=-5}function Vu(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&&(Vu(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 Xu(n,t){return Zo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Ku,n}function $u(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Bu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function Wu(n){return n.children}function Ju(n){return n.value}function Gu(n,t){return t.value-n.value}function Ku(n){return Zo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Qu(n){return n.x}function ni(n){return n.y}function ti(n,t,e){n.y0=t,n.y=e}function ei(n){return Zo.range(n.length)}function ri(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ui(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 ii(n){return n.reduce(oi,0)}function oi(n,t){return n+t[1]}function ai(n,t){return ci(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ci(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 si(n){return[Zo.min(n),Zo.max(n)]}function li(n,t){return n.value-t.value}function fi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function hi(n,t){n._pack_next=t,t._pack_prev=n}function gi(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 pi(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(vi),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],yi(r,u,i),t(i),fi(r,i),r._pack_prev=i,fi(i,u),u=r._pack_next,o=3;s>o;o++){yi(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(gi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!gi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?hi(r,u=a):hi(r=c,u),o--):(fi(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(di)}}function vi(n){n._pack_next=n._pack_prev=n}function di(n){delete n._pack_next,delete n._pack_prev}function mi(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;)mi(u[i],t,e,r)}function yi(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 xi(n,t){return n.parent==t.parent?1:2}function Mi(n){var t=n.children;return t.length?t[0]:n.t}function _i(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function bi(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function wi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Si(n,t,e){return n.a.parent===t.parent?n.a:e}function ki(n){return 1+Zo.max(n,function(n){return n.y})}function Ei(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ai(n){var t=n.children;return t&&t.length?Ai(t[0]):n}function Ci(n){var t,e=n.children;return e&&(t=e.length)?Ci(e[t-1]):n}function Ni(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function zi(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 Li(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ti(n){return n.rangeExtent?n.rangeExtent():Li(n.range())}function qi(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 Ri(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 Di(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ss}function Pi(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=Zo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ui(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Pi:qi,c=r?Uu:Pu;return o=u(n,t,c,e),a=u(t,n,c,hu),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(zu)},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 Oi(n,t)},i.tickFormat=function(t,e){return Yi(n,t,e)},i.nice=function(t){return Hi(n,t),u()},i.copy=function(){return Ui(n,t,e,r)},u()}function ji(n,t){return Zo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Hi(n,t){return Ri(n,Di(Fi(n,t)[2]))}function Fi(n,t){null==t&&(t=10);var e=Li(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 Oi(n,t){return Zo.range.apply(Zo,Fi(n,t))}function Yi(n,t,e){var r=Fi(n,t);if(e){var u=Ga.exec(e);if(u.shift(),"s"===u[8]){var i=Zo.formatPrefix(Math.max(ua(r[0]),ua(r[1])));return u[7]||(u[7]="."+Ii(i.scale(r[2]))),u[8]="f",e=Zo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Zi(u[8],r)),e=u.join("")}else e=",."+Ii(r[2])+"f";return Zo.format(e)}function Ii(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Zi(n,t){var e=Ii(t[2]);return n in ls?Math.abs(e-Ii(Math.max(ua(t[0]),ua(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Vi(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=Ri(r.map(u),e?Math:hs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Li(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 fs;arguments.length<2?t=fs:"function"!=typeof t&&(t=Zo.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 Vi(n.copy(),t,e,r)},ji(o,n)}function Xi(n,t,e){function r(t){return n(u(t))}var u=$i(t),i=$i(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 Oi(e,n)},r.tickFormat=function(n,t){return Yi(e,n,t)},r.nice=function(n){return r.domain(Hi(e,n))},r.exponent=function(o){return arguments.length?(u=$i(t=o),i=$i(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Xi(n.copy(),t,e)},ji(r,n)}function $i(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Bi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Zo.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new o;for(var i,a=-1,c=r.length;++a<c;)u.has(i=r[a])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,a=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,o){arguments.length<2&&(o=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+o);return i=r(n.length<2?(c+s)/2:c+l*o/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-o+2*c);return i=r(l+h*c,h),s&&i.reverse(),a=h*(1-o),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-o+2*c)),g=f-l-(n.length-o)*h;return i=r(l+Math.round(g/2),h),s&&i.reverse(),a=Math.round(h*(1-o)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return Li(t.a[0])},e.copy=function(){return Bi(n,t)},e.domain(n)}function Wi(e,r){function u(){var n=0,t=r.length;for(o=[];++n<t;)o[n-1]=Zo.quantile(e,n/t);return i}function i(n){return isNaN(n=+n)?void 0:r[Zo.bisect(o,n)]}var o;return i.domain=function(r){return arguments.length?(e=r.filter(t).sort(n),u()):e},i.range=function(n){return arguments.length?(r=n,u()):r},i.quantiles=function(){return o},i.invertExtent=function(n){return n=r.indexOf(n),0>n?[0/0,0/0]:[n>0?o[n-1]:e[0],n<o.length?o[n]:e[e.length-1]]},i.copy=function(){return Wi(e,r)},u()}function Ji(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 Ji(n,t,e)},u()}function Gi(n,t){function e(e){return e>=e?t[Zo.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 Gi(n,t)},e}function Ki(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 Oi(n,t)},t.tickFormat=function(t,e){return Yi(n,t,e)},t.copy=function(){return Ki(n)},t}function Qi(n){return n.innerRadius}function no(n){return n.outerRadius}function to(n){return n.startAngle}function eo(n){return n.endAngle}function ro(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=bt(e),p=bt(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=wr,r=Sr,u=we,i=uo,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=xs.get(n)||uo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function uo(n){return n.join("L")}function io(n){return uo(n)+"Z"}function oo(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 ao(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 co(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 so(n,t){return n.length<4?uo(n):n[1]+ho(n.slice(1,n.length-1),go(n,t))}function lo(n,t){return n.length<3?uo(n):n[0]+ho((n.push(n[0]),n),go([n[n.length-2]].concat(n,[n[1]]),t))}function fo(n,t){return n.length<3?uo(n):n[0]+ho(n,go(n,t))}function ho(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return uo(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 go(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 po(n){if(n.length<3)return uo(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",xo(bs,o),",",xo(bs,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Mo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function vo(n){if(n.length<4)return uo(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(xo(bs,i)+","+xo(bs,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Mo(e,i,o);return e.join("")}function mo(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=[xo(bs,o),",",xo(bs,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Mo(t,o,a);return t.join("")}function yo(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 po(n)}function xo(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Mo(n,t,e){n.push("C",xo(Ms,t),",",xo(Ms,e),",",xo(_s,t),",",xo(_s,e),",",xo(bs,t),",",xo(bs,e))}function _o(n,t){return(t[1]-n[1])/(t[0]-n[0])}function bo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=_o(u,i);++t<e;)r[t]=(o+(o=_o(u=i,i=n[t+1])))/2;return r[t]=o,r}function wo(n){for(var t,e,r,u,i=[],o=bo(n),a=-1,c=n.length-1;++a<c;)t=_o(n[a],n[a+1]),ua(t)<ka?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 So(n){return n.length<3?uo(n):n[0]+ho(n,wo(n))}function ko(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ms,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Eo(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=bt(e),_=bt(u),b=e===r?function(){return g}:bt(r),w=u===i?function(){return p}:bt(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=wr,r=wr,u=0,i=Sr,o=we,a=uo,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=xs.get(n)||uo).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 Ao(n){return n.radius}function Co(n){return[n.x,n.y]}function No(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ms;return[e*Math.cos(r),e*Math.sin(r)]}}function zo(){return 64}function Lo(){return"circle"}function To(n){var t=Math.sqrt(n/ba);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function qo(n,t){return sa(n,Cs),n.id=t,n}function Ro(n,t,e,r){var u=n.id;return P(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 Do(n){return null==n&&(n=""),function(){this.textContent=n}}function Po(n,t,e,r){var u=n.__transition__||(n.__transition__={active:0,count:0}),i=u[e];if(!i){var a=r.time;i=u[e]={tween:new o,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++u.count,Zo.timer(function(r){function o(r){return u.active>e?s():(u.active=e,i.event&&i.event.start.call(n,l,t),i.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Zo.timer(function(){return p.c=c(r||1)?we:c,1},0,a),void 0)}function c(r){if(u.active!==e)return s();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a);
+return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ba,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Uo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function jo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Ho(n){return n.toISOString()}function Fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Zo.bisect(Us,u);return i==Us.length?[t.year,Fi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Us[i-1]<Us[i]/u?i-1:i]:[Fs,Fi(n,e)[2]]}return r.invert=function(t){return Oo(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Oo)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Oo(+e+1),t).length}var i=r.domain(),o=Li(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Ri(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Oo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Oo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Li(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],Oo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Fo(n.copy(),t,e)},ji(r,n)}function Oo(n){return new Date(n)}function Yo(n){return JSON.parse(n.responseText)}function Io(n){var t=$o.createRange();return t.selectNode($o.body),t.createContextualFragment(n.responseText)}var Zo={version:"3.4.11"};Date.now||(Date.now=function(){return+new Date});var Vo=[].slice,Xo=function(n){return Vo.call(n)},$o=document,Bo=$o.documentElement,Wo=window;try{Xo(Bo.childNodes)[0].nodeType}catch(Jo){Xo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{$o.createElement("div").style.setProperty("opacity",0,"")}catch(Go){var Ko=Wo.Element.prototype,Qo=Ko.setAttribute,na=Ko.setAttributeNS,ta=Wo.CSSStyleDeclaration.prototype,ea=ta.setProperty;Ko.setAttribute=function(n,t){Qo.call(this,n,t+"")},Ko.setAttributeNS=function(n,t,e){na.call(this,n,t,e+"")},ta.setProperty=function(n,t,e){ea.call(this,n,t+"",e)}}Zo.ascending=n,Zo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Zo.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},Zo.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},Zo.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]},Zo.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},Zo.mean=function(n,e){var r,u=0,i=n.length,o=-1,a=i;if(1===arguments.length)for(;++o<i;)t(r=n[o])?u+=r:--a;else for(;++o<i;)t(r=e.call(n,n[o],o))?u+=r:--a;return a?u/a:void 0},Zo.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},Zo.median=function(e,r){return arguments.length>1&&(e=e.map(r)),e=e.filter(t),e.length?Zo.quantile(e.sort(n),.5):void 0};var ra=e(n);Zo.bisectLeft=ra.left,Zo.bisect=Zo.bisectRight=ra.right,Zo.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Zo.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},Zo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Zo.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},Zo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Zo.min(arguments,r),e=new Array(t);++n<t;)for(var u,i=-1,o=e[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return e},Zo.transpose=function(n){return Zo.zip.apply(Zo,n)},Zo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Zo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Zo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Zo.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 ua=Math.abs;Zo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(ua(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)<t;)i.push(r/o);return i},Zo.map=function(n){var t=new o;if(n instanceof o)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},i(o,{has:a,get:function(n){return this[ia+n]},set:function(n,t){return this[ia+n]=t},remove:c,keys:s,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:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1),this[t])}});var ia="\x00",oa=ia.charCodeAt(0);Zo.nest=function(){function n(t,a,c){if(c>=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++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>=i.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,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Zo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Zo.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ia+n]=!0,n},remove:function(n){return n=ia+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1))}}),Zo.behavior={},Zo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=g(n,t,t[e]);return n};var aa=["webkit","ms","moz","Moz","o","O"];Zo.dispatch=function(){for(var n=new d,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=m(n);return n},d.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}},Zo.event=null,Zo.requote=function(n){return n.replace(ca,"\\$&")};var ca=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},la=function(n,t){return t.querySelector(n)},fa=function(n,t){return t.querySelectorAll(n)},ha=Bo.matches||Bo[p(Bo,"matchesSelector")],ga=function(n,t){return ha.call(n,t)};"function"==typeof Sizzle&&(la=function(n,t){return Sizzle(n,t)[0]||null},fa=Sizzle,ga=Sizzle.matchesSelector),Zo.selection=function(){return ma};var pa=Zo.selection.prototype=[];pa.select=function(n){var t,e,r,u,i=[];n=b(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 _(i)},pa.selectAll=function(n){var t,e,r=[];n=w(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=Xo(n.call(e,e.__data__,a,u))),t.parentNode=e);return _(r)};var va={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/"};Zo.ns={prefix:va,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),va.hasOwnProperty(e)?{space:va[e],local:n}:n}},pa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Zo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},pa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(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(!E(n[u]).test(t))return!1;return!0}for(t in n)this.each(C(t,n[t]));return this}return this.each(C(n,t))},pa.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(z(e,n[e],t));return this}if(2>r)return Wo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(z(n,t,e))},pa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},pa.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},pa.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},pa.append=function(n){return n=T(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},pa.insert=function(n,t){return n=T(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},pa.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},pa.data=function(n,t){function e(n,e){var r,u,i,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 o,y=new o,x=[];for(r=-1;++r<a;)d=t.call(u=n[r],u.__data__,r),m.has(d)?v[r]=u:m.set(d,u),x.push(d);for(r=-1;++r<f;)d=t.call(e,i=e[r],r),(u=m.get(d))?(g[r]=u,u.__data__=i):y.has(d)||(p[r]=q(i)),y.set(d,i),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=q(i);for(;f>r;++r)p[r]=q(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,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++i<a;)(u=r[i])&&(n[i]=u.__data__);return n}var c=U([]),s=_([]),l=_([]);if("function"==typeof n)for(;++i<a;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<a;)e(r=this[i],n);return s.enter=function(){return c},s.exit=function(){return l},s},pa.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},pa.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(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 _(u)},pa.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},pa.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},pa.each=function(n){return P(this,function(t,e,r){n.call(t,t.__data__,e,r)})},pa.call=function(n){var t=Xo(arguments);return n.apply(t[0]=this,t),this},pa.empty=function(){return!this.node()},pa.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},pa.size=function(){var n=0;return this.each(function(){++n}),n};var da=[];Zo.selection.enter=U,Zo.selection.enter.prototype=da,da.append=pa.append,da.empty=pa.empty,da.node=pa.node,da.call=pa.call,da.size=pa.size,da.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 _(o)},da.insert=function(n,t){return arguments.length<2&&(t=j(this)),pa.insert.call(this,n,t)},pa.transition=function(){for(var n,t,e=Ss||++Ns,r=[],u=ks||{time:Date.now(),ease:xu,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])&&Po(t,c,e,u),n.push(t)}return qo(r,e)},pa.interrupt=function(){return this.each(H)},Zo.select=function(n){var t=["string"==typeof n?la(n,$o):n];return t.parentNode=Bo,_([t])},Zo.selectAll=function(n){var t=Xo("string"==typeof n?fa(n,$o):n);return t.parentNode=Bo,_([t])};var ma=Zo.select(Bo);pa.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(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ya=Zo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ya.forEach(function(n){"on"+n in $o&&ya.remove(n)});var xa="onselectstart"in $o?null:p(Bo.style,"userSelect"),Ma=0;Zo.mouse=function(n){return Z(n,x())};var _a=/WebKit/.test(Wo.navigator.userAgent)?-1:0;Zo.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Xo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Zo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Zo.event.target===f),g({type:"dragend"}))}var s,l=this,f=Zo.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Zo.select(u()).on(i+d,a).on(o+d,c),y=I(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Zo.mouse,$,"mousemove","mouseup"),i=t(V,Zo.touch,X,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Zo.rebind(n,e,"on")};var ba=Math.PI,wa=2*ba,Sa=ba/2,ka=1e-6,Ea=ka*ka,Aa=ba/180,Ca=180/ba,Na=Math.SQRT2,za=2,La=4;Zo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(za*h)*(e*nt(Na*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Na*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Na*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+La*f)/(2*i*za*h),p=(c*c-i*i-La*f)/(2*c*za*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))/Na;return e.duration=1e3*y,e},Zo.behavior.zoom=function(){function n(n){n.on(A,s).on(Ra+".zoom",f).on("dblclick.zoom",h).on(z,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(x.range().map(function(n){return(n-S.x)/S.k}).map(x.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(Zo.mouse(r),h),a(s)}function e(){f.on(C,null).on(N,null),g(l&&Zo.event.target===i),c(s)}var r=this,i=Zo.event.target,s=L.of(r,arguments),l=0,f=Zo.select(Wo).on(C,n).on(N,e),h=t(Zo.mouse(r)),g=I();H.call(r),o(s)}function l(){function n(){var n=Zo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Zo.event.target;Zo.select(t).on(M,i).on(_,f),b.push(t);for(var e=Zo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var s=n(),l=Date.now();if(1===s.length){if(500>l-m){var h=s[0],g=v[h.identifier];r(2*S.k),u(h,g),y(),a(p)}m=l}else if(s.length>1){var h=s[0],x=s[1],w=h[0]-x[0],k=h[1]-x[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Zo.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=d&&Math.sqrt(l/d);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)}m=null,u(n,t),a(p)}function f(){if(Zo.event.touches.length){for(var t=Zo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Zo.selectAll(b).on(x,null),w.on(A,s).on(z,l),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,x=".zoom-"+Zo.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=[],w=Zo.select(g).on(A,null).on(z,e),k=I();H.call(g),e(),o(p)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Zo.mouse(this)),H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y(),r(Math.pow(2,.002*Ta())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Zo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Zo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=qa,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Ss?Zo.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=Zo.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?qa:[+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,x=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},Zo.rebind(n,L,"on")};var Ta,qa=[0,1/0],Ra="onwheel"in $o?(Ta=function(){return-Zo.event.deltaY*(Zo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in $o?(Ta=function(){return Zo.event.wheelDelta},"mousewheel"):(Ta=function(){return-Zo.event.detail},"MozMousePixelScroll");Zo.color=et,et.prototype.toString=function(){return this.rgb()+""},Zo.hsl=rt;var Da=rt.prototype=new et;Da.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,this.l/n)},Da.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,n*this.l)},Da.rgb=function(){return ut(this.h,this.s,this.l)},Zo.hcl=it;var Pa=it.prototype=new et;Pa.brighter=function(n){return new it(this.h,this.c,Math.min(100,this.l+Ua*(arguments.length?n:1)))},Pa.darker=function(n){return new it(this.h,this.c,Math.max(0,this.l-Ua*(arguments.length?n:1)))},Pa.rgb=function(){return ot(this.h,this.c,this.l).rgb()},Zo.lab=at;var Ua=18,ja=.95047,Ha=1,Fa=1.08883,Oa=at.prototype=new et;Oa.brighter=function(n){return new at(Math.min(100,this.l+Ua*(arguments.length?n:1)),this.a,this.b)},Oa.darker=function(n){return new at(Math.max(0,this.l-Ua*(arguments.length?n:1)),this.a,this.b)},Oa.rgb=function(){return ct(this.l,this.a,this.b)},Zo.rgb=gt;var Ya=gt.prototype=new et;Ya.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),new gt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new gt(u,u,u)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new gt(n*this.r,n*this.g,n*this.b)},Ya.hsl=function(){return yt(this.r,this.g,this.b)},Ya.toString=function(){return"#"+dt(this.r)+dt(this.g)+dt(this.b)};var Ia=Zo.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});Ia.forEach(function(n,t){Ia.set(n,pt(t))}),Zo.functor=bt,Zo.xhr=St(wt),Zo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=kt(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 h,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},Zo.csv=Zo.dsv(",","text/csv"),Zo.tsv=Zo.dsv("    ","text/tab-separated-values"),Zo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Za,Va,Xa,$a,Ba,Wa=Wo[p(Wo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Zo.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};Va?Va.n=i:Za=i,Va=i,Xa||($a=clearTimeout($a),Xa=1,Wa(At))},Zo.timer.flush=function(){Ct(),Nt()},Zo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ja=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Zo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Zo.round(n,zt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),Ja[8+e/3]};var Ga=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Ka=Zo.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=Zo.round(n,zt(n,t))).toFixed(Math.max(0,Math.min(20,zt(n*(1+1e-15),t))))}}),Qa=Zo.time={},nc=Date;Rt.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(){tc.setUTCDate.apply(this._,arguments)},setDay:function(){tc.setUTCDay.apply(this._,arguments)},setFullYear:function(){tc.setUTCFullYear.apply(this._,arguments)},setHours:function(){tc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){tc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){tc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){tc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){tc.setUTCSeconds.apply(this._,arguments)},setTime:function(){tc.setTime.apply(this._,arguments)}};var tc=Date.prototype;Qa.year=Dt(function(n){return n=Qa.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Qa.years=Qa.year.range,Qa.years.utc=Qa.year.utc.range,Qa.day=Dt(function(n){var t=new nc(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}),Qa.days=Qa.day.range,Qa.days.utc=Qa.day.utc.range,Qa.dayOfYear=function(n){var t=Qa.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=Qa[n]=Dt(function(n){return(n=Qa.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=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Qa[n+"s"]=e.range,Qa[n+"s"].utc=e.utc.range,Qa[n+"OfYear"]=function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)}}),Qa.week=Qa.sunday,Qa.weeks=Qa.sunday.range,Qa.weeks.utc=Qa.sunday.utc.range,Qa.weekOfYear=Qa.sundayOfYear;var ec={"-":"",_:" ",0:"0"},rc=/^\s*\d+/,uc=/^%/;Zo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Ut(n)}};var ic=Zo.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"]});Zo.format=ic.numberFormat,Zo.geo={},ue.prototype={s:0,t:0,add:function(n){ie(n,this.t,oc),ie(oc.s,this.s,this),this.s?this.t+=oc.t:this.s=oc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var oc=new ue;Zo.geo.stream=function(n,t){n&&ac.hasOwnProperty(n.type)?ac[n.type](n,t):oe(n,t)};var ac={Feature:function(n,t){oe(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)oe(e[r].geometry,t)}},cc={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){ae(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t,0)},Polygon:function(n,t){ce(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ce(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)oe(e[r],t)}};Zo.geo.area=function(n){return sc=0,Zo.geo.stream(n,fc),sc};var sc,lc=new ue,fc={sphere:function(){sc+=4*ba},point:v,lineStart:v,lineEnd:v,polygonStart:function(){lc.reset(),fc.lineStart=se},polygonEnd:function(){var n=2*lc;sc+=0>n?4*ba+n:n,fc.lineStart=fc.lineEnd=fc.point=v}};Zo.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=le([t*Aa,e*Aa]);if(m){var u=he(m,r),i=[u[1],-u[0],0],o=he(i,u);ve(o),o=de(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ca*s,d=ua(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ca;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ca;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+=ua(r)>180?r+(r>0?360:-360):r}else v=n,d=e;fc.point(n,e),t(n,e)}function i(){fc.lineStart()}function o(){u(v,d),fc.lineEnd(),ua(y)>ka&&(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,fc.polygonStart()},polygonEnd:function(){fc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>lc?(l=-(h=180),f=-(g=90)):y>ka?g=90:-ka>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Zo.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]]}}(),Zo.geo.centroid=function(n){hc=gc=pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,wc);var t=Mc,e=_c,r=bc,u=t*t+e*e+r*r;return Ea>u&&(t=mc,e=yc,r=xc,ka>gc&&(t=pc,e=vc,r=dc),u=t*t+e*e+r*r,Ea>u)?[0/0,0/0]:[Math.atan2(e,t)*Ca,G(r/Math.sqrt(u))*Ca]};var hc,gc,pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc={sphere:v,point:ye,lineStart:Me,lineEnd:_e,polygonStart:function(){wc.lineStart=be},polygonEnd:function(){wc.lineStart=Me}},Sc=Ae(we,Te,Re,[-ba,-ba/2]),kc=1e9;Zo.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=Ue(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]])},(Zo.geo.conicEqualArea=function(){return He(Fe)}).raw=Fe,Zo.geo.albers=function(){return Zo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Zo.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=Zo.geo.albers(),o=Zo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Zo.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+ka,f+.12*s+ka],[l-.214*s-ka,f+.234*s-ka]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+ka,f+.166*s+ka],[l-.115*s-ka,f+.234*s-ka]]).stream(c).point,n},n.scale(1070)};var Ec,Ac,Cc,Nc,zc,Lc,Tc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){Ac=0,Tc.lineStart=Oe},polygonEnd:function(){Tc.lineStart=Tc.lineEnd=Tc.point=v,Ec+=ua(Ac/2)}},qc={point:Ye,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Rc={point:Ve,lineStart:Xe,lineEnd:$e,polygonStart:function(){Rc.lineStart=Be},polygonEnd:function(){Rc.point=Ve,Rc.lineStart=Xe,Rc.lineEnd=$e}};Zo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Zo.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 Ec=0,Zo.geo.stream(n,u(Tc)),Ec},n.centroid=function(n){return pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,u(Rc)),bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:dc?[pc/dc,vc/dc]:[0/0,0/0]},n.bounds=function(n){return zc=Lc=-(Cc=Nc=1/0),Zo.geo.stream(n,u(qc)),[[Cc,Nc],[zc,Lc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Ge(n):wt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ie:new We(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(Zo.geo.albersUsa()).context(null)},Zo.geo.transform=function(n){return{stream:function(t){var e=new Ke(t);for(var r in n)e[r]=n[r];return e}}},Ke.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()}},Zo.geo.projection=nr,Zo.geo.projectionMutator=tr,(Zo.geo.equirectangular=function(){return nr(rr)}).raw=rr.invert=rr,Zo.geo.rotation=function(n){function t(t){return t=n(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t}return n=ir(n[0]%360*Aa,n[1]*Aa,n.length>2?n[2]*Aa:0),t.invert=function(t){return t=n.invert(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t},t},ur.invert=rr,Zo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ir(-n[0]*Aa,-n[1]*Aa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ca,n[1]*=Ca}}),{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=sr((t=+r)*Aa,u*Aa),n):t},n.precision=function(r){return arguments.length?(e=sr(t*Aa,(u=+r)*Aa),n):u},n.angle(90)},Zo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Aa,u=n[1]*Aa,i=t[1]*Aa,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)},Zo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Zo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Zo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Zo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ua(n%d)>ka}).map(l)).concat(Zo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ua(n%m)>ka}).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=fr(a,o,90),f=hr(r,e,y),h=fr(s,c,90),g=hr(i,u,y),n):y},n.majorExtent([[-180,-90+ka],[180,90-ka]]).minorExtent([[-180,-80-ka],[180,80+ka]])},Zo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=gr,u=pr;return n.distance=function(){return Zo.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},Zo.geo.interpolate=function(n,t){return vr(n[0]*Aa,n[1]*Aa,t[0]*Aa,t[1]*Aa)},Zo.geo.length=function(n){return Dc=0,Zo.geo.stream(n,Pc),Dc};var Dc,Pc={sphere:v,point:v,lineStart:dr,lineEnd:v,polygonStart:v,polygonEnd:v},Uc=mr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Zo.geo.azimuthalEqualArea=function(){return nr(Uc)}).raw=Uc;var jc=mr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},wt);(Zo.geo.azimuthalEquidistant=function(){return nr(jc)}).raw=jc,(Zo.geo.conicConformal=function(){return He(yr)}).raw=yr,(Zo.geo.conicEquidistant=function(){return He(xr)}).raw=xr;var Hc=mr(function(n){return 1/n},Math.atan);(Zo.geo.gnomonic=function(){return nr(Hc)}).raw=Hc,Mr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Sa]},(Zo.geo.mercator=function(){return _r(Mr)}).raw=Mr;var Fc=mr(function(){return 1},Math.asin);(Zo.geo.orthographic=function(){return nr(Fc)}).raw=Fc;var Oc=mr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Zo.geo.stereographic=function(){return nr(Oc)}).raw=Oc,br.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Sa]},(Zo.geo.transverseMercator=function(){var n=_r(br),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])},e([0,0,90])}).raw=br,Zo.geom={},Zo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=bt(e),i=bt(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(Er),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=kr(a),l=kr(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=wr,r=Sr;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)},Zo.geom.polygon=function(n){return sa(n,Yc),n};var Yc=Zo.geom.polygon.prototype=[];Yc.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},Yc.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]},Yc.clip=function(n){for(var t,e,r,u,i,o,a=Nr(n),c=-1,s=this.length-Nr(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],Ar(o,l,u)?(Ar(i,l,u)||n.push(Cr(i,o,l,u)),n.push(o)):Ar(i,l,u)&&n.push(Cr(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Ic,Zc,Vc,Xc,$c,Bc=[],Wc=[];Ur.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(Hr),t.length},Wr.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}},Jr.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=nu(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&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Qr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Qr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(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?nu(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,Kr(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,Qr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Kr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Qr(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,Kr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Qr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Zo.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 tu(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)/ka)*ka,y:Math.round(o(n,t)/ka)*ka,i:t}})}var r=wr,u=Sr,i=r,o=u,a=Jc;return n?t(n):(t.links=function(n){return tu(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 tu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Hr),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&&ru(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=bt(r=n),t):r},t.y=function(n){return arguments.length?(o=bt(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Jc:n,t):a===Jc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Jc?null:a&&a[1]},t)};var Jc=[[-1e6,-1e6],[1e6,1e6]];Zo.geom.delaunay=function(n){return Zo.geom.voronoi().triangles(n)},Zo.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(ua(c-e)+ua(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]=ou()),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=bt(a),M=bt(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=ou();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){au(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=wr,c=Sr;return(o=arguments.length)?(a=uu,c=iu,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)},Zo.interpolateRgb=cu,Zo.interpolateObject=su,Zo.interpolateNumber=lu,Zo.interpolateString=fu;var Gc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Kc=new RegExp(Gc.source,"g");Zo.interpolate=hu,Zo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ia.has(t)||/^(#|rgb\(|hsl\()/.test(t)?cu:fu:t instanceof et?cu:Array.isArray(t)?gu:"object"===e&&isNaN(t)?su:lu)(n,t)}],Zo.interpolateArray=gu;var Qc=function(){return wt},ns=Zo.map({linear:Qc,poly:Mu,quad:function(){return mu},cubic:function(){return yu},sin:function(){return _u},exp:function(){return bu},circle:function(){return wu},elastic:Su,back:ku,bounce:function(){return Eu}}),ts=Zo.map({"in":wt,out:vu,"in-out":du,"out-in":function(n){return du(vu(n))}});Zo.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=ns.get(e)||Qc,r=ts.get(r)||wt,pu(r(e.apply(null,Vo.call(arguments,1))))},Zo.interpolateHcl=Au,Zo.interpolateHsl=Cu,Zo.interpolateLab=Nu,Zo.interpolateRound=zu,Zo.transform=function(n){var t=$o.createElementNS(Zo.ns.prefix.svg,"g");return(Zo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:es)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var es={a:1,b:0,c:0,d:1,e:0,f:0};Zo.interpolateTransform=Du,Zo.layout={},Zo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(ju(n[e]));return t}},Zo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Zo.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(Zo.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=(wa-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},Zo.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=Zo.event.x,n.py=Zo.event.y,a.resume()}var e,r,u,i,o,a={},c=Zo.dispatch("start","tick","end"),s=[1,1],l=.9,f=rs,h=us,g=-30,p=is,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(Vu(t=Zo.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}),Zo.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=Zo.behavior.drag().origin(wt).on("dragstart.force",Ou).on("drag.force",t).on("dragend.force",Yu)),arguments.length?(this.on("mouseover.force",Iu).on("mouseout.force",Zu).call(e),void 0):e},Zo.rebind(a,c,"on")};var rs=20,us=1,is=1/0;Zo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(s=e.call(n,i,i.depth))&&(c=s.length)){for(var c,s,l;--c>=0;)o.push(l=s[c]),l.parent=i,l.depth=i.depth+1;r&&(i.value=0),i.children=s}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Bu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=Gu,e=Wu,r=Ju;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&($u(t,function(n){n.children&&(n.value=0)}),Bu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Zo.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=Zo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Xu(e,r)},Zo.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)/Zo.sum(o),s=Zo.range(i.length);null!=e&&s.sort(e===os?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=os,r=0,u=wa;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 os={};Zo.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=Zo.permute(s,f),l=Zo.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=wt,e=ei,r=ri,u=ti,i=Qu,o=ni;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:as.get(t)||ei,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:cs.get(t)||ri,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 as=Zo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ui),i=n.map(ii),o=Zo.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 Zo.range(n.length).reverse()},"default":ei}),cs=Zo.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:ri});Zo.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[Zo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=si,u=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=bt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ci(n,t)}:bt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Zo.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,Bu(a,function(n){n.r=+l(n.value)}),Bu(a,pi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Bu(a,function(n){n.r+=f}),Bu(a,pi),Bu(a,function(n){n.r-=f})}return mi(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Zo.layout.hierarchy().sort(li),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},Xu(n,e)},Zo.layout.tree=function(){function n(n,u){var l=o.call(this,n,u),f=l[0],h=t(f);if(Bu(h,e),h.parent.m=-h.z,$u(h,r),s)$u(f,i);else{var g=f,p=f,v=f;$u(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);$u(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return l}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){wi(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],s=u.m,l=i.m,f=o.m,h=c.m;o=_i(o),u=Mi(u),o&&u;)c=Mi(c),i=_i(i),i.a=n,r=o.z+f-u.z-s+a(o._,u._),r>0&&(bi(Si(o,n,e),n,r),s+=r,l+=r),f+=o.m,s+=u.m,h+=c.m,l+=i.m;o&&!_i(i)&&(i.t=o,i.m+=f-l),u&&!Mi(c)&&(c.t=u,c.m+=s-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Zo.layout.hierarchy().sort(null).value(null),a=xi,c=[1,1],s=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(s=null==(c=t)?i:null,n):s?null:c},n.nodeSize=function(t){return arguments.length?(s=null==(c=t)?null:i,n):s?c:null},Xu(n,o)},Zo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Bu(c,function(n){var t=n.children;t&&t.length?(n.x=Ei(t),n.y=ki(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ai(c),f=Ci(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Bu(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=Zo.layout.hierarchy().sort(null).value(null),e=xi,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},Xu(n,t)},Zo.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=Zo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ni,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?Ni(t):zi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return zi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ni:"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},Xu(i,a)},Zo.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=Zo.random.normal.apply(Zo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Zo.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}}},Zo.scale={};var ss={floor:wt,ceil:wt};Zo.scale.linear=function(){return Ui([0,1],[0,1],hu,!1)};var ls={s:1,g:1,p:1,r:1,e:1};Zo.scale.log=function(){return Vi(Zo.scale.linear().domain([0,1]),10,!0,[1,10])};var fs=Zo.format(".0e"),hs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Zo.scale.pow=function(){return Xi(Zo.scale.linear(),1,[0,1])},Zo.scale.sqrt=function(){return Zo.scale.pow().exponent(.5)},Zo.scale.ordinal=function(){return Bi([],{t:"range",a:[[]]})},Zo.scale.category10=function(){return Zo.scale.ordinal().range(gs)},Zo.scale.category20=function(){return Zo.scale.ordinal().range(ps)},Zo.scale.category20b=function(){return Zo.scale.ordinal().range(vs)},Zo.scale.category20c=function(){return Zo.scale.ordinal().range(ds)};var gs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(vt),ps=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(vt),vs=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(vt),ds=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(vt);Zo.scale.quantile=function(){return Wi([],[])},Zo.scale.quantize=function(){return Ji(0,1,[0,1])},Zo.scale.threshold=function(){return Gi([.5],[0,1])},Zo.scale.identity=function(){return Ki([0,1])},Zo.svg={},Zo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ms,a=u.apply(this,arguments)+ms,c=(o>a&&(c=o,o=a,a=c),a-o),s=ba>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);
+return c>=ys?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=Qi,e=no,r=to,u=eo;return n.innerRadius=function(e){return arguments.length?(t=bt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=bt(t),n):e},n.startAngle=function(t){return arguments.length?(r=bt(t),n):r},n.endAngle=function(t){return arguments.length?(u=bt(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+ms;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ms=-Sa,ys=wa-ka;Zo.svg.line=function(){return ro(wt)};var xs=Zo.map({linear:uo,"linear-closed":io,step:oo,"step-before":ao,"step-after":co,basis:po,"basis-open":vo,"basis-closed":mo,bundle:yo,cardinal:fo,"cardinal-open":so,"cardinal-closed":lo,monotone:So});xs.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Ms=[0,2/3,1/3,0],_s=[0,1/3,2/3,0],bs=[0,1/6,2/3,1/6];Zo.svg.line.radial=function(){var n=ro(ko);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},ao.reverse=co,co.reverse=ao,Zo.svg.area=function(){return Eo(wt)},Zo.svg.area.radial=function(){var n=Eo(ko);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},Zo.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)+ms,l=s.call(n,u,r)+ms;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>ba)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=gr,o=pr,a=Ao,c=to,s=eo;return n.radius=function(t){return arguments.length?(a=bt(t),n):a},n.source=function(t){return arguments.length?(i=bt(t),n):i},n.target=function(t){return arguments.length?(o=bt(t),n):o},n.startAngle=function(t){return arguments.length?(c=bt(t),n):c},n.endAngle=function(t){return arguments.length?(s=bt(t),n):s},n},Zo.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=gr,e=pr,r=Co;return n.source=function(e){return arguments.length?(t=bt(e),n):t},n.target=function(t){return arguments.length?(e=bt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Zo.svg.diagonal.radial=function(){var n=Zo.svg.diagonal(),t=Co,e=n.projection;return n.projection=function(n){return arguments.length?e(No(t=n)):t},n},Zo.svg.symbol=function(){function n(n,r){return(ws.get(t.call(this,n,r))||To)(e.call(this,n,r))}var t=Lo,e=zo;return n.type=function(e){return arguments.length?(t=bt(e),n):t},n.size=function(t){return arguments.length?(e=bt(t),n):e},n};var ws=Zo.map({circle:To,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*As)),e=t*As;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/Es),e=t*Es/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Zo.svg.symbolTypes=ws.keys();var Ss,ks,Es=Math.sqrt(3),As=Math.tan(30*Aa),Cs=[],Ns=0;Cs.call=pa.call,Cs.empty=pa.empty,Cs.node=pa.node,Cs.size=pa.size,Zo.transition=function(n){return arguments.length?Ss?n.transition():n:ma.transition()},Zo.transition.prototype=Cs,Cs.select=function(n){var t,e,r,u=this.id,i=[];n=b(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__),Po(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return qo(i,u)},Cs.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=w(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])&&Po(u,g,o,i),t.push(u)}return qo(a,o)},Cs.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(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 qo(u,this.id)},Cs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Cs.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?Du:hu,a=Zo.ns.qualify(n);return Ro(this,"attr."+n,t,a.local?i:u)},Cs.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=Zo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Cs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Wo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=hu(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 Ro(this,"style."+n,t,u)},Cs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Wo.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)},Cs.text=function(n){return Ro(this,"text",n,Do)},Cs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Cs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Zo.ease.apply(Zo,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Cs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(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}))},Cs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(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}))},Cs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=ks,u=Ss;Ss=e,P(this,function(t,r,u){ks=t.__transition__[e],n.call(t,t.__data__,r,u)}),ks=r,Ss=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Zo.dispatch("start","end"))).on(n,t)});return this},Cs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ns,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,Po(e,s,i,r)),n.push(e)}return qo(o,i)},Zo.svg.axis=function(){function n(n){n.each(function(){var n,s=Zo.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):wt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",ka),d=Zo.transition(p.exit()).style("opacity",ka).remove(),m=Zo.transition(p.order()).style("opacity",1),y=Ti(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Zo.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=Uo,_.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=Uo,_.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=jo,_.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=jo,_.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=Zo.scale.linear(),r=zs,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 Ls?t+"":zs,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 zs="bottom",Ls={top:1,right:1,bottom:1,left:1};Zo.svg.brush=function(){function n(i){i.each(function(){var i=Zo.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,wt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[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=Zo.transition(i),h=Zo.transition(o);c&&(l=Ti(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ti(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==Zo.event.keyCode&&(C||(x=null,z[0]-=l[1],z[1]-=f[1],C=2),y())}function p(){32==Zo.event.keyCode&&2==C&&(z[0]+=l[1],z[1]+=f[1],C=0,y())}function v(){var n=Zo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Zo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),z[0]=l[+(n[0]<x[0])],z[1]=f[+(n[1]<x[1])]):x=null),E&&d(n,c,0)&&(e(S),u=!0),A&&d(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function d(n,t,e){var r,u,a=Ti(t),c=a[0],s=a[1],p=z[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 m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Zo.select("body").style("cursor",null),L.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=Zo.select(Zo.event.target),w=a.of(_,arguments),S=Zo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=I(),z=Zo.mouse(_),L=Zo.select(Wo).on("keydown.brush",u).on("keyup.brush",p);if(Zo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=l[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);M=[l[1-T]-z[0],f[1-q]-z[1]],z[0]=l[T],z[1]=f[q]}else Zo.event.altKey&&(x=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Zo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=qs[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,Ss?Zo.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=gu(l,t.x),r=gu(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=qs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=qs[!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]},Zo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},qs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Rs=Qa.format=ic.timeFormat,Ds=Rs.utc,Ps=Ds("%Y-%m-%dT%H:%M:%S.%LZ");Rs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ho:Ps,Ho.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ho.toString=Ps.toString,Qa.second=Dt(function(n){return new nc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Qa.seconds=Qa.second.range,Qa.seconds.utc=Qa.second.utc.range,Qa.minute=Dt(function(n){return new nc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Qa.minutes=Qa.minute.range,Qa.minutes.utc=Qa.minute.utc.range,Qa.hour=Dt(function(n){var t=n.getTimezoneOffset()/60;return new nc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Qa.hours=Qa.hour.range,Qa.hours.utc=Qa.hour.utc.range,Qa.month=Dt(function(n){return n=Qa.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Qa.months=Qa.month.range,Qa.months.utc=Qa.month.utc.range;var Us=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],js=[[Qa.second,1],[Qa.second,5],[Qa.second,15],[Qa.second,30],[Qa.minute,1],[Qa.minute,5],[Qa.minute,15],[Qa.minute,30],[Qa.hour,1],[Qa.hour,3],[Qa.hour,6],[Qa.hour,12],[Qa.day,1],[Qa.day,2],[Qa.week,1],[Qa.month,1],[Qa.month,3],[Qa.year,1]],Hs=Rs.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",we]]),Fs={range:function(n,t,e){return Zo.range(Math.ceil(n/e)*e,+t,e).map(Oo)},floor:wt,ceil:wt};js.year=Qa.year,Qa.scale=function(){return Fo(Zo.scale.linear(),js,Hs)};var Os=js.map(function(n){return[n[0].utc,n[1]]}),Ys=Ds.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",we]]);Os.year=Qa.year.utc,Qa.scale.utc=function(){return Fo(Zo.scale.linear(),Os,Ys)},Zo.text=St(function(n){return n.responseText}),Zo.json=function(n,t){return kt(n,"application/json",Yo,t)},Zo.html=function(n,t){return kt(n,"text/html",Io,t)},Zo.xml=St(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Zo):"object"==typeof module&&module.exports&&(module.exports=Zo),this.d3=Zo}();
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/MotionMark/resources/debug-runner/graph.js b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/graph.js
new file mode 100644
index 0000000..4b420e8
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/graph.js
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 2015-2018 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.
+ */
+Utilities.extendObject(window.benchmarkController, {
+    updateGraphData: function(testResult, testData, options)
+    {
+        var element = document.getElementById("test-graph-data");
+        element.innerHTML = "";
+        element._testResult = testResult;
+        element._options = options;
+
+        var margins = new Insets(30, 30, 30, 40);
+        var size = Point.elementClientSize(element);
+        size.y = window.innerHeight - element.offsetTop;
+        size = size.subtract(margins.size);
+
+        // Convert from compact JSON output to propertied data
+        var samplesWithProperties = {};
+        [Strings.json.controller, Strings.json.complexity].forEach(function(seriesName) {
+            var series = testData[Strings.json.samples][seriesName];
+            samplesWithProperties[seriesName] = series.toArray();
+        })
+
+        this._targetFrameRate = options["frame-rate"] || 60;
+
+        this.createTimeGraph(testResult, samplesWithProperties[Strings.json.controller], testData[Strings.json.marks], testData[Strings.json.controller], options, margins, size);
+        this.onTimeGraphOptionsChanged();
+
+        this._showOrHideNodes(true, "form[name=graph-type]");
+        document.forms["graph-type"].elements["type"] = "complexity";
+        this.createComplexityGraph(testResult, testData[Strings.json.controller], samplesWithProperties, options, margins, size);
+        this.onComplexityGraphOptionsChanged();
+
+        this.onGraphTypeChanged();
+    },
+
+    _addRegressionLine: function(parent, xScale, yScale, points, range, isAlongYAxis)
+    {
+        var polygon = [];
+        var line = []
+        var xRange = isAlongYAxis ? range : 0;
+        var yRange = isAlongYAxis ? 0 : range;
+        for (var i = 0; i < points.length; ++i) {
+            var point = points[i];
+            var x;
+            if (xRange instanceof Array)
+                x = xRange[0];
+            else
+                x = point[0] + xRange;
+            polygon.push(xScale(x), yScale(point[1] + yRange));
+            line.push(xScale(point[0]), yScale(point[1]));
+        }
+        for (var i = points.length - 1; i >= 0; --i) {
+            var point = points[i];
+            var x;
+            if (xRange instanceof Array)
+                x = xRange[1];
+            else
+                x = point[0] - xRange;
+            polygon.push(xScale(x), yScale(point[1] - yRange));
+        }
+        parent.append("polygon")
+            .attr("points", polygon.join(","));
+        parent.append("line")
+            .attr("x1", line[0])
+            .attr("y1", line[1])
+            .attr("x2", line[2])
+            .attr("y2", line[3]);
+    },
+
+    _addRegression: function(data, svg, xScale, yScale)
+    {
+        svg.append("circle")
+            .attr("cx", xScale(data.segment1[1][0]))
+            .attr("cy", yScale(data.segment1[1][1]))
+            .attr("r", 3);
+        this._addRegressionLine(svg, xScale, yScale, data.segment1, data.stdev);
+        this._addRegressionLine(svg, xScale, yScale, data.segment2, data.stdev);
+    },
+
+    createComplexityGraph: function(result, timeRegressions, data, options, margins, size)
+    {
+        var svg = d3.select("#test-graph-data").append("svg")
+            .attr("id", "complexity-graph")
+            .attr("class", "hidden")
+            .attr("width", size.width + margins.left + margins.right)
+            .attr("height", size.height + margins.top + margins.bottom)
+            .append("g")
+                .attr("transform", "translate(" + margins.left + "," + margins.top + ")");
+
+        var timeSamples = data[Strings.json.controller];
+
+        var xMin = 100000, xMax = 0;
+        if (timeRegressions) {
+            timeRegressions.forEach(function(regression) {
+                for (var i = regression.startIndex; i <= regression.endIndex; ++i) {
+                    xMin = Math.min(xMin, timeSamples[i].complexity);
+                    xMax = Math.max(xMax, timeSamples[i].complexity);
+                }
+            });
+        } else {
+            xMin = d3.min(timeSamples, function(s) { return s.complexity; });
+            xMax = d3.max(timeSamples, function(s) { return s.complexity; });
+        }
+
+        var xScale = d3.scale.linear()
+            .range([0, size.width])
+            .domain([xMin, xMax]);
+        var yScale = d3.scale.linear()
+            .range([size.height, 0])
+            .domain([1000/(this._targetFrameRate/3), 1000/this._targetFrameRate]);
+
+        var xAxis = d3.svg.axis()
+            .scale(xScale)
+            .orient("bottom");
+        var yAxis = d3.svg.axis()
+            .scale(yScale)
+            .tickValues([1000/20, 1000/25, 1000/30, 1000/35, 1000/40, 1000/45, 1000/50, 1000/55, 1000/60, 1000/90, 1000/120])
+            .tickFormat(function(d) { return (1000 / d).toFixed(0); })
+            .orient("left");
+
+        // x-axis
+        svg.append("g")
+            .attr("class", "x axis")
+            .attr("transform", "translate(0," + size.height + ")")
+            .call(xAxis);
+
+        // y-axis
+        svg.append("g")
+            .attr("class", "y axis")
+            .call(yAxis);
+
+        // time result
+        var mean = svg.append("g")
+            .attr("class", "mean complexity");
+        var timeResult = result[Strings.json.controller];
+        var yMin = yScale.domain()[0], yMax = yScale.domain()[1];
+        this._addRegressionLine(mean, xScale, yScale, [[timeResult.average, yMin], [timeResult.average, yMax]], timeResult.stdev, true);
+
+        // regression
+        this._addRegression(result[Strings.json.complexity], svg.append("g").attr("class", "regression raw"), xScale, yScale);
+
+        var bootstrapResult = result[Strings.json.complexity][Strings.json.bootstrap];
+        if (bootstrapResult) {
+            var histogram = d3.layout.histogram()
+                .bins(xScale.ticks(100))(bootstrapResult.data);
+            var yBootstrapScale = d3.scale.linear()
+                .range([size.height/2, 0])
+                .domain([0, d3.max(histogram, function(d) { return d.y; })]);
+            group = svg.append("g").attr("class", "bootstrap");
+            var bar = group.selectAll(".bar")
+                .data(histogram)
+                .enter().append("g")
+                    .attr("class", "bar")
+                    .attr("transform", function(d) { return "translate(" + xScale(d.x) + "," + yBootstrapScale(d.y) + ")"; });
+            bar.append("rect")
+                .attr("x", 1)
+                .attr("y", size.height/2)
+                .attr("width", xScale(histogram[1].x) - xScale(histogram[0].x) - 1)
+                .attr("height", function(d) { return size.height/2 - yBootstrapScale(d.y); });
+            group = group.append("g").attr("class", "median");
+            this._addRegressionLine(group, xScale, yScale, [[bootstrapResult.median, yMin], [bootstrapResult.median, yMax]], [bootstrapResult.confidenceLow, bootstrapResult.confidenceHigh], true);
+            group.append("circle")
+                .attr("cx", xScale(bootstrapResult.median))
+                .attr("cy", yScale(1000/60))
+                .attr("r", 5);
+        }
+
+        // series
+        group = svg.append("g")
+            .attr("class", "series raw")
+            .selectAll("line")
+                .data(data[Strings.json.complexity])
+                .enter();
+        group.append("line")
+            .attr("x1", function(d) { return xScale(d.complexity) - 3; })
+            .attr("x2", function(d) { return xScale(d.complexity) + 3; })
+            .attr("y1", function(d) { return yScale(d.frameLength) - 3; })
+            .attr("y2", function(d) { return yScale(d.frameLength) + 3; });
+        group.append("line")
+            .attr("x1", function(d) { return xScale(d.complexity) - 3; })
+            .attr("x2", function(d) { return xScale(d.complexity) + 3; })
+            .attr("y1", function(d) { return yScale(d.frameLength) + 3; })
+            .attr("y2", function(d) { return yScale(d.frameLength) - 3; });
+
+        // Cursor
+        var cursorGroup = svg.append("g").attr("class", "cursor hidden");
+        cursorGroup.append("line")
+            .attr("class", "x")
+            .attr("x1", 0)
+            .attr("x2", 0)
+            .attr("y1", yScale(yAxis.scale().domain()[0]) + 10)
+            .attr("y2", yScale(yAxis.scale().domain()[1]));
+        cursorGroup.append("line")
+            .attr("class", "y")
+            .attr("x1", xScale(xAxis.scale().domain()[0]) - 10)
+            .attr("x2", xScale(xAxis.scale().domain()[1]))
+            .attr("y1", 0)
+            .attr("y2", 0)
+        cursorGroup.append("text")
+            .attr("class", "label x")
+            .attr("x", 0)
+            .attr("y", yScale(yAxis.scale().domain()[0]) + 15)
+            .attr("baseline-shift", "-100%")
+            .attr("text-anchor", "middle");
+        cursorGroup.append("text")
+            .attr("class", "label y")
+            .attr("x", xScale(xAxis.scale().domain()[0]) - 15)
+            .attr("y", 0)
+            .attr("baseline-shift", "-30%")
+            .attr("text-anchor", "end");
+        // Area to handle mouse events
+        var area = svg.append("rect")
+            .attr("fill", "transparent")
+            .attr("x", 0)
+            .attr("y", 0)
+            .attr("width", size.width)
+            .attr("height", size.height);
+
+        area.on("mouseover", function() {
+            document.querySelector("#complexity-graph .cursor").classList.remove("hidden");
+        }).on("mouseout", function() {
+            document.querySelector("#complexity-graph .cursor").classList.add("hidden");
+        }).on("mousemove", function() {
+            var location = d3.mouse(this);
+            var location_domain = [xScale.invert(location[0]), yScale.invert(location[1])];
+            cursorGroup.select("line.x")
+                .attr("x1", location[0])
+                .attr("x2", location[0]);
+            cursorGroup.select("text.x")
+                .attr("x", location[0])
+                .text(location_domain[0].toFixed(1));
+            cursorGroup.select("line.y")
+                .attr("y1", location[1])
+                .attr("y2", location[1]);
+            cursorGroup.select("text.y")
+                .attr("y", location[1])
+                .text((1000 / location_domain[1]).toFixed(1));
+        });
+    },
+
+    createTimeGraph: function(result, samples, marks, regressions, options, margins, size)
+    {
+        var svg = d3.select("#test-graph-data").append("svg")
+            .attr("id", "time-graph")
+            .attr("width", size.width + margins.left + margins.right)
+            .attr("height", size.height + margins.top + margins.bottom)
+            .append("g")
+                .attr("transform", "translate(" + margins.left + "," + margins.top + ")");
+
+        // Axis scales
+        var x = d3.scale.linear()
+                .range([0, size.width])
+                .domain([
+                    Math.min(d3.min(samples, function(s) { return s.time; }), 0),
+                    d3.max(samples, function(s) { return s.time; })]);
+        var complexityMax = d3.max(samples, function(s) {
+            if (s.time > 0)
+                return s.complexity;
+            return 0;
+        });
+
+        var yLeft = d3.scale.linear()
+                .range([size.height, 0])
+                .domain([0, complexityMax]);
+        var yRight = d3.scale.linear()
+                .range([size.height, 0])
+                .domain([1000/(this._targetFrameRate/3), 1000/this._targetFrameRate]);
+
+        // Axes
+        var xAxis = d3.svg.axis()
+                .scale(x)
+                .orient("bottom")
+                .tickFormat(function(d) { return (d/1000).toFixed(0); });
+        var yAxisLeft = d3.svg.axis()
+                .scale(yLeft)
+                .orient("left");
+        var yAxisRight = d3.svg.axis()
+                .scale(yRight)
+                .tickValues([1000/20, 1000/25, 1000/30, 1000/35, 1000/40, 1000/45, 1000/50, 1000/55, 1000/60, 1000/90, 1000/120])
+                .tickFormat(function(d) { return (1000/d).toFixed(0); })
+                .orient("right");
+
+        // x-axis
+        svg.append("g")
+            .attr("class", "x axis")
+            .attr("fill", "rgb(235, 235, 235)")
+            .attr("transform", "translate(0," + size.height + ")")
+            .call(xAxis)
+            .append("text")
+                .attr("class", "label")
+                .attr("x", size.width)
+                .attr("y", -6)
+                .attr("fill", "rgb(235, 235, 235)")
+                .style("text-anchor", "end")
+                .text("time");
+
+        // yLeft-axis
+        svg.append("g")
+            .attr("class", "yLeft axis")
+            .attr("fill", "#7ADD49")
+            .call(yAxisLeft)
+            .append("text")
+                .attr("class", "label")
+                .attr("transform", "rotate(-90)")
+                .attr("y", 6)
+                .attr("fill", "#7ADD49")
+                .attr("dy", ".71em")
+                .style("text-anchor", "end")
+                .text(Strings.text.complexity);
+
+        // yRight-axis
+        svg.append("g")
+            .attr("class", "yRight axis")
+            .attr("fill", "#FA4925")
+            .attr("transform", "translate(" + size.width + ", 0)")
+            .call(yAxisRight)
+            .append("text")
+                .attr("class", "label")
+                .attr("x", 9)
+                .attr("y", -20)
+                .attr("fill", "#FA4925")
+                .attr("dy", ".71em")
+                .style("text-anchor", "start")
+                .text(Strings.text.frameRate);
+
+        // marks
+        var yMin = yRight(yAxisRight.scale().domain()[0]);
+        var yMax = yRight(yAxisRight.scale().domain()[1]);
+        for (var markName in marks) {
+            var mark = marks[markName];
+            var xLocation = x(mark.time);
+
+            var markerGroup = svg.append("g")
+                .attr("class", "marker")
+                .attr("transform", "translate(" + xLocation + ", 0)");
+            markerGroup.append("text")
+                .attr("transform", "translate(10, " + (yMin - 10) + ") rotate(-90)")
+                .style("text-anchor", "start")
+                .text(markName)
+            markerGroup.append("line")
+                .attr("x1", 0)
+                .attr("x2", 0)
+                .attr("y1", yMin)
+                .attr("y2", yMax);
+        }
+
+        if (Strings.json.controller in result) {
+            var complexity = result[Strings.json.controller];
+            var regression = svg.append("g")
+                .attr("class", "complexity mean");
+            this._addRegressionLine(regression, x, yLeft, [[samples[0].time, complexity.average], [samples[samples.length - 1].time, complexity.average]], complexity.stdev);
+        }
+        if (Strings.json.frameLength in result) {
+            var frameLength = result[Strings.json.frameLength];
+            var regression = svg.append("g")
+                .attr("class", "fps mean");
+            this._addRegressionLine(regression, x, yRight, [[samples[0].time, 1000/frameLength.average], [samples[samples.length - 1].time, 1000/frameLength.average]], frameLength.stdev);
+        }
+
+        // right-target
+        if (options["controller"] == "adaptive") {
+            var targetFrameLength = 1000 / options["frame-rate"];
+            svg.append("line")
+                .attr("x1", x(0))
+                .attr("x2", size.width)
+                .attr("y1", yRight(targetFrameLength))
+                .attr("y2", yRight(targetFrameLength))
+                .attr("class", "target-fps marker");
+        }
+
+        // Cursor
+        var cursorGroup = svg.append("g").attr("class", "cursor");
+        cursorGroup.append("line")
+            .attr("x1", 0)
+            .attr("x2", 0)
+            .attr("y1", yMin)
+            .attr("y2", yMin);
+
+        // Data
+        var allData = samples;
+        var filteredData = samples.filter(function (sample) {
+            return "smoothedFrameLength" in sample;
+        });
+
+        function addData(name, data, yCoordinateCallback, pointRadius, omitLine) {
+            var svgGroup = svg.append("g").attr("id", name);
+            if (!omitLine) {
+                svgGroup.append("path")
+                    .datum(data)
+                    .attr("d", d3.svg.line()
+                        .x(function(d) { return x(d.time); })
+                        .y(yCoordinateCallback));
+            }
+            svgGroup.selectAll("circle")
+                .data(data)
+                .enter()
+                .append("circle")
+                .attr("cx", function(d) { return x(d.time); })
+                .attr("cy", yCoordinateCallback)
+                .attr("r", pointRadius);
+
+            cursorGroup.append("circle")
+                .attr("class", name)
+                .attr("r", pointRadius + 2);
+        }
+
+        addData("complexity", allData, function(d) { return yLeft(d.complexity); }, 2);
+        addData("rawFPS", allData, function(d) { return yRight(d.frameLength); }, 1);
+        addData("filteredFPS", filteredData, function(d) { return yRight(d.smoothedFrameLength); }, 2);
+
+        // regressions
+        var regressionGroup = svg.append("g")
+            .attr("id", "regressions");
+        if (regressions) {
+            var complexities = [];
+            regressions.forEach(function (regression) {
+                if (!isNaN(regression.segment1[0][1]) && !isNaN(regression.segment1[1][1])) {
+                    regressionGroup.append("line")
+                        .attr("x1", x(regression.segment1[0][0]))
+                        .attr("x2", x(regression.segment1[1][0]))
+                        .attr("y1", yRight(regression.segment1[0][1]))
+                        .attr("y2", yRight(regression.segment1[1][1]));
+                }
+                if (!isNaN(regression.segment2[0][1]) && !isNaN(regression.segment2[1][1])) {
+                    regressionGroup.append("line")
+                        .attr("x1", x(regression.segment2[0][0]))
+                        .attr("x2", x(regression.segment2[1][0]))
+                        .attr("y1", yRight(regression.segment2[0][1]))
+                        .attr("y2", yRight(regression.segment2[1][1]));
+                }
+                // inflection point
+                regressionGroup.append("circle")
+                    .attr("cx", x(regression.segment2[0][0]))
+                    .attr("cy", yRight(regression.segment2[0][1]))
+                    .attr("r", 3);
+                regressionGroup.append("line")
+                    .attr("class", "association")
+                    .attr("stroke-dasharray", "5, 3")
+                    .attr("x1", x(regression.segment2[0][0]))
+                    .attr("x2", x(regression.segment2[0][0]))
+                    .attr("y1", yRight(regression.segment2[0][1]))
+                    .attr("y2", yLeft(regression.complexity));
+                regressionGroup.append("circle")
+                    .attr("cx", x(regression.segment1[1][0]))
+                    .attr("cy", yLeft(regression.complexity))
+                    .attr("r", 5);
+                complexities.push(regression.complexity);
+            });
+            if (complexities.length) {
+                var yLeftComplexities = d3.svg.axis()
+                    .scale(yLeft)
+                    .tickValues(complexities)
+                    .tickSize(10)
+                    .orient("left");
+                svg.append("g")
+                    .attr("class", "complexity yLeft axis")
+                    .call(yLeftComplexities);
+            }
+        }
+
+        // Area to handle mouse events
+        var area = svg.append("rect")
+            .attr("fill", "transparent")
+            .attr("x", 0)
+            .attr("y", 0)
+            .attr("width", size.width)
+            .attr("height", size.height);
+
+        var timeBisect = d3.bisector(function(d) { return d.time; }).right;
+        var statsToHighlight = ["complexity", "rawFPS", "filteredFPS"];
+        area.on("mouseover", function() {
+            document.querySelector("#time-graph .cursor").classList.remove("hidden");
+            document.querySelector("#test-graph nav").classList.remove("hide-data");
+        }).on("mouseout", function() {
+            document.querySelector("#time-graph .cursor").classList.add("hidden");
+            document.querySelector("#test-graph nav").classList.add("hide-data");
+        }).on("mousemove", function() {
+            var form = document.forms["time-graph-options"].elements;
+
+            var mx_domain = x.invert(d3.mouse(this)[0]);
+            var index = Math.min(timeBisect(allData, mx_domain), allData.length - 1);
+            var data = allData[index];
+            var cursor_x = x(data.time);
+            var cursor_y = yAxisRight.scale().domain()[1];
+            var ys = [yRight(yAxisRight.scale().domain()[0]), yRight(yAxisRight.scale().domain()[1])];
+
+            document.querySelector("#test-graph nav .time").textContent = (data.time / 1000).toFixed(4) + "s (" + index + ")";
+            statsToHighlight.forEach(function(name) {
+                var element = document.querySelector("#test-graph nav ." + name);
+                var content = "";
+                var data_y = null;
+                switch (name) {
+                case "complexity":
+                    content = data.complexity;
+                    data_y = yLeft(data.complexity);
+                    break;
+                case "rawFPS":
+                    content = (1000/data.frameLength).toFixed(2);
+                    data_y = yRight(data.frameLength);
+                    break;
+                case "filteredFPS":
+                    if ("smoothedFrameLength" in data) {
+                        content = (1000/data.smoothedFrameLength).toFixed(2);
+                        data_y = yRight(data.smoothedFrameLength);
+                    }
+                    break;
+                }
+
+                element.textContent = content;
+
+                if (form[name].checked && data_y !== null) {
+                    ys.push(data_y);
+                    cursorGroup.select("." + name)
+                        .attr("cx", cursor_x)
+                        .attr("cy", data_y);
+                    document.querySelector("#time-graph .cursor ." + name).classList.remove("hidden");
+                } else
+                    document.querySelector("#time-graph .cursor ." + name).classList.add("hidden");
+            });
+
+            if (form["rawFPS"].checked)
+                cursor_y = Math.max(cursor_y, data.frameLength);
+            cursorGroup.select("line")
+                .attr("x1", cursor_x)
+                .attr("x2", cursor_x)
+                .attr("y1", Math.min.apply(null, ys))
+                .attr("y2", Math.max.apply(null, ys));
+
+        });
+    },
+
+    _showOrHideNodes: function(isShown, selector) {
+        var nodeList = document.querySelectorAll(selector);
+        if (isShown) {
+            for (var i = 0; i < nodeList.length; ++i)
+                nodeList[i].classList.remove("hidden");
+        } else {
+            for (var i = 0; i < nodeList.length; ++i)
+                nodeList[i].classList.add("hidden");
+        }
+    },
+
+    onComplexityGraphOptionsChanged: function() {
+        var form = document.forms["complexity-graph-options"].elements;
+        benchmarkController._showOrHideNodes(form["series-raw"].checked, "#complexity-graph .series.raw");
+        benchmarkController._showOrHideNodes(form["regression-time-score"].checked, "#complexity-graph .mean.complexity");
+        benchmarkController._showOrHideNodes(form["bootstrap-score"].checked, "#complexity-graph .bootstrap");
+        benchmarkController._showOrHideNodes(form["complexity-regression-aggregate-raw"].checked, "#complexity-graph .regression.raw");
+    },
+
+    onTimeGraphOptionsChanged: function() {
+        var form = document.forms["time-graph-options"].elements;
+        benchmarkController._showOrHideNodes(form["markers"].checked, ".marker");
+        benchmarkController._showOrHideNodes(form["averages"].checked, "#test-graph-data .mean");
+        benchmarkController._showOrHideNodes(form["complexity"].checked, "#complexity");
+        benchmarkController._showOrHideNodes(form["rawFPS"].checked, "#rawFPS");
+        benchmarkController._showOrHideNodes(form["filteredFPS"].checked, "#filteredFPS");
+        benchmarkController._showOrHideNodes(form["regressions"].checked, "#regressions");
+    },
+
+    onGraphTypeChanged: function() {
+        var form = document.forms["graph-type"].elements;
+        var testResult = document.getElementById("test-graph-data")._testResult;
+        var isTimeSelected = form["graph-type"].value == "time";
+
+        benchmarkController._showOrHideNodes(isTimeSelected, "#time-graph");
+        benchmarkController._showOrHideNodes(isTimeSelected, "form[name=time-graph-options]");
+        benchmarkController._showOrHideNodes(!isTimeSelected, "#complexity-graph");
+        benchmarkController._showOrHideNodes(!isTimeSelected, "form[name=complexity-graph-options]");
+
+        var score = "", mean = "";
+        if (isTimeSelected) {
+            score = testResult[Strings.json.score].toFixed(2);
+
+            var regression = testResult[Strings.json.controller];
+            mean = [
+                "mean: ",
+                regression.average.toFixed(2),
+                " ± ",
+                regression.stdev.toFixed(2),
+                " (",
+                regression.percent.toFixed(2),
+                "%)"];
+            if (regression.concern) {
+                mean = mean.concat([
+                    ", worst 5%: ",
+                    regression.concern.toFixed(2)]);
+            }
+            mean = mean.join("");
+        } else {
+            var complexityRegression = testResult[Strings.json.complexity];
+            document.getElementById("complexity-regression-aggregate-raw").textContent = complexityRegression.complexity.toFixed(2) + ", ±" + complexityRegression.stdev.toFixed(2) + "ms";
+            var bootstrap = complexityRegression[Strings.json.bootstrap];
+            if (bootstrap) {
+                score = bootstrap.median.toFixed(2);
+                mean = [
+                    (bootstrap.confidencePercentage * 100).toFixed(0),
+                    "% CI: ",
+                    bootstrap.confidenceLow.toFixed(2),
+                    "–",
+                    bootstrap.confidenceHigh.toFixed(2)
+                ].join("");
+            }
+        }
+
+        sectionsManager.setSectionScore("test-graph", score, mean, this._targetFrameRate);
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/resources/debug-runner/motionmark.css b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/motionmark.css
new file mode 100644
index 0000000..b3079b9
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/motionmark.css
@@ -0,0 +1,801 @@
+/*
+ * Copyright (C) 2015-2018 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.
+ */
+body {
+    font-size: initial;
+}
+
+body.showing-intro,
+body.showing-results,
+body.showing-test-graph {
+    background-color: rgb(96, 96, 96);
+    background-image: initial;
+    background-repeat: initial;
+    background-size: initial;
+    animation: initial;
+    will-change: initial;
+
+    color: rgb(235, 235, 235);
+}
+
+section .body {
+    margin-left: 0;
+    max-width: initial;
+    transform: none;
+}
+
+header {
+    margin: 3em 0 1em;
+    text-align: center;
+}
+
+header h1, header h2 {
+    font-size: 3em;
+    margin: 0;
+}
+
+button {
+    transform: none !important;
+    min-width: initial;
+    transition: none;
+    animation: none;
+    will-change: initial;
+
+    display: block;
+    font-size: 1.5em;
+    border: 2px solid rgb(235, 235, 235);
+    color: rgb(235, 235, 235);
+    background: transparent;
+    border-radius: 10px;
+    padding: .5em 2em;
+}
+
+button:hover {
+    background-color: rgba(255, 255, 255, .1);
+    cursor: pointer;
+}
+
+button:active {
+    color: inherit;
+    background-color: rgba(255, 255, 255, .2);
+}
+
+button:disabled {
+    border-color: rgba(235, 235, 235, .5);
+    color: rgba(235, 235, 235, .5);
+}
+
+@media screen and (max-device-width: 414px),
+    screen and (max-device-height: 414px) and (orientation: landscape) {
+    header h1 {
+        font-size: 2em;
+    }
+
+    section {
+        box-sizing: border-box;
+        width: 100%;
+        height: 100%;
+        padding: 0 5px;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+/*                               Tree                                         */
+/* -------------------------------------------------------------------------- */
+
+.tree {
+    padding: 0;
+    list-style-type: none;
+}
+
+.tree .expand-button {
+    position: absolute;
+    clip: rect(0, 0, 0, 0);
+}
+
+.tree .expand-button ~ ul {
+    display: none;
+}
+
+.tree .expand-button:checked ~ ul {
+    display: block;
+}
+
+.tree ul {
+    list-style-type:none;
+}
+
+.tree li {
+    position: relative;
+    padding: 0 0 1em 1em;
+}
+
+.tree ul li {
+    list-style:none;
+    padding: 1em 0 0 0em;
+}
+
+.tree > li:last-child {
+    padding-bottom: 0;
+}
+
+.tree-label {
+  position: relative;
+  display: inline-block;
+}
+
+label.tree-label {
+    cursor: pointer;
+}
+
+.tree > li > label.tree-label:before {
+    position: relative;
+    z-index: 1;
+    float: left;
+    margin: 0 0 0 -2em;
+    width: 1em;
+    height: 1em;
+    content: '\25BA';
+    text-align: center;
+    line-height: 2.5em;
+    font-size: .5em;
+}
+
+.tree > li > :checked ~ label.tree-label:before {
+    content: '\25BC';
+}
+
+.tree .link {
+    cursor: pointer;
+    color: #999;
+    font-style: italic;
+    margin-left: 2em;
+}
+
+@media screen and (max-device-width: 414px),
+    screen and (max-device-height: 414px) and (orientation: landscape) {
+    .tree {
+        padding-left: 1em;
+    }
+    .tree > li > label.tree-label:before {
+        font-size: 1em;
+        margin-left: -1.75em;
+        line-height: 1em;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+/*                                 Intro Section                              */
+/* -------------------------------------------------------------------------- */
+
+#intro {
+    padding: 0;
+    opacity: initial;
+    transition: none;
+}
+
+#intro .body > p {
+    padding: 1em 0;
+    margin: 0 auto;
+    text-align: center;
+}
+
+#intro .start-benchmark {
+    padding: 10vh 0;
+    text-align: center;
+}
+
+#intro .start-benchmark p {
+    color: hsl(11, 72%, 50%);
+    margin-bottom: 1em;
+    -apple-trailing-word: -apple-partially-balanced;
+}
+
+#intro .start-benchmark button {
+    margin: 0 auto;
+}
+
+
+@media screen and (max-device-width: 414px),
+    screen and (max-device-height: 414px) and (orientation: landscape) {
+    #intro.selected {
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        flex-flow: column;
+    }
+
+    #intro p {
+        padding-left: 20px;
+        padding-right: 20px;
+        font-size: 1.5em;
+    }
+}
+
+#intro h2 {
+    font-size: 1.2em;
+}
+
+#intro .body > div:first-of-type {
+    width: 100%;
+    margin: 2em 0 0;
+    flex-direction: row;
+    display: flex;
+    align-content: flex-start;
+}
+
+#suites {
+    padding-left: 15vw;
+    padding-right: 3em;
+    flex: 1 1 30%;
+}
+
+#options {
+    flex: 10 1 auto;
+}
+
+#intro input[type="number"] {
+    width: 50px;
+}
+
+#suites input[type="number"] {
+    display: none;
+    float: right;
+}
+
+#suites input[type="number"].selected {
+    display: inline;
+    margin: 0;
+}
+
+#suites ul ul {
+    font-size: .8em;
+    margin: 0;
+    padding: 0 0 0 1em;
+}
+
+#suites > div {
+    margin: 3em 0;
+}
+
+#drop-target {
+    font-size: 1em;
+    border-radius: 10px;
+    padding: .5em 2em;
+    border: 2px solid rgb(235, 235, 235);
+    color: rgb(235, 235, 235);
+}
+
+#drop-target:hover {
+    background-color: rgba(255, 255, 255, .1);
+    cursor: pointer;
+}
+
+#options ul {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+}
+
+#options h3 {
+    font-size: 1em;
+    font-weight: inherit;
+    margin: 0 0 .3em 0;
+    padding: 0;
+}
+
+#options > form > ul > li {
+    padding: 0 0 1em 0;
+}
+
+#options ul ul {
+    padding: 0;
+}
+
+#options li {
+    padding: .1em 0;
+}
+
+#intro > p {
+    padding: 0 5px 1em;
+    font-size: 1em;
+}
+
+#intro .start-benchmark {
+    padding: 0 0 10vh;
+    margin-top: 0;
+}
+
+#intro .start-benchmark p {
+    color: hsl(11, 100%, 66%);
+}
+
+#frame-rate-detection span {
+    color: red;
+}
+
+@media screen and (max-device-width: 414px),
+    screen and (max-device-height: 414px) and (orientation: landscape) {
+    #intro .body > div:first-of-type {
+        flex-direction: column;
+    }
+
+    #suites,
+    #options {
+        padding: 0 5px;
+        margin: 0;
+        flex: 0 0 auto;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+/*                           Running Section                                  */
+/* -------------------------------------------------------------------------- */
+
+#running-test {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+#progress {
+    display: none;
+}
+
+.display-progress-bar #progress {
+    display: block;
+    position: fixed;
+    top: 0;
+    left: 0;
+    height: 6px;
+    width: 100%;
+    background-color: rgb(128, 128, 128);
+}
+
+.display-progress-bar #progress-completed {
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 6px;
+    width: 0;
+    background-color: rgb(235, 96, 32);
+}
+
+body.showing-test-container.tiles-big {
+    overflow: hidden;
+}
+
+body.showing-test-container.tiles-classic {
+    width: 3000px;
+    height: 3000px;
+    overflow: scroll;
+}
+
+/* -------------------------------------------------------------------------- */
+/*                           Results Section                                  */
+/* -------------------------------------------------------------------------- */
+
+#results {
+    text-align: center;
+}
+
+#results h1, #test-graph h1 {
+    font-size: 2em;
+}
+
+#results button.small-button {
+    border: 1px solid rgba(235, 235, 235, .9);
+    color: rgba(235, 235, 235, .9);
+    border-radius: 2px;
+    padding: 1px 4px;
+    margin: 0 0 0 1em;
+    font-size: 9px;
+}
+
+#results button.small-button:active {
+    background-color: rgba(235, 235, 235, .2);
+    color: inherit;
+}
+
+#results .score,
+#test-graph .score {
+    font-size: 3em;
+    font-weight: bold;
+    margin: 0;
+}
+
+#results .confidence,
+#test-graph .confidence {
+    margin-top: 0;
+    margin-bottom: 1em;
+    font-size: 1.5em;
+    font-weight: 400;
+    text-indent: inherit;
+    color: inherit;
+}
+
+#results-tables {
+    direction: rtl;
+
+    display: flex;
+
+    align-items: center;
+    justify-content: center;
+
+    margin: 3em 0;
+}
+
+#results .table-container > div {
+    margin-left: 0;
+}
+
+#results #results-score {
+    float: initial;
+}
+
+#results #results-header {
+    width: initial;
+    position: initial;
+}
+
+#results table {
+    direction: ltr;
+    min-width: initial;
+}
+
+#results table td.suites-separator {
+    padding: .5em 0;
+}
+
+#results table tr:nth-child(even) {
+    background-color: transparent;
+}
+
+#results th {
+    padding: .5em 0;
+}
+
+#results tr td {
+    padding: .25em 0;
+}
+
+#results-header td, #results-header th {
+    text-align: left;
+}
+#results-header tr td {
+    padding-right: 1em;
+}
+#results-score td, #results-score th {
+    text-align: right;
+}
+#results .body > button {
+    margin: 1.5em auto .5em;
+}
+#results footer {
+    padding-bottom: 10vh;
+}
+
+@media screen and (max-device-width: 414px),
+    screen and (max-device-height: 414px) and (orientation: landscape) {
+    #results.selected {
+        padding: 0 20px;
+    }
+}
+
+#overlay {
+    background: rgba(0, 0, 10, .8);
+}
+
+@supports (-webkit-backdrop-filter: blur(10px)) {
+    #overlay {
+        background: rgba(0, 0, 10, .4);
+    }
+}
+
+#overlay > div div {
+    border: 1px solid rgb(241, 241, 241);
+}
+
+#overlay button {
+    margin: 2em auto;
+    border-color: rgb(241, 241, 241);
+    color: rgb(241, 241, 241);
+}
+
+#overlay button:hover {
+    background-color: rgba(255, 255, 255, .1);
+}
+
+#overlay button:active {
+    background-color: rgba(255, 255, 255, .2);
+}
+
+#results-data .average {
+    padding-left: 1em;
+    text-align: right;
+}
+
+#results-data .stdev {
+    text-align: left;
+    padding-left: .25em;
+}
+
+#results-data .left {
+    text-align: left;
+}
+
+#results-data .right {
+    text-align: right;
+}
+
+#results-data .pad-left {
+    padding-left: 1em;
+}
+
+#results-data .pad-right {
+    padding-right: .25em;
+}
+
+#results-data .small {
+    font-size: .8em;
+}
+
+#results-tables td.noisy-results {
+    color: rgb(255, 104, 104);
+}
+
+#results-tables div {
+    direction: ltr;
+    display: flex;
+    flex-direction: row;
+}
+
+#test-graph {
+    flex: 1 0 calc(100% - 40px);
+}
+
+#test-graph h1 {
+    margin-bottom: 0;
+}
+
+#test-graph header {
+    position: relative;
+    text-align:center;
+}
+
+#test-graph header button {
+    position: absolute;
+    top: 0;
+    left: 0;
+    border-width: 1px;
+    font-size: 1em;
+    padding: .5em 1em;
+}
+
+#test-graph .score, #test-graph .confidence {
+    margin: 0;
+}
+
+#test-graph nav {
+    position: absolute;
+    top: 1.5em;
+    right: 0;
+    font-size: .7em;
+    width: 28em;
+}
+
+#test-graph nav ul {
+    margin: 0 30px 1em 0;
+    padding: 0;
+    list-style: none;
+}
+
+#test-graph nav li {
+    padding: .1em 0;
+}
+
+#test-graph nav li > span {
+    float: right;
+}
+
+#test-graph nav.hide-data span {
+    display: none;
+}
+
+/* -------------------------------------------------------------------------- */
+/*                           Graph Section                                    */
+/* -------------------------------------------------------------------------- */
+
+#test-graph-data {
+    z-index: 1;
+    font: 10px sans-serif;
+    color: rgb(235, 235, 235);
+}
+
+#test-graph-data > svg {
+    fill: none;
+    overflow: visible;
+}
+
+.axis path,
+.axis line {
+    fill: none;
+    stroke: #999999;
+    shape-rendering: crispEdges;
+}
+
+.axis text {
+    fill: #999;
+}
+
+.yLeft.axis text {
+    fill: #7add49;
+}
+.yLeft.axis path,
+.yLeft.axis line {
+    stroke: #7add49;
+}
+.yRight.axis text {
+    fill: #fa4925;
+}
+.yRight.axis path,
+.yRight.axis line {
+    stroke: #fa4925;
+}
+
+.axis.complexity .tick line {
+    stroke: rgba(200, 200, 200, .6);
+    stroke-width: 2px;
+}
+
+.axis.complexity .domain,
+.axis.complexity text {
+    stroke: transparent;
+    fill: transparent;
+}
+
+.marker line {
+    stroke: #5493D6;
+}
+
+.marker text {
+    fill: #999;
+}
+
+.mean.complexity line {
+    stroke: hsla(100, 69%, 58%, .8);
+    stroke-width: 2px;
+}
+
+.mean.complexity polygon {
+    fill: hsla(100, 69%, 58%, .05);
+}
+
+.target-fps {
+    stroke: rgba(250, 73, 37, .4);
+    stroke-width: 1px;
+    stroke-dasharray: 10, 10;
+}
+
+.mean.fps line {
+    stroke: hsla(10, 96%, 56%, .8);
+    stroke-width: 2px;
+}
+
+.mean.fps polygon {
+    fill: hsla(10, 96%, 56%, .1);
+}
+
+#regressions line {
+    stroke: rgba(200, 200, 200, .8);
+    stroke-width: 2px;
+}
+
+#regressions line.association {
+    stroke-width: 1px;
+}
+
+#regressions circle {
+    fill: rgba(200, 200, 200, .8);
+}
+
+.cursor line {
+    stroke: rgb(250, 250, 250);
+    stroke-width: 1px;
+}
+
+.cursor circle,
+.cursor text {
+    fill: rgb(250, 250, 250);
+}
+
+#complexity path {
+    stroke: rgba(122, 221, 73, .7);
+    stroke-width: 2px;
+}
+
+#complexity circle {
+    fill: rgb(122, 221, 73);
+}
+
+#filteredFPS path {
+    stroke: hsla(30, 96%, 56%, .7);
+    stroke-width: 1px;
+}
+
+#filteredFPS circle {
+    fill: hsl(30, 96%, 56%);
+}
+
+#rawFPS path {
+    stroke: rgba(250, 73, 37, .7);
+    stroke-width: 1px;
+}
+
+#rawFPS circle {
+    fill: rgb(250, 73, 37);
+}
+
+#complexity-graph .regression line {
+    stroke: rgba(253, 253, 253, .8);
+    stroke-width: 2px;
+}
+
+#complexity-graph .regression circle {
+    fill: rgba(253, 253, 253, .8);
+}
+
+#complexity-graph .regression polygon {
+    fill: rgba(253, 253, 253, .2);
+}
+
+#complexity-graph .raw.series line {
+    stroke: hsla(30, 96%, 56%, .3);
+    stroke-width: 1px;
+}
+
+#complexity-graph .raw.regression line {
+    stroke: rgba(30, 96%, 86%, .6);
+}
+
+#complexity-graph .raw.regression polygon {
+    stroke: rgba(30, 96%, 86%, .05);
+}
+
+#complexity-graph .bootstrap .bar {
+    fill: hsla(260, 56%, 66%, .4);
+}
+
+#complexity-graph .bootstrap .median line {
+    stroke: hsla(300, 56%, 66%, .8);
+    stroke-width: 2px;
+}
+
+#complexity-graph .bootstrap .median circle {
+    fill: hsla(300, 56%, 66%, .8);
+}
+
+#complexity-graph .bootstrap .median polygon {
+    fill: hsla(240, 56%, 66%, .4);
+}
diff --git a/third_party/blink/perf_tests/MotionMark/resources/debug-runner/motionmark.js b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/motionmark.js
new file mode 100644
index 0000000..5df2466
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/motionmark.js
@@ -0,0 +1,728 @@
+/*
+ * Copyright (C) 2015-2020 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.
+ */
+ProgressBar = Utilities.createClass(
+    function(element, ranges)
+    {
+        this._element = element;
+        this._ranges = ranges;
+        this._currentRange = 0;
+        this._updateElement();
+    }, {
+
+    _updateElement: function()
+    {
+        this._element.style.width = (this._currentRange * (100 / this._ranges)) + "%";
+    },
+
+    incrementRange: function()
+    {
+        ++this._currentRange;
+        this._updateElement();
+    }
+});
+
+DeveloperResultsTable = Utilities.createSubclass(ResultsTable,
+    function(element, headers)
+    {
+        ResultsTable.call(this, element, headers);
+    }, {
+
+    _addGraphButton: function(td, testName, testResult, testData)
+    {
+        var button = Utilities.createElement("button", { class: "small-button" }, td);
+        button.textContent = Strings.text.graph + "…";
+        button.testName = testName;
+        button.testResult = testResult;
+        button.testData = testData;
+
+        button.addEventListener("click", function(e) {
+            benchmarkController.showTestGraph(e.target.testName, e.target.testResult, e.target.testData);
+        });
+    },
+
+    _isNoisyMeasurement: function(jsonExperiment, data, measurement, options)
+    {
+        const percentThreshold = 10;
+        const averageThreshold = 2;
+
+        if (measurement == Strings.json.measurements.percent)
+            return data[Strings.json.measurements.percent] >= percentThreshold;
+
+        if (jsonExperiment == Strings.json.frameLength && measurement == Strings.json.measurements.average)
+            return Math.abs(data[Strings.json.measurements.average] - options["frame-rate"]) >= averageThreshold;
+
+        return false;
+    },
+
+    _addTest: function(testName, testResult, options, testData)
+    {
+        var row = Utilities.createElement("tr", {}, this.element);
+
+        var isNoisy = false;
+        [Strings.json.complexity, Strings.json.frameLength].forEach(function (experiment) {
+            var data = testResult[experiment];
+            for (var measurement in data) {
+                if (this._isNoisyMeasurement(experiment, data, measurement, options))
+                    isNoisy = true;
+            }
+        }, this);
+
+        this._flattenedHeaders.forEach(function (header) {
+            var className = "";
+            if (header.className) {
+                if (typeof header.className == "function")
+                    className = header.className(testResult, options);
+                else
+                    className = header.className;
+            }
+
+            if (header.text == Strings.text.testName) {
+                if (isNoisy)
+                    className += " noisy-results";
+                var td = Utilities.createElement("td", { class: className }, row);
+                td.textContent = testName;
+                return;
+            }
+
+            var td = Utilities.createElement("td", { class: className }, row);
+            if (header.title == Strings.text.graph) {
+                this._addGraphButton(td, testName, testResult, testData);
+            } else if (!("text" in header)) {
+                td.textContent = testResult[header.title];
+            } else if (typeof header.text == "string") {
+                var data = testResult[header.text];
+                if (typeof data == "number")
+                    data = data.toFixed(2);
+                td.textContent = data;
+            } else
+                td.textContent = header.text(testResult);
+        }, this);
+    }
+});
+
+Utilities.extendObject(window.benchmarkRunnerClient, {
+    testsCount: null,
+    progressBar: null,
+
+    initialize: function(suites, options)
+    {
+        this.testsCount = this.iterationCount * suites.reduce(function (count, suite) { return count + suite.tests.length; }, 0);
+        this.options = options;
+    },
+
+    willStartFirstIteration: function()
+    {
+        this.results = new ResultsDashboard(Strings.version, this.options);
+        this.progressBar = new ProgressBar(document.getElementById("progress-completed"), this.testsCount);
+    },
+
+    didRunTest: function(testData)
+    {
+        this.progressBar.incrementRange();
+        this.results.calculateScore(testData);
+    }
+});
+
+Utilities.extendObject(window.sectionsManager, {
+    setSectionHeader: function(sectionIdentifier, title)
+    {
+        document.querySelector("#" + sectionIdentifier + " h1").textContent = title;
+    },
+
+    populateTable: function(tableIdentifier, headers, dashboard)
+    {
+        var table = new DeveloperResultsTable(document.getElementById(tableIdentifier), headers);
+        table.showIterations(dashboard);
+    }
+});
+
+window.optionsManager =
+{
+    valueForOption: function(name)
+    {
+        var formElement = document.forms["benchmark-options"].elements[name];
+        if (formElement.type == "checkbox")
+            return formElement.checked;
+        else if (formElement.constructor === HTMLCollection) {
+            for (var i = 0; i < formElement.length; ++i) {
+                var radio = formElement[i];
+                if (radio.checked)
+                    return formElement.value;
+            }
+            return null;
+        }
+        return formElement.value;
+    },
+
+    updateUIFromLocalStorage: function()
+    {
+        var formElements = document.forms["benchmark-options"].elements;
+
+        for (var i = 0; i < formElements.length; ++i) {
+            var formElement = formElements[i];
+            var name = formElement.id || formElement.name;
+            var type = formElement.type;
+
+            var value = localStorage.getItem(name);
+            if (value === null)
+                continue;
+
+            if (type == "number")
+                formElements[name].value = +value;
+            else if (type == "checkbox")
+                formElements[name].checked = value == "true";
+            else if (type == "radio")
+                formElements[name].value = value;
+        }
+    },
+
+    updateLocalStorageFromUI: function()
+    {
+        var formElements = document.forms["benchmark-options"].elements;
+        var options = {};
+
+        for (var i = 0; i < formElements.length; ++i) {
+            var formElement = formElements[i];
+            var name = formElement.id || formElement.name;
+            var type = formElement.type;
+
+            if (type == "number")
+                options[name] = +formElement.value;
+            else if (type == "checkbox")
+                options[name] = formElement.checked;
+            else if (type == "radio") {
+                var radios = formElements[name];
+                if (radios.constructor === HTMLCollection) {
+                    for (var j = 0; j < radios.length; ++j) {
+                        var radio = radios[j];
+                        if (radio.checked) {
+                            options[name] = radio.value;
+                            break;
+                        }
+                    }
+                } else
+                    options[name] = formElements[name].value;
+            }
+
+            try {
+                localStorage.setItem(name, options[name]);
+            } catch (e) {}
+        }
+
+        return options;
+    },
+
+    updateDisplay: function()
+    {
+        document.body.classList.remove("display-minimal");
+        document.body.classList.remove("display-progress-bar");
+
+        document.body.classList.add("display-" + optionsManager.valueForOption("display"));
+    },
+
+    updateTiles: function()
+    {
+        document.body.classList.remove("tiles-big");
+        document.body.classList.remove("tiles-classic");
+
+        document.body.classList.add("tiles-" + optionsManager.valueForOption("tiles"));
+    }
+};
+
+window.suitesManager =
+{
+    _treeElement: function()
+    {
+        return document.querySelector("#suites > .tree");
+    },
+
+    _suitesElements: function()
+    {
+        return document.querySelectorAll("#suites > ul > li");
+    },
+
+    _checkboxElement: function(element)
+    {
+        return element.querySelector("input[type='checkbox']:not(.expand-button)");
+    },
+
+    _editElement: function(element)
+    {
+        return element.querySelector("input[type='number']");
+    },
+
+    _editsElements: function()
+    {
+        return document.querySelectorAll("#suites input[type='number']");
+    },
+
+    _localStorageNameForTest: function(suiteName, testName)
+    {
+        return suiteName + "/" + testName;
+    },
+
+    _updateSuiteCheckboxState: function(suiteCheckbox)
+    {
+        var numberEnabledTests = 0;
+        suiteCheckbox.testsElements.forEach(function(testElement) {
+            var testCheckbox = this._checkboxElement(testElement);
+            if (testCheckbox.checked)
+                ++numberEnabledTests;
+        }, this);
+        suiteCheckbox.checked = numberEnabledTests > 0;
+        suiteCheckbox.indeterminate = numberEnabledTests > 0 && numberEnabledTests < suiteCheckbox.testsElements.length;
+    },
+
+    isAtLeastOneTestSelected: function()
+    {
+        var suitesElements = this._suitesElements();
+
+        for (var i = 0; i < suitesElements.length; ++i) {
+            var suiteElement = suitesElements[i];
+            var suiteCheckbox = this._checkboxElement(suiteElement);
+
+            if (suiteCheckbox.checked)
+                return true;
+        }
+
+        return false;
+    },
+
+    _onChangeSuiteCheckbox: function(event)
+    {
+        var selected = event.target.checked;
+        event.target.testsElements.forEach(function(testElement) {
+            var testCheckbox = this._checkboxElement(testElement);
+            testCheckbox.checked = selected;
+        }, this);
+        benchmarkController.updateStartButtonState();
+    },
+
+    _onChangeTestCheckbox: function(suiteCheckbox)
+    {
+        this._updateSuiteCheckboxState(suiteCheckbox);
+        benchmarkController.updateStartButtonState();
+    },
+
+    _createSuiteElement: function(treeElement, suite, id)
+    {
+        var suiteElement = Utilities.createElement("li", {}, treeElement);
+        var expand = Utilities.createElement("input", { type: "checkbox",  class: "expand-button", id: id }, suiteElement);
+        var label = Utilities.createElement("label", { class: "tree-label", for: id }, suiteElement);
+
+        var suiteCheckbox = Utilities.createElement("input", { type: "checkbox" }, label);
+        suiteCheckbox.suite = suite;
+        suiteCheckbox.onchange = this._onChangeSuiteCheckbox.bind(this);
+        suiteCheckbox.testsElements = [];
+
+        label.appendChild(document.createTextNode(" " + suite.name));
+        return suiteElement;
+    },
+
+    _createTestElement: function(listElement, test, suiteCheckbox)
+    {
+        var testElement = Utilities.createElement("li", {}, listElement);
+        var span = Utilities.createElement("label", { class: "tree-label" }, testElement);
+
+        var testCheckbox = Utilities.createElement("input", { type: "checkbox" }, span);
+        testCheckbox.test = test;
+        testCheckbox.onchange = function(event) {
+            this._onChangeTestCheckbox(event.target.suiteCheckbox);
+        }.bind(this);
+        testCheckbox.suiteCheckbox = suiteCheckbox;
+
+        suiteCheckbox.testsElements.push(testElement);
+        span.appendChild(document.createTextNode(" " + test.name + " "));
+
+        testElement.appendChild(document.createTextNode(" "));
+        var link = Utilities.createElement("span", {}, testElement);
+        link.classList.add("link");
+        link.textContent = "link";
+        link.suiteName = Utilities.stripUnwantedCharactersForURL(suiteCheckbox.suite.name);
+        link.testName = test.name;
+        link.onclick = function(event) {
+            var element = event.target;
+            var title = "Link to run “" + element.testName + "” with current options:";
+            var url = location.href.split(/[?#]/)[0];
+            var options = optionsManager.updateLocalStorageFromUI();
+            Utilities.extendObject(options, {
+                "suite-name": element.suiteName,
+                "test-name": Utilities.stripUnwantedCharactersForURL(element.testName)
+            });
+            var complexity = suitesManager._editElement(element.parentNode).value;
+            if (complexity)
+                options.complexity = complexity;
+            prompt(title, url + Utilities.convertObjectToQueryString(options));
+        };
+
+        var complexity = Utilities.createElement("input", { type: "number" }, testElement);
+        complexity.relatedCheckbox = testCheckbox;
+        complexity.oninput = function(event) {
+            var relatedCheckbox = event.target.relatedCheckbox;
+            relatedCheckbox.checked = true;
+            this._onChangeTestCheckbox(relatedCheckbox.suiteCheckbox);
+        }.bind(this);
+        return testElement;
+    },
+
+    createElements: function()
+    {
+        var treeElement = this._treeElement();
+
+        Suites.forEach(function(suite, index) {
+            var suiteElement = this._createSuiteElement(treeElement, suite, "suite-" + index);
+            var listElement = Utilities.createElement("ul", {}, suiteElement);
+            var suiteCheckbox = this._checkboxElement(suiteElement);
+
+            suite.tests.forEach(function(test) {
+                this._createTestElement(listElement, test, suiteCheckbox);
+            }, this);
+        }, this);
+    },
+
+    updateEditsElementsState: function()
+    {
+        var editsElements = this._editsElements();
+        var showComplexityInputs = optionsManager.valueForOption("controller") == "fixed";
+
+        for (var i = 0; i < editsElements.length; ++i) {
+            var editElement = editsElements[i];
+            if (showComplexityInputs)
+                editElement.classList.add("selected");
+            else
+                editElement.classList.remove("selected");
+        }
+    },
+
+    updateUIFromLocalStorage: function()
+    {
+        var suitesElements = this._suitesElements();
+
+        for (var i = 0; i < suitesElements.length; ++i) {
+            var suiteElement = suitesElements[i];
+            var suiteCheckbox = this._checkboxElement(suiteElement);
+            var suite = suiteCheckbox.suite;
+
+            suiteCheckbox.testsElements.forEach(function(testElement) {
+                var testCheckbox = this._checkboxElement(testElement);
+                var testEdit = this._editElement(testElement);
+                var test = testCheckbox.test;
+
+                var str = localStorage.getItem(this._localStorageNameForTest(suite.name, test.name));
+                if (str === null)
+                    return;
+
+                var value = JSON.parse(str);
+                testCheckbox.checked = value.checked;
+                testEdit.value = value.complexity;
+            }, this);
+
+            this._updateSuiteCheckboxState(suiteCheckbox);
+        }
+
+        benchmarkController.updateStartButtonState();
+    },
+
+    updateLocalStorageFromUI: function()
+    {
+        var suitesElements = this._suitesElements();
+        var suites = [];
+
+        for (var i = 0; i < suitesElements.length; ++i) {
+            var suiteElement = suitesElements[i];
+            var suiteCheckbox = this._checkboxElement(suiteElement);
+            var suite = suiteCheckbox.suite;
+
+            var tests = [];
+            suiteCheckbox.testsElements.forEach(function(testElement) {
+                var testCheckbox = this._checkboxElement(testElement);
+                var testEdit = this._editElement(testElement);
+                var test = testCheckbox.test;
+
+                if (testCheckbox.checked) {
+                    test.complexity = testEdit.value;
+                    tests.push(test);
+                }
+
+                var value = { checked: testCheckbox.checked, complexity: testEdit.value };
+                try {
+                    localStorage.setItem(this._localStorageNameForTest(suite.name, test.name), JSON.stringify(value));
+                } catch (e) {}
+            }, this);
+
+            if (tests.length)
+                suites.push(new Suite(suiteCheckbox.suite.name, tests));
+        }
+
+        return suites;
+    },
+
+    suitesFromQueryString: function(suiteName, testName)
+    {
+        suiteName = decodeURIComponent(suiteName);
+        testName = decodeURIComponent(testName);
+
+        var suites = [];
+        var suiteRegExp = new RegExp(suiteName, "i");
+        var testRegExp = new RegExp(testName, "i");
+
+        for (var i = 0; i < Suites.length; ++i) {
+            var suite = Suites[i];
+            if (!Utilities.stripUnwantedCharactersForURL(suite.name).match(suiteRegExp))
+                continue;
+
+            var test;
+            for (var j = 0; j < suite.tests.length; ++j) {
+                suiteTest = suite.tests[j];
+                if (Utilities.stripUnwantedCharactersForURL(suiteTest.name).match(testRegExp)) {
+                    test = suiteTest;
+                    break;
+                }
+            }
+
+            if (!test)
+                continue;
+
+            suites.push(new Suite(suiteName, [test]));
+        };
+
+        return suites;
+    },
+
+    updateLocalStorageFromJSON: function(results)
+    {
+        for (var suiteName in results[Strings.json.results.tests]) {
+            var suiteResults = results[Strings.json.results.tests][suiteName];
+            for (var testName in suiteResults) {
+                var testResults = suiteResults[testName];
+                var data = testResults[Strings.json.controller];
+                var complexity = Math.round(data[Strings.json.measurements.average]);
+
+                var value = { checked: true, complexity: complexity };
+                try {
+                    localStorage.setItem(this._localStorageNameForTest(suiteName, testName), JSON.stringify(value));
+                } catch (e) {}
+            }
+        }
+    }
+}
+
+Utilities.extendObject(window.benchmarkController, {
+    initialize: function()
+    {
+        document.title = Strings.text.title.replace("%s", Strings.version);
+        document.querySelectorAll(".version").forEach(function(e) {
+            e.textContent = Strings.version;
+        });
+
+        document.forms["benchmark-options"].addEventListener("change", benchmarkController.onBenchmarkOptionsChanged, true);
+        document.forms["graph-type"].addEventListener("change", benchmarkController.onGraphTypeChanged, true);
+        document.forms["time-graph-options"].addEventListener("change", benchmarkController.onTimeGraphOptionsChanged, true);
+        document.forms["complexity-graph-options"].addEventListener("change", benchmarkController.onComplexityGraphOptionsChanged, true);
+        optionsManager.updateUIFromLocalStorage();
+        optionsManager.updateDisplay();
+        optionsManager.updateTiles();
+
+        if (benchmarkController.startBenchmarkImmediatelyIfEncoded())
+            return;
+
+        benchmarkController.addOrientationListenerIfNecessary();
+        suitesManager.createElements();
+        suitesManager.updateUIFromLocalStorage();
+        suitesManager.updateEditsElementsState();
+
+        benchmarkController.detectSystemFrameRate();
+
+        var dropTarget = document.getElementById("drop-target");
+        function stopEvent(e) {
+            e.stopPropagation();
+            e.preventDefault();
+        }
+        dropTarget.addEventListener("dragenter", stopEvent, false);
+        dropTarget.addEventListener("dragover", stopEvent, false);
+        dropTarget.addEventListener("dragleave", stopEvent, false);
+        dropTarget.addEventListener("drop", function (e) {
+            e.stopPropagation();
+            e.preventDefault();
+
+            if (!e.dataTransfer.files.length)
+                return;
+
+            var file = e.dataTransfer.files[0];
+
+            var reader = new FileReader();
+            reader.filename = file.name;
+            reader.onload = function(e) {
+                var run = JSON.parse(e.target.result);
+                if (run.debugOutput instanceof Array)
+                    run = run.debugOutput[0];
+                if (!("version" in run))
+                    run.version = "1.0";
+                benchmarkRunnerClient.results = new ResultsDashboard(run.version, run.options, run.data);
+                benchmarkController.showResults();
+            };
+
+            reader.readAsText(file);
+            document.title = "File: " + reader.filename;
+        }, false);
+    },
+
+    updateStartButtonState: function()
+    {
+        var startButton = document.getElementById("run-benchmark");
+        if ("isInLandscapeOrientation" in this && !this.isInLandscapeOrientation) {
+            startButton.disabled = true;
+            return;
+        }
+        startButton.disabled = !suitesManager.isAtLeastOneTestSelected();
+    },
+
+    onBenchmarkOptionsChanged: function(event)
+    {
+        switch (event.target.name) {
+        case "controller":
+            suitesManager.updateEditsElementsState();
+            break;
+        case "display":
+            optionsManager.updateDisplay();
+            break;
+        case "tiles":
+            optionsManager.updateTiles();
+            break;
+        }
+    },
+
+    startBenchmark: function()
+    {
+        benchmarkController.determineCanvasSize();
+        benchmarkController.options = Utilities.mergeObjects(this.benchmarkDefaultParameters, optionsManager.updateLocalStorageFromUI());
+        benchmarkController.suites = suitesManager.updateLocalStorageFromUI();
+        this._startBenchmark(benchmarkController.suites, benchmarkController.options, "running-test");
+    },
+
+    startBenchmarkImmediatelyIfEncoded: function()
+    {
+        benchmarkController.options = Utilities.convertQueryStringToObject(location.search);
+        if (!benchmarkController.options)
+            return false;
+
+        benchmarkController.suites = suitesManager.suitesFromQueryString(benchmarkController.options["suite-name"], benchmarkController.options["test-name"]);
+        if (!benchmarkController.suites.length)
+            return false;
+
+        setTimeout(function() {
+            this._startBenchmark(benchmarkController.suites, benchmarkController.options, "running-test");
+        }.bind(this), 0);
+        return true;
+    },
+
+    restartBenchmark: function()
+    {
+        this._startBenchmark(benchmarkController.suites, benchmarkController.options, "running-test");
+    },
+
+    showResults: function()
+    {
+        if (!this.addedKeyEvent) {
+            document.addEventListener("keypress", this.handleKeyPress, false);
+            this.addedKeyEvent = true;
+        }
+
+        var dashboard = benchmarkRunnerClient.results;
+        if (dashboard.options["controller"] == "ramp")
+            Headers.details[3].disabled = true;
+        else {
+            Headers.details[1].disabled = true;
+            Headers.details[4].disabled = true;
+        }
+
+        if (dashboard.options[Strings.json.configuration]) {
+            document.body.classList.remove("small", "medium", "large");
+            document.body.classList.add(dashboard.options[Strings.json.configuration]);
+        }
+
+        var score = dashboard.score;
+        var confidence = ((dashboard.scoreLowerBound / score - 1) * 100).toFixed(2) +
+            "% / +" + ((dashboard.scoreUpperBound / score - 1) * 100).toFixed(2) + "%";
+        var fps = dashboard._systemFrameRate;
+        sectionsManager.setSectionVersion("results", dashboard.version);
+        sectionsManager.setSectionScore("results", score.toFixed(2), confidence, fps);
+        sectionsManager.populateTable("results-header", Headers.testName, dashboard);
+        sectionsManager.populateTable("results-score", Headers.score, dashboard);
+        sectionsManager.populateTable("results-data", Headers.details, dashboard);
+        sectionsManager.showSection("results", true);
+
+        suitesManager.updateLocalStorageFromJSON(dashboard.results[0]);
+    },
+
+    showTestGraph: function(testName, testResult, testData)
+    {
+        sectionsManager.setSectionHeader("test-graph", testName);
+        sectionsManager.showSection("test-graph", true);
+        this.updateGraphData(testResult, testData, benchmarkRunnerClient.results.options);
+    },
+    detectSystemFrameRate: function()
+    {
+        let last = 0;
+        let average = 0;
+        let count = 0;
+
+        const finish = function()
+        {
+            const commonFrameRates = [15, 30, 45, 60, 90, 120, 144];
+            const distanceFromFrameRates = commonFrameRates.map(rate => {
+                return Math.abs(Math.round(rate - average));
+            });
+            let shortestDistance = Number.MAX_VALUE;
+            let targetFrameRate = undefined;
+            for (let i = 0; i < commonFrameRates.length; i++) {
+                if (distanceFromFrameRates[i] < shortestDistance) {
+                    targetFrameRate = commonFrameRates[i];
+                    shortestDistance = distanceFromFrameRates[i];
+                }
+            }
+            targetFrameRate = targetFrameRate || 60;
+            document.getElementById("frame-rate-detection").textContent = `Detected system frame rate as ${targetFrameRate} FPS`;
+            document.getElementById("system-frame-rate").value = targetFrameRate;
+            document.getElementById("frame-rate").value = Math.round(targetFrameRate * 5 / 6);
+        }
+
+        const tick = function(timestamp)
+        {
+            average -= average / 30;
+            average += 1000. / (timestamp - last) / 30;
+            document.querySelector("#frame-rate-detection span").textContent = Math.round(average);
+            last = timestamp;
+            count++;
+            if (count < 300)
+                requestAnimationFrame(tick);
+            else
+                finish();
+        }
+
+        requestAnimationFrame(tick);
+    }
+
+});
diff --git a/third_party/blink/perf_tests/MotionMark/resources/debug-runner/tests.js b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/tests.js
new file mode 100644
index 0000000..ed96349
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/debug-runner/tests.js
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2015-2018 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.
+ */
+Utilities.extendObject(Strings.text, {
+    samples: "Samples",
+    complexity: "Time Complexity",
+    frameRate: "FPS",
+    confidenceInterval: "80% Confidence Interval",
+    mergedRawComplexity: "Raw Complexity",
+    graph: "Graph",
+    title: "MotionMark %s developer",
+});
+
+
+Utilities.extendObject(Headers, {
+    details: [
+        {
+            title: Strings.text.graph
+        },
+        {
+            title: Strings.text.confidenceInterval,
+            children:
+            [
+                {
+                    text: function(data) {
+                        return data[Strings.json.complexity][Strings.json.bootstrap].confidenceLow.toFixed(2);
+                    },
+                    className: "right pad-left pad-right"
+                },
+                {
+                    text: function(data) {
+                        return " - " + data[Strings.json.complexity][Strings.json.bootstrap].confidenceHigh.toFixed(2);
+                    },
+                    className: "left"
+                },
+                {
+                    text: function(data) {
+                        var bootstrap = data[Strings.json.complexity][Strings.json.bootstrap];
+                        return (100 * (bootstrap.confidenceLow / bootstrap.median - 1)).toFixed(2) + "%";
+                    },
+                    className: "left pad-left small"
+                },
+                {
+                    text: function(data) {
+                        var bootstrap = data[Strings.json.complexity][Strings.json.bootstrap];
+                        return "+" + (100 * (bootstrap.confidenceHigh / bootstrap.median - 1)).toFixed(2) + "%";
+                    },
+                    className: "left pad-left small"
+                }
+            ]
+        },
+        {
+            title: Strings.text.complexity,
+            children:
+            [
+                {
+                    text: function(data) {
+                        return data[Strings.json.controller][Strings.json.measurements.average].toFixed(2);
+                    },
+                    className: "average"
+                },
+                {
+                    text: function(data) {
+                        return [
+                            "± ",
+                            data[Strings.json.controller][Strings.json.measurements.percent].toFixed(2),
+                            "%"
+                        ].join("");
+                    },
+                    className: function(data) {
+                        var className = "stdev";
+
+                        if (data[Strings.json.controller][Strings.json.measurements.percent] >= 10)
+                            className += " noisy-results";
+                        return className;
+                    }
+                }
+            ]
+        },
+        {
+            title: Strings.text.frameRate,
+            children:
+            [
+                {
+                    text: function(data) {
+                        return data[Strings.json.frameLength][Strings.json.measurements.average].toFixed(2);
+                    },
+                    className: function(data, options) {
+                        var className = "average";
+                        if (Math.abs(data[Strings.json.frameLength][Strings.json.measurements.average] - options["frame-rate"]) >= 2)
+                            className += " noisy-results";
+                        return className;
+                    }
+                },
+                {
+                    text: function(data) {
+                        var frameRateData = data[Strings.json.frameLength];
+                        return [
+                            "± ",
+                            frameRateData[Strings.json.measurements.percent].toFixed(2),
+                            "%"
+                        ].join("");
+                    },
+                    className: function(data) {
+                        var className = "stdev";
+
+                        if (data[Strings.json.frameLength][Strings.json.measurements.percent] >= 10)
+                            className += " noisy-results";
+                        return className;
+                    }
+                }
+            ]
+        },
+        {
+            title: Strings.text.mergedRawComplexity,
+            children:
+            [
+                {
+                    text: function(data) {
+                        return data[Strings.json.complexity][Strings.json.complexity].toFixed(2);
+                    },
+                    className: "average"
+                },
+                {
+                    text: function(data) {
+                        return [
+                            "± ",
+                            data[Strings.json.complexity][Strings.json.measurements.stdev].toFixed(2),
+                            "ms"
+                        ].join("");
+                    },
+                    className: "stdev"
+                }
+            ]
+        }
+    ]
+})
+
+///////////
+// Suites
+
+Suites.push(new Suite("HTML suite",
+    [
+        {
+            url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=12&particleHeight=12&shape=circle",
+            name: "CSS bouncing circles"
+        },
+        {
+            url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=40&particleHeight=40&shape=rect&clip=star",
+            name: "CSS bouncing clipped rects"
+        },
+        {
+            url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=50&particleHeight=50&shape=circle&fill=gradient",
+            name: "CSS bouncing gradient circles"
+        },
+        {
+            url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=80&particleHeight=80&shape=circle&blend",
+            name: "CSS bouncing blend circles"
+        },
+        {
+            url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=80&particleHeight=80&shape=circle&filter",
+            name: "CSS bouncing filter circles"
+        },
+        {
+            url: "bouncing-particles/bouncing-css-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.svg",
+            name: "CSS bouncing SVG images"
+        },
+        {
+            url: "bouncing-particles/bouncing-tagged-images.html?particleWidth=100&particleHeight=100",
+            name: "CSS bouncing tagged images"
+        },
+        {
+            url: "dom/focus.html",
+            name: "Focus 2.0"
+        },
+        {
+            url: "dom/particles.html",
+            name: "DOM particles, SVG masks"
+        },
+        {
+            url: "dom/compositing-transforms.html?particleWidth=50&particleHeight=50&filters=yes&imageSrc=../resources/yin-yang.svg",
+            name: "Composited Transforms"
+        }
+    ]
+));
+
+Suites.push(new Suite("Canvas suite",
+    [
+        {
+            url: "bouncing-particles/bouncing-canvas-shapes.html?particleWidth=40&particleHeight=40&shape=rect&clip=star",
+            name: "canvas bouncing clipped rects"
+        },
+        {
+            url: "bouncing-particles/bouncing-canvas-shapes.html?particleWidth=50&particleHeight=50&shape=circle&fill=gradient",
+            name: "canvas bouncing gradient circles"
+        },
+        {
+            url: "bouncing-particles/bouncing-canvas-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.svg",
+            name: "canvas bouncing SVG images"
+        },
+        {
+            url: "bouncing-particles/bouncing-canvas-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.png",
+            name: "canvas bouncing PNG images"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=strokes",
+            name: "Stroke shapes"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=fills",
+            name: "Fill shapes"
+        },
+        {
+            url: "simple/tiled-canvas-image.html",
+            name: "Canvas put/get image data"
+        },
+    ]
+));
+
+Suites.push(new Suite("SVG suite",
+    [
+        {
+            url: "bouncing-particles/bouncing-svg-shapes.html?particleWidth=12&particleHeight=12&shape=circle",
+            name: "SVG bouncing circles",
+        },
+        {
+            url: "bouncing-particles/bouncing-svg-shapes.html?particleWidth=40&particleHeight=40&shape=rect&clip=star",
+            name: "SVG bouncing clipped rects",
+        },
+        {
+            url: "bouncing-particles/bouncing-svg-shapes.html?particleWidth=50&particleHeight=50&shape=circle&fill=gradient",
+            name: "SVG bouncing gradient circles"
+        },
+        {
+            url: "bouncing-particles/bouncing-svg-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.svg",
+            name: "SVG bouncing SVG images"
+        },
+        {
+            url: "bouncing-particles/bouncing-svg-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.png",
+            name: "SVG bouncing PNG images"
+        },
+    ]
+));
+
+Suites.push(new Suite("Leaves suite",
+    [
+        {
+            url: "dom/leaves.html?style=simple",
+            name: "Translate-only Leaves"
+        },
+        {
+            url: "dom/leaves.html?style=scale",
+            name: "Translate + Scale Leaves"
+        },
+        {
+            url: "dom/leaves.html?style=opacity",
+            name: "Translate + Opacity Leaves"
+        }
+    ]
+));
+
+Suites.push(new Suite("Multiply suite",
+    [
+        {
+            url: "dom/multiply.html?style=opacity",
+            name: "Multiply: CSS opacity only"
+        },
+        {
+            url: "dom/multiply.html?style=display",
+            name: "Multiply: CSS display only"
+        },
+        {
+            url: "dom/multiply.html?style=visibility",
+            name: "Multiply: CSS visibility only"
+        }
+    ]
+));
+
+Suites.push(new Suite("Text suite",
+    [
+        {
+            url: "text/design.html?corpus=latin",
+            name: "Design: Latin only (12 items)"
+        },
+        {
+            url: "text/design.html?corpus=cjk",
+            name: "Design: CJK only (12 items)"
+        },
+        {
+            url: "text/design.html?corpus=arabic",
+            name: "Design: RTL and complex scripts only (12 items)"
+        },
+        {
+            url: "text/design-6.html?corpus=latin",
+            name: "Design: Latin only (6 items)"
+        },
+        {
+            url: "text/design-6.html?corpus=cjk",
+            name: "Design: CJK only (6 items)"
+        },
+        {
+            url: "text/design-6.html?corpus=arabic",
+            name: "Design: RTL and complex scripts only (6 items)"
+        },
+    ]
+));
+
+Suites.push(new Suite("Suits suite",
+    [
+        {
+            url: "svg/suits.html?style=clip",
+            name: "Suits: clip only"
+        },
+        {
+            url: "svg/suits.html?style=shape",
+            name: "Suits: shape only"
+        },
+        {
+            url: "svg/suits.html?style=rotation",
+            name: "Suits: clip, shape, rotation"
+        },
+        {
+            url: "svg/suits.html?style=gradient",
+            name: "Suits: clip, shape, gradient"
+        },
+        {
+            url: "svg/suits.html?style=static",
+            name: "Suits: static"
+        },
+    ]
+));
+
+Suites.push(new Suite("3D Graphics",
+    [
+        {
+            url: "3d/triangles-webgl.html",
+            name: "Triangles (WebGL)"
+        },
+        {
+            url: "3d/triangles-webgpu.html",
+            name: "Triangles (WebGPU)"
+        },
+    ]
+));
+
+Suites.push(new Suite("Basic canvas path suite",
+    [
+        {
+            url: "simple/simple-canvas-paths.html?pathType=line&lineCap=butt",
+            name: "Canvas line segments, butt caps"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=line&lineCap=round",
+            name: "Canvas line segments, round caps"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=line&lineCap=square",
+            name: "Canvas line segments, square caps"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=linePath&lineJoin=bevel",
+            name: "Canvas line path, bevel join"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=linePath&lineJoin=round",
+            name: "Canvas line path, round join"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=linePath&lineJoin=miter",
+            name: "Canvas line path, miter join"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=linePath&lineDash=1",
+            name: "Canvas line path with dash pattern"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=quadratic",
+            name: "Canvas quadratic segments"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=quadraticPath",
+            name: "Canvas quadratic path"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=bezier",
+            name: "Canvas bezier segments"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=bezierPath",
+            name: "Canvas bezier path"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?&pathType=arcTo",
+            name: "Canvas arcTo segments"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=arc",
+            name: "Canvas arc segments"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=rect",
+            name: "Canvas rects"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=ellipse",
+            name: "Canvas ellipses"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=spreadSheets",
+            name: "Canvas Spreadsheets"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=lineFill",
+            name: "Canvas line path, fill"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=quadraticFill",
+            name: "Canvas quadratic path, fill"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=bezierFill",
+            name: "Canvas bezier path, fill"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?&pathType=arcToFill",
+            name: "Canvas arcTo segments, fill"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=arcFill",
+            name: "Canvas arc segments, fill"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=rectFill",
+            name: "Canvas rects, fill"
+        },
+        {
+            url: "simple/simple-canvas-paths.html?pathType=ellipseFill",
+            name: "Canvas ellipses, fill"
+        }
+    ]
+));
diff --git a/third_party/blink/perf_tests/MotionMark/resources/extensions.js b/third_party/blink/perf_tests/MotionMark/resources/extensions.js
new file mode 100644
index 0000000..c303c3f
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/extensions.js
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2015-2019 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.
+ */
+Utilities =
+{
+    _parse: function(str, sep)
+    {
+        var output = {};
+        str.split(sep).forEach(function(part) {
+            var item = part.split("=");
+            var value = decodeURIComponent(item[1]);
+            if (value[0] == "'" )
+                output[item[0]] = value.substr(1, value.length - 2);
+            else
+                output[item[0]] = value;
+          });
+        return output;
+    },
+
+    parseParameters: function()
+    {
+        return this._parse(window.location.search.substr(1), "&");
+    },
+
+    parseArguments: function(str)
+    {
+        return this._parse(str, " ");
+    },
+
+    extendObject: function(obj1, obj2)
+    {
+        for (var attrname in obj2)
+            obj1[attrname] = obj2[attrname];
+        return obj1;
+    },
+
+    copyObject: function(obj)
+    {
+        return this.extendObject({}, obj);
+    },
+
+    mergeObjects: function(obj1, obj2)
+    {
+        return this.extendObject(this.copyObject(obj1), obj2);
+    },
+
+    createClass: function(classConstructor, classMethods)
+    {
+        classConstructor.prototype = classMethods;
+        return classConstructor;
+    },
+
+    createSubclass: function(superclass, classConstructor, classMethods)
+    {
+        classConstructor.prototype = Object.create(superclass.prototype);
+        classConstructor.prototype.constructor = classConstructor;
+        if (classMethods)
+            Utilities.extendObject(classConstructor.prototype, classMethods);
+        return classConstructor;
+    },
+
+    createElement: function(name, attrs, parentElement)
+    {
+        var element = document.createElement(name);
+
+        for (var key in attrs)
+            element.setAttribute(key, attrs[key]);
+
+        parentElement.appendChild(element);
+        return element;
+    },
+
+    createSVGElement: function(name, attrs, xlinkAttrs, parentElement)
+    {
+        const svgNamespace = "http://www.w3.org/2000/svg";
+        const xlinkNamespace = "http://www.w3.org/1999/xlink";
+
+        var element = document.createElementNS(svgNamespace, name);
+
+        for (var key in attrs)
+            element.setAttribute(key, attrs[key]);
+
+        for (var key in xlinkAttrs)
+            element.setAttributeNS(xlinkNamespace, key, xlinkAttrs[key]);
+
+        parentElement.appendChild(element);
+        return element;
+    },
+
+    browserPrefix: function()
+    {
+        if (this._browserPrefix !== undefined)
+            return this._browserPrefix;
+
+        // Get the HTML element's CSSStyleDeclaration
+        var styles = window.getComputedStyle(document.documentElement, '');
+
+        // Convert the styles list to an array
+        var stylesArray = Array.prototype.slice.call(styles);
+
+        // Concatenate all the styles in one big string
+        var stylesString = stylesArray.join('');
+
+        // Search the styles string for a known prefix type, settle on Opera if none is found.
+        var prefixes = stylesString.match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o']);
+
+        // prefixes has two elements; e.g. for webkit it has ['-webkit-', 'webkit'];
+        var prefix = prefixes[1];
+
+        // Have 'O' before 'Moz' in the string so it is matched first.
+        var dom = ('WebKit|O|Moz|MS').match(new RegExp(prefix, 'i'))[0];
+
+        // Return all the required prefixes.
+        this._browserPrefix = {
+            dom: dom,
+            lowercase: prefix,
+            css: '-' + prefix + '-',
+            js: prefix[0].toUpperCase() + prefix.substr(1)
+        };
+
+        return this._browserPrefix;
+    },
+
+    setElementPrefixedProperty: function(element, property, value)
+    {
+        element.style[property] = element.style[this.browserPrefix().js + property[0].toUpperCase() + property.substr(1)] = value;
+    },
+
+    stripUnwantedCharactersForURL: function(inputString)
+    {
+        return inputString.replace(/\W/g, '');
+    },
+
+    convertObjectToQueryString: function(object)
+    {
+        var queryString = [];
+        for (var property in object) {
+            if (object.hasOwnProperty(property))
+                queryString.push(encodeURIComponent(property) + "=" + encodeURIComponent(object[property]));
+        }
+        return "?" + queryString.join("&");
+    },
+
+    convertQueryStringToObject: function(queryString)
+    {
+        queryString = queryString.substring(1);
+        if (!queryString)
+            return null;
+
+        var object = {};
+        queryString.split("&").forEach(function(parameter) {
+            var components = parameter.split("=");
+            object[components[0]] = components[1];
+        });
+        return object;
+    },
+
+    progressValue: function(value, min, max)
+    {
+        return (value - min) / (max - min);
+    },
+
+    lerp: function(value, min, max)
+    {
+        return min + (max - min) * value;
+    },
+
+    toFixedNumber: function(number, precision)
+    {
+        if (number.toFixed)
+            return Number(number.toFixed(precision));
+        return number;
+    }
+};
+
+Array.prototype.swap = function(i, j)
+{
+    var t = this[i];
+    this[i] = this[j];
+    this[j] = t;
+    return this;
+}
+
+if (!Array.prototype.fill) {
+    Array.prototype.fill = function(value) {
+        if (this == null)
+            throw new TypeError('Array.prototype.fill called on null or undefined');
+
+        var object = Object(this);
+        var len = parseInt(object.length, 10);
+        var start = arguments[1];
+        var relativeStart = parseInt(start, 10) || 0;
+        var k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);
+        var end = arguments[2];
+        var relativeEnd = end === undefined ? len : (parseInt(end) || 0) ;
+        var final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len);
+
+        for (; k < final; k++)
+            object[k] = value;
+
+        return object;
+    };
+}
+
+if (!Array.prototype.find) {
+    Array.prototype.find = function(predicate) {
+        if (this == null)
+            throw new TypeError('Array.prototype.find called on null or undefined');
+        if (typeof predicate !== 'function')
+            throw new TypeError('predicate must be a function');
+
+        var list = Object(this);
+        var length = list.length >>> 0;
+        var thisArg = arguments[1];
+        var value;
+
+        for (var i = 0; i < length; i++) {
+            value = list[i];
+            if (predicate.call(thisArg, value, i, list))
+                return value;
+        }
+        return undefined;
+    };
+}
+
+Array.prototype.shuffle = function()
+{
+    for (var index = this.length - 1; index >= 0; --index) {
+        var randomIndex = Math.floor(Math.random() * (index + 1));
+        this.swap(index, randomIndex);
+    }
+    return this;
+}
+
+Point = Utilities.createClass(
+    function(x, y)
+    {
+        this.x = x;
+        this.y = y;
+    }, {
+
+    // Used when the point object is used as a size object.
+    get width()
+    {
+        return this.x;
+    },
+
+    // Used when the point object is used as a size object.
+    get height()
+    {
+        return this.y;
+    },
+
+    // Used when the point object is used as a size object.
+    get center()
+    {
+        return new Point(this.x / 2, this.y / 2);
+    },
+
+    str: function()
+    {
+        return "x = " + this.x + ", y = " + this.y;
+    },
+
+    add: function(other)
+    {
+        if(isNaN(other.x))
+            return new Point(this.x + other, this.y + other);
+        return new Point(this.x + other.x, this.y + other.y);
+    },
+
+    subtract: function(other)
+    {
+        if(isNaN(other.x))
+            return new Point(this.x - other, this.y - other);
+        return new Point(this.x - other.x, this.y - other.y);
+    },
+
+    multiply: function(other)
+    {
+        if(isNaN(other.x))
+            return new Point(this.x * other, this.y * other);
+        return new Point(this.x * other.x, this.y * other.y);
+    },
+
+    move: function(angle, velocity, timeDelta)
+    {
+        return this.add(Point.pointOnCircle(angle, velocity * (timeDelta / 1000)));
+    },
+
+    length: function() {
+        return Math.sqrt( this.x * this.x + this.y * this.y );
+    },
+
+    normalize: function() {
+        var l = Math.sqrt( this.x * this.x + this.y * this.y );
+        this.x /= l;
+        this.y /= l;
+        return this;
+    }
+});
+
+Utilities.extendObject(Point, {
+    zero: new Point(0, 0),
+
+    pointOnCircle: function(angle, radius)
+    {
+        return new Point(radius * Math.cos(angle), radius * Math.sin(angle));
+    },
+
+    pointOnEllipse: function(angle, radiuses)
+    {
+        return new Point(radiuses.x * Math.cos(angle), radiuses.y * Math.sin(angle));
+    },
+
+    elementClientSize: function(element)
+    {
+        var rect = element.getBoundingClientRect();
+        return new Point(rect.width, rect.height);
+    }
+});
+
+Insets = Utilities.createClass(
+    function(top, right, bottom, left)
+    {
+        this.top = top;
+        this.right = right;
+        this.bottom = bottom;
+        this.left = left;
+    }, {
+
+    get width()
+    {
+        return this.left + this.right;
+    },
+
+    get height()
+    {
+        return this.top + this.bottom;
+    },
+
+    get size()
+    {
+        return new Point(this.width, this.height);
+    }
+});
+
+Insets.elementPadding = function(element)
+{
+    var styles = window.getComputedStyle(element);
+    return new Insets(
+        parseFloat(styles.paddingTop),
+        parseFloat(styles.paddingRight),
+        parseFloat(styles.paddingBottom),
+        parseFloat(styles.paddingTop));
+}
+
+UnitBezier = Utilities.createClass(
+    function(point1, point2)
+    {
+        // First and last points in the Bézier curve are assumed to be (0,0) and (!,1)
+        this._c = point1.multiply(3);
+        this._b = point2.subtract(point1).multiply(3).subtract(this._c);
+        this._a = new Point(1, 1).subtract(this._c).subtract(this._b);
+    }, {
+
+    epsilon: 1e-5,
+    derivativeEpsilon: 1e-6,
+
+    solve: function(x)
+    {
+        return this.sampleY(this.solveForT(x));
+    },
+
+    sampleX: function(t)
+    {
+        return ((this._a.x * t + this._b.x) * t + this._c.x) * t;
+    },
+
+    sampleY: function(t)
+    {
+        return ((this._a.y * t + this._b.y) * t + this._c.y) * t;
+    },
+
+    sampleDerivativeX: function(t)
+    {
+        return(3 * this._a.x * t + 2 * this._b.x) * t + this._c.x;
+    },
+
+    solveForT: function(x)
+    {
+        var t0, t1, t2, x2, d2, i;
+
+        for (t2 = x, i = 0; i < 8; ++i) {
+            x2 = this.sampleX(t2) - x;
+            if (Math.abs(x2) < this.epsilon)
+                return t2;
+            d2 = this.sampleDerivativeX(t2);
+            if (Math.abs(d2) < this.derivativeEpsilon)
+                break;
+            t2 = t2 - x2 / d2;
+        }
+
+        t0 = 0;
+        t1 = 1;
+        t2 = x;
+
+        if (t2 < t0)
+            return t0;
+        if (t2 > t1)
+            return t1;
+
+        while (t0 < t1) {
+            x2 = this.sampleX(t2);
+            if (Math.abs(x2 - x) < this.epsilon)
+                return t2;
+            if (x > x2)
+                t0 = t2;
+            else
+                t1 = t2;
+            t2 = (t1 - t0) * .5 + t0;
+        }
+
+        return t2;
+    }
+});
+
+SimplePromise = Utilities.createClass(
+    function()
+    {
+        this._chainedPromise = null;
+        this._callback = null;
+    }, {
+
+    then: function (callback)
+    {
+        if (this._callback)
+            throw "SimplePromise doesn't support multiple calls to then";
+
+        this._callback = callback;
+        this._chainedPromise = new SimplePromise;
+
+        if (this._resolved)
+            this.resolve(this._resolvedValue);
+
+        return this._chainedPromise;
+    },
+
+    resolve: function (value)
+    {
+        if (!this._callback) {
+            this._resolved = true;
+            this._resolvedValue = value;
+            return;
+        }
+
+        var result = this._callback(value);
+        if (result instanceof SimplePromise) {
+            var chainedPromise = this._chainedPromise;
+            result.then(function (result) { chainedPromise.resolve(result); });
+        } else
+            this._chainedPromise.resolve(result);
+    }
+});
+
+var Heap = Utilities.createClass(
+    function(maxSize, compare)
+    {
+        this._maxSize = maxSize;
+        this._compare = compare;
+        this._size = 0;
+        this._values = new Array(this._maxSize);
+    }, {
+
+    // This is a binary heap represented in an array. The root element is stored
+    // in the first element in the array. The root is followed by its two children.
+    // Then its four grandchildren and so on. So every level in the binary heap is
+    // doubled in the following level. Here is an example of the node indices and
+    // how they are related to their parents and children.
+    // ===========================================================================
+    //              0       1       2       3       4       5       6
+    // PARENT       -1      0       0       1       1       2       2
+    // LEFT         1       3       5       7       9       11      13
+    // RIGHT        2       4       6       8       10      12      14
+    // ===========================================================================
+    _parentIndex: function(i)
+    {
+        return i > 0 ? Math.floor((i - 1) / 2) : -1;
+    },
+
+    _leftIndex: function(i)
+    {
+        var leftIndex = i * 2 + 1;
+        return leftIndex < this._size ? leftIndex : -1;
+    },
+
+    _rightIndex: function(i)
+    {
+        var rightIndex = i * 2 + 2;
+        return rightIndex < this._size ? rightIndex : -1;
+    },
+
+    // Return the child index that may violate the heap property at index i.
+    _childIndex: function(i)
+    {
+        var left = this._leftIndex(i);
+        var right = this._rightIndex(i);
+
+        if (left != -1 && right != -1)
+            return this._compare(this._values[left], this._values[right]) > 0 ? left : right;
+
+        return left != -1 ? left : right;
+    },
+
+    init: function()
+    {
+        this._size = 0;
+    },
+
+    top: function()
+    {
+        return this._size ? this._values[0] : NaN;
+    },
+
+    push: function(value)
+    {
+        if (this._size == this._maxSize) {
+            // If size is bounded and the new value can be a parent of the top()
+            // if the size were unbounded, just ignore the new value.
+            if (this._compare(value, this.top()) > 0)
+                return;
+            this.pop();
+        }
+        this._values[this._size++] = value;
+        this._bubble(this._size - 1);
+    },
+
+    pop: function()
+    {
+        if (!this._size)
+            return NaN;
+
+        this._values[0] = this._values[--this._size];
+        this._sink(0);
+    },
+
+    _bubble: function(i)
+    {
+        // Fix the heap property at index i given that parent is the only node that
+        // may violate the heap property.
+        for (var pi = this._parentIndex(i); pi != -1; i = pi, pi = this._parentIndex(pi)) {
+            if (this._compare(this._values[pi], this._values[i]) > 0)
+                break;
+
+            this._values.swap(pi, i);
+        }
+    },
+
+    _sink: function(i)
+    {
+        // Fix the heap property at index i given that each of the left and the right
+        // sub-trees satisfies the heap property.
+        for (var ci = this._childIndex(i); ci != -1; i = ci, ci = this._childIndex(ci)) {
+            if (this._compare(this._values[i], this._values[ci]) > 0)
+                break;
+
+            this._values.swap(ci, i);
+        }
+    },
+
+    str: function()
+    {
+        var out = "Heap[" + this._size + "] = [";
+        for (var i = 0; i < this._size; ++i) {
+            out += this._values[i];
+            if (i < this._size - 1)
+                out += ", ";
+        }
+        return out + "]";
+    },
+
+    values: function(size) {
+        // Return the last "size" heap elements values.
+        var values = this._values.slice(0, this._size);
+        return values.sort(this._compare).slice(0, Math.min(size, this._size));
+    }
+});
+
+Utilities.extendObject(Heap, {
+    createMinHeap: function(maxSize)
+    {
+        return new Heap(maxSize, function(a, b) { return b - a; });
+    },
+
+    createMaxHeap: function(maxSize) {
+        return new Heap(maxSize, function(a, b) { return a - b; });
+    }
+});
+
+var SampleData = Utilities.createClass(
+    function(fieldMap, data)
+    {
+        this.fieldMap = fieldMap || {};
+        this.data = data || [];
+    }, {
+
+    get length()
+    {
+        return this.data.length;
+    },
+
+    addField: function(name, index)
+    {
+        this.fieldMap[name] = index;
+    },
+
+    push: function(datum)
+    {
+        this.data.push(datum);
+    },
+
+    sort: function(sortFunction)
+    {
+        this.data.sort(sortFunction);
+    },
+
+    slice: function(begin, end)
+    {
+        return new SampleData(this.fieldMap, this.data.slice(begin, end));
+    },
+
+    forEach: function(iterationFunction)
+    {
+        this.data.forEach(iterationFunction);
+    },
+
+    createDatum: function()
+    {
+        return [];
+    },
+
+    getFieldInDatum: function(datum, fieldName)
+    {
+        if (typeof datum === 'number')
+            datum = this.data[datum];
+        return datum[this.fieldMap[fieldName]];
+    },
+
+    setFieldInDatum: function(datum, fieldName, value)
+    {
+        if (typeof datum === 'number')
+            datum = this.data[datum];
+        return datum[this.fieldMap[fieldName]] = value;
+    },
+
+    at: function(index)
+    {
+        return this.data[index];
+    },
+
+    toArray: function()
+    {
+        var array = [];
+
+        this.data.forEach(function(datum) {
+            var newDatum = {};
+            array.push(newDatum);
+
+            for (var fieldName in this.fieldMap) {
+                var value = this.getFieldInDatum(datum, fieldName);
+                if (value !== null && value !== undefined)
+                    newDatum[fieldName] = value;
+            }
+        }, this);
+
+        return array;
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/resources/runner/benchmark-runner.js b/third_party/blink/perf_tests/MotionMark/resources/runner/benchmark-runner.js
new file mode 100644
index 0000000..1aa63035
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/runner/benchmark-runner.js
@@ -0,0 +1,179 @@
+BenchmarkRunnerState = Utilities.createClass(
+    function(suites)
+    {
+        this._suites = suites;
+        this._suiteIndex = -1;
+        this._testIndex = 0;
+        this.next();
+    }, {
+
+    currentSuite: function()
+    {
+        return this._suites[this._suiteIndex];
+    },
+
+    currentTest: function()
+    {
+        var suite = this.currentSuite();
+        return suite ? suite.tests[this._testIndex] : null;
+    },
+
+    isFirstTest: function()
+    {
+        return !this._testIndex;
+    },
+
+    next: function()
+    {
+        this._testIndex++;
+
+        var suite = this._suites[this._suiteIndex];
+        if (suite && this._testIndex < suite.tests.length)
+            return;
+
+        this._testIndex = 0;
+        do {
+            this._suiteIndex++;
+        } while (this._suiteIndex < this._suites.length && this._suites[this._suiteIndex].disabled);
+    },
+
+    prepareCurrentTest: function(runner, frame)
+    {
+        var test = this.currentTest();
+        var promise = new SimplePromise;
+
+        frame.onload = function() {
+            promise.resolve();
+        };
+
+        frame.src = "tests/" + test.url;
+        return promise;
+    }
+});
+
+BenchmarkRunner = Utilities.createClass(
+    function(suites, frameContainer, client)
+    {
+        this._suites = suites;
+        this._client = client;
+        this._frameContainer = frameContainer;
+    }, {
+
+    _appendFrame: function()
+    {
+        var frame = document.createElement("iframe");
+        frame.setAttribute("scrolling", "no");
+
+        this._frameContainer.insertBefore(frame, this._frameContainer.firstChild);
+        this._frame = frame;
+        return frame;
+    },
+
+    _removeFrame: function()
+    {
+        if (this._frame) {
+            this._frame.parentNode.removeChild(this._frame);
+            this._frame = null;
+        }
+    },
+
+    _runBenchmarkAndRecordResults: function(state)
+    {
+        var promise = new SimplePromise;
+        var suite = state.currentSuite();
+        var test = state.currentTest();
+
+        if (this._client && this._client.willRunTest)
+            this._client.willRunTest(suite, test);
+
+        var contentWindow = this._frame.contentWindow;
+        var self = this;
+
+        var options = { complexity: test.complexity };
+        Utilities.extendObject(options, this._client.options);
+        Utilities.extendObject(options, contentWindow.Utilities.parseParameters());
+
+        var benchmark = new contentWindow.benchmarkClass(options);
+        document.body.style.backgroundColor = benchmark.backgroundColor();
+        benchmark.run().then(function(testData) {
+            var suiteResults = self._suitesResults[suite.name] || {};
+            suiteResults[test.name] = testData;
+            self._suitesResults[suite.name] = suiteResults;
+
+            if (self._client && self._client.didRunTest)
+                self._client.didRunTest(testData);
+
+            state.next();
+            if (state.currentSuite() != suite)
+                self._removeFrame();
+            promise.resolve(state);
+        });
+
+        return promise;
+    },
+
+    step: function(state)
+    {
+        if (!state) {
+            state = new BenchmarkRunnerState(this._suites);
+            this._suitesResults = {};
+        }
+
+        var suite = state.currentSuite();
+        if (!suite) {
+            this._finalize();
+            var promise = new SimplePromise;
+            promise.resolve();
+            return promise;
+        }
+
+        if (state.isFirstTest()) {
+            this._appendFrame();
+        }
+
+        return state.prepareCurrentTest(this, this._frame).then(function(prepareReturnValue) {
+            return this._runBenchmarkAndRecordResults(state);
+        }.bind(this));
+    },
+
+    runAllSteps: function(startingState)
+    {
+        var nextCallee = this.runAllSteps.bind(this);
+        this.step(startingState).then(function(nextState) {
+            if (nextState)
+                nextCallee(nextState);
+        });
+    },
+
+    runMultipleIterations: function()
+    {
+        var self = this;
+        var currentIteration = 0;
+
+        this._runNextIteration = function() {
+            currentIteration++;
+            if (currentIteration < self._client.iterationCount)
+                self.runAllSteps();
+            else if (this._client && this._client.didFinishLastIteration) {
+                document.body.style.backgroundColor = "";
+                self._client.didFinishLastIteration();
+            }
+        }
+
+        if (this._client && this._client.willStartFirstIteration)
+            this._client.willStartFirstIteration();
+
+        this.runAllSteps();
+    },
+
+    _finalize: function()
+    {
+        this._removeFrame();
+
+        if (this._client && this._client.didRunSuites)
+            this._client.didRunSuites(this._suitesResults);
+
+        if (this._runNextIteration)
+            this._runNextIteration();
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/resources/runner/crystal.svg b/third_party/blink/perf_tests/MotionMark/resources/runner/crystal.svg
new file mode 100644
index 0000000..0090df6c
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/runner/crystal.svg
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg viewBox="0 0 1000 1000" preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <g fill="white" stroke="white" stroke-width="0.15">
+        <path fill-opacity="1" stroke-opacity="1" d=" M 0 0 L 327.88 0 C 325.14 2.87 322.60 5.94 319.73 8.68 C 315.84 12.50 311.31 16.05 309.30 21.31 C 303.10 37.43 296.87 53.54 290.57 69.62 C 288.47 75.11 285.91 80.43 284.24 86.07 C 285.81 87.43 287.37 88.81 289.07 90.01 C 311.23 105.31 332.96 121.25 355.21 136.43 C 357.15 140.82 359.76 145.01 360.61 149.80 C 361.24 153.54 361.64 157.34 361.37 161.13 C 358.55 166.08 356.04 171.21 353.27 176.19 C 353.07 176.54 352.67 177.23 352.48 177.57 C 350 179.82 347.14 181.57 344.29 183.30 C 335.73 188.47 327.27 193.80 318.71 198.98 C 308.13 198.76 297.56 199.12 287.01 199.74 C 279.65 200.20 272.27 199.53 264.92 200.02 C 262.30 200.09 259.91 201.30 257.93 202.94 C 238.82 218.89 219.07 234.08 199.86 249.90 C 196.40 252.94 194.22 257.05 191.56 260.74 C 185.35 267.44 176.30 270.51 169.90 276.91 C 167.71 282.16 169.92 288.14 170.35 293.60 C 171.49 300.35 172.29 307.14 173.21 313.92 C 173.56 316.94 174.94 319.79 177.25 321.80 C 191.06 333.94 203.32 347.74 217.23 359.78 C 225.25 367.81 233.44 375.66 241.21 383.92 C 240.08 390.20 237.63 396.53 238.91 402.98 C 243.04 426.95 247.04 450.94 251.10 474.92 C 252.01 480.25 253.09 485.59 253.21 491.02 C 252.78 493.08 252.36 495.16 251.80 497.20 C 245.46 503.93 239.30 510.88 232.53 517.18 C 229.17 519.86 225.15 522.50 223.72 526.76 C 222.48 536.86 222.68 547.08 221.69 557.21 C 221.55 562.43 220.62 567.83 222.17 572.93 C 227.92 589.76 231.93 607.12 236.76 624.23 C 237.77 628.08 239 631.89 239.78 635.81 C 236.34 648.91 232.70 661.96 229.12 675.02 C 221.78 676.32 214.41 674.68 207.03 674.87 C 197.35 675.08 187.73 673.63 178.06 673.91 C 167.70 674.16 157.40 672.47 147.04 672.92 C 134.73 673.25 122.45 671.07 110.15 672.14 C 114.51 679.54 119.71 686.40 124.41 693.59 C 143.51 722.45 162.87 751.15 181.98 780 C 185.26 784.93 191.47 785.96 196.30 788.75 C 197.35 794.78 196.74 800.90 196.84 806.98 C 196.94 817.65 196.93 828.31 196.97 838.98 C 197.12 846.82 196.23 854.78 198.23 862.46 C 198.18 870.99 198.91 879.57 197.90 888.06 C 196.92 891.68 197.94 895.32 199.28 898.70 C 195.30 904.88 190.33 910.34 185.64 915.99 C 178.89 920.62 171.57 924.35 164.65 928.72 C 158.28 932.76 151.41 936 145.28 940.39 C 140 944.77 136.22 950.60 131.64 955.65 C 128.24 959.88 124.34 963.73 121.19 968.16 C 119.32 970.80 120.37 974.22 120.59 977.20 C 121.77 984.78 122.70 992.40 123.77 1000 L 0 1000 L 0 0 Z"/>
+        <path fill-opacity="0.9883" stroke-opacity="0.9883" d=" M 169.90 276.91 C 176.30 270.51 185.35 267.44 191.56 260.74 C 195.63 265.49 201.89 267.02 207.24 269.80 C 229.32 280.67 251.38 291.56 273.44 302.46 C 289.29 309.67 304.43 318.39 320.48 325.16 C 323.79 331.38 327.72 337.24 331.27 343.31 C 301.44 357.25 271.05 370 241.21 383.92 C 233.44 375.66 225.25 367.81 217.23 359.78 C 203.32 347.74 191.06 333.94 177.25 321.80 C 174.94 319.79 173.56 316.94 173.21 313.92 C 172.29 307.14 171.49 300.35 170.35 293.60 C 169.92 288.14 167.71 282.16 169.90 276.91 Z"/>
+        <path fill-opacity="0.9804" stroke-opacity="0.9804" d=" M 110.15 672.14 C 122.45 671.07 134.73 673.25 147.04 672.92 C 157.40 672.47 167.70 674.16 178.06 673.91 C 187.73 673.63 197.35 675.08 207.03 674.87 C 214.41 674.68 221.78 676.32 229.12 675.02 C 230.32 677.25 231.56 679.45 232.90 681.60 C 233.20 683.35 233.22 685.15 232.89 686.92 C 226.83 717.17 221.18 747.50 215.10 777.75 C 209.29 781.47 203.40 785.09 197.76 789.07 C 197.63 813.54 198.62 838 198.23 862.46 C 196.23 854.78 197.12 846.82 196.97 838.98 C 196.93 828.31 196.94 817.65 196.84 806.98 C 196.74 800.90 197.35 794.78 196.30 788.75 C 191.47 785.96 185.26 784.93 181.98 780 C 162.87 751.15 143.51 722.45 124.41 693.59 C 119.71 686.40 114.51 679.54 110.15 672.14 Z"/>
+        <path fill-opacity="0.9687" stroke-opacity="0.9687" d=" M 287.01 199.74 C 297.56 199.12 308.13 198.76 318.71 198.98 C 320.17 228.28 318.86 257.66 320.23 286.97 C 320.34 299.70 320.40 312.43 320.48 325.16 C 304.43 318.39 289.29 309.67 273.44 302.46 C 251.38 291.56 229.32 280.67 207.24 269.80 C 201.89 267.02 195.63 265.49 191.56 260.74 C 194.22 257.05 196.40 252.94 199.86 249.90 C 219.07 234.08 238.82 218.89 257.93 202.94 C 259.91 201.30 262.30 200.09 264.92 200.02 C 272.27 199.53 279.65 200.20 287.01 199.74 Z"/>
+        <path fill-opacity="0.953" stroke-opacity="0.953" d=" M 327.88 0 L 373.98 0 C 367.79 45.48 361.61 90.97 355.21 136.43 C 332.96 121.25 311.23 105.31 289.07 90.01 C 287.37 88.81 285.81 87.43 284.24 86.07 C 285.91 80.43 288.47 75.11 290.57 69.62 C 296.87 53.54 303.10 37.43 309.30 21.31 C 311.31 16.05 315.84 12.50 319.73 8.68 C 322.60 5.94 325.14 2.87 327.88 0 Z"/>
+        <path fill-opacity="0.9491" stroke-opacity="0.9491" d=" M 164.65 928.72 C 171.57 924.35 178.89 920.62 185.64 915.99 C 186.75 944 188.72 971.99 190.07 1000 L 123.77 1000 C 122.70 992.40 121.77 984.78 120.59 977.20 C 120.37 974.22 119.32 970.80 121.19 968.16 C 124.34 963.73 128.24 959.88 131.64 955.65 C 136.22 950.60 140 944.77 145.28 940.39 C 151.41 936 158.28 932.76 164.65 928.72 Z"/>
+        <path fill-opacity="0.9295" stroke-opacity="0.9295" d=" M 331.27 343.31 C 342.73 349.21 354.49 354.50 365.86 360.56 C 366.36 361.84 366.86 363.12 367.37 364.41 C 367.21 366.77 366.28 368.98 365.20 371.06 C 362.81 375.78 360.53 380.54 358.35 385.36 C 345.47 397.11 333.54 409.87 321.09 422.06 C 299.90 443.25 278.73 464.47 257.50 485.61 C 255.90 487.27 254.44 489.06 253.21 491.02 C 253.09 485.59 252.01 480.25 251.10 474.92 C 247.04 450.94 243.04 426.95 238.91 402.98 C 237.63 396.53 240.08 390.20 241.21 383.92 C 271.05 370 301.44 357.25 331.27 343.31 Z"/>
+        <path fill-opacity="0.8785" stroke-opacity="0.8785" d=" M 223.72 526.76 C 225.15 522.50 229.17 519.86 232.53 517.18 C 238.93 523.27 246.16 528.39 253.01 533.95 C 280.84 556.11 308.83 578.09 336.63 600.29 C 341.10 603.79 346.07 606.93 349.22 611.79 C 350.70 615.38 352.13 618.98 353.74 622.52 C 347.24 625.52 339.96 624.93 333.04 625.88 C 301.97 629.40 270.82 632.13 239.78 635.81 C 239 631.89 237.77 628.08 236.76 624.23 C 231.93 607.12 227.92 589.76 222.17 572.93 C 220.62 567.83 221.55 562.43 221.69 557.21 C 222.68 547.08 222.48 536.86 223.72 526.76 Z"/>
+        <path fill-opacity="0.8746" stroke-opacity="0.8746" d=" M 199.28 898.70 C 203.46 901.06 207.86 902.98 212.33 904.76 C 214.88 905.73 217.17 907.37 218.69 909.68 C 225.30 927.02 231.55 944.50 238.11 961.86 C 239.21 964.87 240.62 967.82 241.15 971.02 C 241.25 973.62 240.44 976.14 239.87 978.66 C 238.03 985.74 236.68 992.94 234.74 1000 L 190.07 1000 C 188.72 971.99 186.75 944 185.64 915.99 C 190.33 910.34 195.30 904.88 199.28 898.70 Z"/>
+        <path fill-opacity="0.8706" stroke-opacity="0.8706" d=" M 232.90 681.60 C 235.14 683.02 237.58 684.12 240.11 684.93 C 258.41 690.06 276.85 694.79 294.93 700.68 C 304.80 726.80 314.30 753.06 323.99 779.25 C 321.69 780.75 319.57 782.51 317.43 784.23 C 283.33 781.96 249.22 779.81 215.10 777.75 C 221.18 747.50 226.83 717.17 232.89 686.92 C 233.22 685.15 233.20 683.35 232.90 681.60 Z"/>
+        <path fill-opacity="0.8589" stroke-opacity="0.8589" d=" M 353.74 622.52 C 354.67 624.51 355 626.71 354.72 628.90 C 354.14 631.20 353.60 633.50 353.05 635.80 C 350.68 639.43 347.58 642.48 344.71 645.70 C 328.13 664.04 311.35 682.20 294.93 700.68 C 276.85 694.79 258.41 690.06 240.11 684.93 C 237.58 684.12 235.14 683.02 232.90 681.60 C 231.56 679.45 230.32 677.25 229.12 675.02 C 232.70 661.96 236.34 648.91 239.78 635.81 C 270.82 632.13 301.97 629.40 333.04 625.88 C 339.96 624.93 347.24 625.52 353.74 622.52 Z"/>
+        <path fill-opacity="0.855" stroke-opacity="0.855" d=" M 197.76 789.07 C 203.40 785.09 209.29 781.47 215.10 777.75 C 249.22 779.81 283.33 781.96 317.43 784.23 C 315.73 791.84 313.84 799.40 312.11 807 C 310.31 810.16 307.51 812.57 304.47 814.49 C 287.18 825.78 270.27 837.63 253.03 848.98 C 236.55 859.79 220.52 871.26 203.96 881.93 C 201.52 883.50 199.47 885.61 197.90 888.06 C 198.91 879.57 198.18 870.99 198.23 862.46 C 198.62 838 197.63 813.54 197.76 789.07 Z"/>
+        <path fill-opacity="0.855" stroke-opacity="0.855" d=" M 344.29 183.30 C 347.14 181.57 350 179.82 352.48 177.57 C 352.77 181.76 355.26 185.30 357.10 188.94 C 365.30 204.47 373.30 220.10 381.52 235.62 C 383.12 238.45 384.06 241.61 384.44 244.84 C 387.81 271.89 391.59 298.89 394.85 325.96 C 385.10 337.41 375.36 348.89 365.86 360.56 C 354.49 354.50 342.73 349.21 331.27 343.31 C 327.72 337.24 323.79 331.38 320.48 325.16 C 320.40 312.43 320.34 299.70 320.23 286.97 C 318.86 257.66 320.17 228.28 318.71 198.98 C 327.27 193.80 335.73 188.47 344.29 183.30 Z"/>
+        <path fill-opacity="0.8432" stroke-opacity="0.8432" d=" M 321.09 422.06 C 333.54 409.87 345.47 397.11 358.35 385.36 C 358.79 393.90 358 402.41 357.61 410.93 C 357.58 424.29 356.35 437.61 356.32 450.97 C 355.30 462.60 355.77 474.29 354.82 485.93 C 354.49 491.91 354.57 497.91 354.23 503.90 C 350.84 504.27 347.41 504.51 344.01 504.17 C 313.30 501.45 282.48 500.24 251.80 497.20 C 252.36 495.16 252.78 493.08 253.21 491.02 C 254.44 489.06 255.90 487.27 257.50 485.61 C 278.73 464.47 299.90 443.25 321.09 422.06 Z"/>
+        <path fill-opacity="0.8393" stroke-opacity="0.8393" d=" M 373.98 0 L 375.50 0 C 397.90 16.47 420.67 32.46 443.14 48.85 C 449.83 53.79 456.77 58.38 463.25 63.61 C 431.93 89.13 400.82 114.91 369.61 140.56 C 366.28 143.28 362.37 145.67 360.61 149.80 C 359.76 145.01 357.15 140.82 355.21 136.43 C 361.61 90.97 367.79 45.48 373.98 0 Z"/>
+        <path fill-opacity="0.8275" stroke-opacity="0.8275" d=" M 251.80 497.20 C 282.48 500.24 313.30 501.45 344.01 504.17 C 347.41 504.51 350.84 504.27 354.23 503.90 C 357.03 506.62 361.90 508.29 361.97 512.80 C 358.05 541.20 353.99 569.58 349.99 597.97 C 349.44 602.54 347.90 607.21 349.22 611.79 C 346.07 606.93 341.10 603.79 336.63 600.29 C 308.83 578.09 280.84 556.11 253.01 533.95 C 246.16 528.39 238.93 523.27 232.53 517.18 C 239.30 510.88 245.46 503.93 251.80 497.20 Z"/>
+        <path fill-opacity="0.8197" stroke-opacity="0.8197" d=" M 304.47 814.49 C 307.51 812.57 310.31 810.16 312.11 807 C 310.99 813.29 311.73 819.70 311.72 826.05 C 312.47 837.02 312.51 848.02 312.50 859.01 C 300.69 875.28 289.35 891.88 277.41 908.05 C 270.37 909.81 263.17 908.36 256.04 908.19 C 249.68 907.96 243.30 908.12 236.94 907.87 C 231.21 907.71 225.49 906.94 219.75 907.36 C 219.49 907.94 218.96 909.10 218.69 909.68 C 217.17 907.37 214.88 905.73 212.33 904.76 C 207.86 902.98 203.46 901.06 199.28 898.70 C 197.94 895.32 196.92 891.68 197.90 888.06 C 199.47 885.61 201.52 883.50 203.96 881.93 C 220.52 871.26 236.55 859.79 253.03 848.98 C 270.27 837.63 287.18 825.78 304.47 814.49 Z"/>
+        <path fill-opacity="0.7844" stroke-opacity="0.7844" d=" M 219.75 907.36 C 225.49 906.94 231.21 907.71 236.94 907.87 C 243.30 908.12 249.68 907.96 256.04 908.19 C 263.17 908.36 270.37 909.81 277.41 908.05 C 279.98 912.58 284.54 915.31 288.41 918.60 C 295.15 924.19 301.91 929.75 308.65 935.35 C 313.06 939.14 318.10 942.31 321.57 947.09 C 318.07 952.97 314.74 958.95 311.43 964.94 C 302.10 970.37 292.91 976.03 283.57 981.44 C 281.17 982.96 278.31 984.13 276.66 986.54 C 275.16 990.86 275.11 995.50 274.48 1000 L 234.74 1000 C 236.68 992.94 238.03 985.74 239.87 978.66 C 240.44 976.14 241.25 973.62 241.15 971.02 C 240.62 967.82 239.21 964.87 238.11 961.86 C 231.55 944.50 225.30 927.02 218.69 909.68 C 218.96 909.10 219.49 907.94 219.75 907.36 Z"/>
+        <path fill-opacity="0.7687" stroke-opacity="0.7687" d=" M 375.50 0 L 548.99 0 C 548.07 11.56 546.25 23.02 544.95 34.54 C 525.98 45.47 506.58 55.63 487.69 66.69 C 479.58 65.38 471.41 64.56 463.25 63.61 C 456.77 58.38 449.83 53.79 443.14 48.85 C 420.67 32.46 397.90 16.47 375.50 0 Z"/>
+        <path fill-opacity="0.7569" stroke-opacity="0.7569" d=" M 352.48 177.57 C 352.67 177.23 353.07 176.54 353.27 176.19 C 355.78 178.93 358.62 181.38 361.89 183.17 C 373.79 190.05 384.67 198.48 396.38 205.65 C 405.55 211.85 415.12 217.43 424.07 223.95 C 435.96 231.69 447.97 239.23 459.67 247.26 C 464.57 250.45 469.33 253.97 474.82 256.12 C 481.80 259.13 489.74 260.31 495.64 265.43 C 491.08 270.99 486.53 276.57 481.84 282.02 C 453.09 297.13 423.63 310.91 394.85 325.96 C 391.59 298.89 387.81 271.89 384.44 244.84 C 384.06 241.61 383.12 238.45 381.52 235.62 C 373.30 220.10 365.30 204.47 357.10 188.94 C 355.26 185.30 352.77 181.76 352.48 177.57 Z"/>
+        <path fill-opacity="0.753" stroke-opacity="0.753" d=" M 369.61 140.56 C 400.82 114.91 431.93 89.13 463.25 63.61 C 471.41 64.56 479.58 65.38 487.69 66.69 C 486.82 82.73 485.05 98.72 483.75 114.73 C 483.15 119.05 483.64 123.99 480.54 127.48 C 469.52 141.36 458.63 155.35 447.54 169.17 C 426.29 167.96 405.18 164.93 383.98 162.95 C 376.44 162.39 368.97 160.61 361.37 161.13 C 361.64 157.34 361.24 153.54 360.61 149.80 C 362.37 145.67 366.28 143.28 369.61 140.56 Z"/>
+        <path fill-opacity="0.7491" stroke-opacity="0.7491" d=" M 344.71 645.70 C 347.58 642.48 350.68 639.43 353.05 635.80 C 353.70 641.86 356.06 647.52 357.70 653.34 C 367.82 686.89 378.38 720.31 388.25 753.93 C 381.61 761.08 375.26 768.49 368.57 775.58 C 353.73 777.09 338.83 777.79 323.99 779.25 C 314.30 753.06 304.80 726.80 294.93 700.68 C 311.35 682.20 328.13 664.04 344.71 645.70 Z"/>
+        <path fill-opacity="0.7491" stroke-opacity="0.7491" d=" M 367.37 364.41 C 368.87 366.30 370.70 367.89 372.63 369.33 C 379.75 374.55 386.90 379.73 394 384.98 C 396.46 386.66 397.68 389.46 398.65 392.18 C 409.39 422.55 420.71 452.72 431.53 483.07 C 430.70 484.02 429.91 485 429.06 485.94 C 421.71 492.88 414.29 499.73 407.01 506.74 C 393.67 507.87 380.29 508.51 366.96 509.77 C 364.79 509.76 362.96 510.89 361.97 512.80 C 361.90 508.29 357.03 506.62 354.23 503.90 C 354.57 497.91 354.49 491.91 354.82 485.93 C 355.77 474.29 355.30 462.60 356.32 450.97 C 356.35 437.61 357.58 424.29 357.61 410.93 C 358 402.41 358.79 393.90 358.35 385.36 C 360.53 380.54 362.81 375.78 365.20 371.06 C 366.28 368.98 367.21 366.77 367.37 364.41 Z"/>
+        <path fill-opacity="0.7451" stroke-opacity="0.7451" d=" M 361.37 161.13 C 368.97 160.61 376.44 162.39 383.98 162.95 C 405.18 164.93 426.29 167.96 447.54 169.17 C 456.58 182.09 466.70 194.20 476.10 206.86 C 488.03 222.59 500.24 238.11 512.07 253.92 C 506.49 257.58 500.73 261.09 495.64 265.43 C 489.74 260.31 481.80 259.13 474.82 256.12 C 469.33 253.97 464.57 250.45 459.67 247.26 C 447.97 239.23 435.96 231.69 424.07 223.95 C 415.12 217.43 405.55 211.85 396.38 205.65 C 384.67 198.48 373.79 190.05 361.89 183.17 C 358.62 181.38 355.78 178.93 353.27 176.19 C 356.04 171.21 358.55 166.08 361.37 161.13 Z"/>
+        <path fill-opacity="0.7334" stroke-opacity="0.7334" d=" M 283.57 981.44 C 292.91 976.03 302.10 970.37 311.43 964.94 C 311.57 976.62 311.48 988.31 311.52 1000 L 274.48 1000 C 275.11 995.50 275.16 990.86 276.66 986.54 C 278.31 984.13 281.17 982.96 283.57 981.44 Z"/>
+        <path fill-opacity="0.702" stroke-opacity="0.702" d=" M 366.96 509.77 C 380.29 508.51 393.67 507.87 407.01 506.74 C 415.89 532.41 425.55 557.83 433.99 583.64 C 427.09 595.62 420.28 607.64 413.32 619.59 C 395.24 621.90 377.04 623.19 358.94 625.21 C 356.73 625.22 355.69 627.25 354.72 628.90 C 355 626.71 354.67 624.51 353.74 622.52 C 352.13 618.98 350.70 615.38 349.22 611.79 C 347.90 607.21 349.44 602.54 349.99 597.97 C 353.99 569.58 358.05 541.20 361.97 512.80 C 362.96 510.89 364.79 509.76 366.96 509.77 Z"/>
+        <path fill-opacity="0.6942" stroke-opacity="0.6942" d=" M 312.50 859.01 C 318.79 860.71 324.36 864.19 330.34 866.66 C 340.54 871.48 351.13 875.47 361.11 880.75 C 368.34 888.78 374.93 897.37 382.12 905.45 C 382.47 918.41 383.24 931.35 383.76 944.30 C 383.10 944.93 382.45 945.58 381.81 946.23 C 365.22 945.99 348.63 946.36 332.05 946.01 C 328.52 945.92 325.03 946.45 321.57 947.09 C 318.10 942.31 313.06 939.14 308.65 935.35 C 301.91 929.75 295.15 924.19 288.41 918.60 C 284.54 915.31 279.98 912.58 277.41 908.05 C 289.35 891.88 300.69 875.28 312.50 859.01 Z"/>
+        <path fill-opacity="0.6746" stroke-opacity="0.6746" d=" M 323.99 779.25 C 338.83 777.79 353.73 777.09 368.57 775.58 C 370.03 778.30 371.42 781.07 373.10 783.67 C 370.01 804.70 367.76 825.84 365.06 846.93 C 363.76 858.20 362.03 869.43 361.11 880.75 C 351.13 875.47 340.54 871.48 330.34 866.66 C 324.36 864.19 318.79 860.71 312.50 859.01 C 312.51 848.02 312.47 837.02 311.72 826.05 C 311.73 819.70 310.99 813.29 312.11 807 C 313.84 799.40 315.73 791.84 317.43 784.23 C 319.57 782.51 321.69 780.75 323.99 779.25 Z"/>
+        <path fill-opacity="0.6589" stroke-opacity="0.6589" d=" M 321.57 947.09 C 325.03 946.45 328.52 945.92 332.05 946.01 C 348.63 946.36 365.22 945.99 381.81 946.23 C 381.69 964.15 381.80 982.08 381.76 1000 L 311.52 1000 C 311.48 988.31 311.57 976.62 311.43 964.94 C 314.74 958.95 318.07 952.97 321.57 947.09 Z"/>
+        <path fill-opacity="0.6314" stroke-opacity="0.6314" d=" M 358.94 625.21 C 377.04 623.19 395.24 621.90 413.32 619.59 C 425.37 632.53 438.16 644.78 450.52 657.44 C 451.82 658.56 451.93 660.27 451.97 661.90 C 447.59 684.96 442.57 707.90 437.80 730.89 C 437.35 732.71 436.78 734.49 436.25 736.30 C 420.39 742.54 404.13 747.73 388.25 753.93 C 378.38 720.31 367.82 686.89 357.70 653.34 C 356.06 647.52 353.70 641.86 353.05 635.80 C 353.60 633.50 354.14 631.20 354.72 628.90 C 355.69 627.25 356.73 625.22 358.94 625.21 Z"/>
+        <path fill-opacity="0.6314" stroke-opacity="0.6314" d=" M 394.85 325.96 C 423.63 310.91 453.09 297.13 481.84 282.02 C 482.68 291.99 484.20 301.89 485.40 311.82 C 488.58 336.52 491.67 361.24 494.97 385.93 C 495.24 388.17 495.36 390.43 495.27 392.70 C 494.98 393.29 494.40 394.47 494.11 395.06 C 462.25 392.21 430.37 389.52 398.47 387.18 C 398.50 388.85 398.54 390.51 398.65 392.18 C 397.68 389.46 396.46 386.66 394 384.98 C 386.90 379.73 379.75 374.55 372.63 369.33 C 370.70 367.89 368.87 366.30 367.37 364.41 C 366.86 363.12 366.36 361.84 365.86 360.56 C 375.36 348.89 385.10 337.41 394.85 325.96 Z"/>
+        <path fill-opacity="0.6314" stroke-opacity="0.6314" d=" M 480.54 127.48 C 483.64 123.99 483.15 119.05 483.75 114.73 C 483.90 118.96 482.75 124.41 486.59 127.38 C 511.90 148.19 537.31 168.90 562.41 189.96 C 550.38 210.51 538.52 231.18 526.52 251.76 C 521.72 252.59 516.86 253.04 512.07 253.92 C 500.24 238.11 488.03 222.59 476.10 206.86 C 466.70 194.20 456.58 182.09 447.54 169.17 C 458.63 155.35 469.52 141.36 480.54 127.48 Z"/>
+        <path fill-opacity="0.6197" stroke-opacity="0.6197" d=" M 373.10 783.67 C 390.18 802.89 407.31 822.08 424.17 841.49 C 410.02 862.72 396.01 884.05 382.12 905.45 C 374.93 897.37 368.34 888.78 361.11 880.75 C 362.03 869.43 363.76 858.20 365.06 846.93 C 367.76 825.84 370.01 804.70 373.10 783.67 Z"/>
+        <path fill-opacity="0.6157" stroke-opacity="0.6157" d=" M 398.47 387.18 C 430.37 389.52 462.25 392.21 494.11 395.06 C 507.28 424.63 520.52 454.18 533.57 483.80 C 528.28 485.95 522.52 485.07 516.98 485.08 C 504.66 484.88 492.32 485.08 480.02 484.26 C 467.69 483.86 455.35 484.30 443.02 483.80 C 438.32 483.76 433.07 482.84 429.06 485.94 C 429.91 485 430.70 484.02 431.53 483.07 C 420.71 452.72 409.39 422.55 398.65 392.18 C 398.54 390.51 398.50 388.85 398.47 387.18 Z"/>
+        <path fill-opacity="0.5844" stroke-opacity="0.5844" d=" M 429.06 485.94 C 433.07 482.84 438.32 483.76 443.02 483.80 C 455.35 484.30 467.69 483.86 480.02 484.26 C 492.32 485.08 504.66 484.88 516.98 485.08 C 522.52 485.07 528.28 485.95 533.57 483.80 C 539.79 490.34 548.27 494.09 555.36 499.59 C 547.53 515.61 539.53 531.54 531.63 547.53 C 524.45 551.24 516.61 553.33 509.10 556.22 C 484.10 565.46 458.83 573.99 433.99 583.64 C 425.55 557.83 415.89 532.41 407.01 506.74 C 414.29 499.73 421.71 492.88 429.06 485.94 Z"/>
+        <path fill-opacity="0.5844" stroke-opacity="0.5844" d=" M 487.69 66.69 C 506.58 55.63 525.98 45.47 544.95 34.54 C 550.76 41.24 556.83 47.69 562.76 54.28 C 565.32 56.80 565.60 60.52 566.26 63.85 C 573.05 98.77 580.17 133.62 586.97 168.53 C 578.90 175.81 570.40 182.60 562.41 189.96 C 537.31 168.90 511.90 148.19 486.59 127.38 C 482.75 124.41 483.90 118.96 483.75 114.73 C 485.05 98.72 486.82 82.73 487.69 66.69 Z"/>
+        <path fill-opacity="0.5216" stroke-opacity="0.5216" d=" M 512.07 253.92 C 516.86 253.04 521.72 252.59 526.52 251.76 C 537.09 261.81 548.06 271.42 558.82 281.26 C 560.14 282.51 561.34 283.91 562.33 285.44 C 569.52 301.98 576.13 318.78 583.48 335.24 C 569.63 344.96 555.01 353.54 540.85 362.81 C 530.10 369.71 519.35 376.60 508.59 383.48 C 504.06 386.41 499.26 389.01 495.27 392.70 C 495.36 390.43 495.24 388.17 494.97 385.93 C 491.67 361.24 488.58 336.52 485.40 311.82 C 484.20 301.89 482.68 291.99 481.84 282.02 C 486.53 276.57 491.08 270.99 495.64 265.43 C 500.73 261.09 506.49 257.58 512.07 253.92 Z"/>
+        <path fill-opacity="0.5138" stroke-opacity="0.5138" d=" M 436.25 736.30 C 436.78 734.49 437.35 732.71 437.80 730.89 C 437.78 732.79 437.53 734.80 438.22 736.64 C 441.14 739 444.70 740.31 448.01 742.02 C 462.68 749.32 477.27 756.77 491.94 764.07 C 498.79 767.56 505.82 770.74 512.43 774.71 C 501.34 792.40 490.14 810.02 479.01 827.69 C 463.85 832.35 448.92 837.79 433.68 842.17 C 430.49 842.09 427.33 841.75 424.17 841.49 C 407.31 822.08 390.18 802.89 373.10 783.67 C 371.42 781.07 370.03 778.30 368.57 775.58 C 375.26 768.49 381.61 761.08 388.25 753.93 C 404.13 747.73 420.39 742.54 436.25 736.30 Z"/>
+        <path fill-opacity="0.502" stroke-opacity="0.502" d=" M 424.17 841.49 C 427.33 841.75 430.49 842.09 433.68 842.17 C 443.79 868.94 454.79 895.37 465.16 922.04 C 460.56 929.15 456.37 936.52 451.83 943.68 C 429.14 944.14 406.45 944.27 383.76 944.30 C 383.24 931.35 382.47 918.41 382.12 905.45 C 396.01 884.05 410.02 862.72 424.17 841.49 Z"/>
+        <path fill-opacity="0.502" stroke-opacity="0.502" d=" M 509.10 556.22 C 516.61 553.33 524.45 551.24 531.63 547.53 C 531.09 554.71 532.47 561.85 532.51 569.03 C 533.82 590.96 534.99 612.90 536.37 634.83 C 536.49 638.03 536.17 641.23 535.71 644.41 C 511.02 648.82 486.33 653.26 461.60 657.44 C 458.13 658.12 453.60 658.08 451.97 661.90 C 451.93 660.27 451.82 658.56 450.52 657.44 C 438.16 644.78 425.37 632.53 413.32 619.59 C 420.28 607.64 427.09 595.62 433.99 583.64 C 458.83 573.99 484.10 565.46 509.10 556.22 Z"/>
+        <path fill-opacity="0.4589" stroke-opacity="0.4589" d=" M 383.76 944.30 C 406.45 944.27 429.14 944.14 451.83 943.68 C 458.08 952.20 465.10 960.12 471.58 968.46 C 473.14 970.27 472.78 972.79 472.87 975.02 C 472.77 983.34 472.82 991.67 472.82 1000 L 381.76 1000 C 381.80 982.08 381.69 964.15 381.81 946.23 C 382.45 945.58 383.10 944.93 383.76 944.30 Z"/>
+        <path fill-opacity="0.451" stroke-opacity="0.451" d=" M 536.37 634.83 C 536.58 638.08 536.48 641.43 537.46 644.58 C 539.62 647.76 543.06 649.85 545.15 653.11 C 545.66 658.17 544.69 663.26 544.85 668.34 C 544.21 689.37 543.11 710.37 542.39 731.40 C 534.92 744.44 528.94 758.25 522.46 771.80 C 519.13 772.81 515.79 773.78 512.43 774.71 C 505.82 770.74 498.79 767.56 491.94 764.07 C 477.27 756.77 462.68 749.32 448.01 742.02 C 444.70 740.31 441.14 739 438.22 736.64 C 437.53 734.80 437.78 732.79 437.80 730.89 C 442.57 707.90 447.59 684.96 451.97 661.90 C 453.60 658.08 458.13 658.12 461.60 657.44 C 486.33 653.26 511.02 648.82 535.71 644.41 C 536.17 641.23 536.49 638.03 536.37 634.83 Z"/>
+        <path fill-opacity="0.4471" stroke-opacity="0.4471" d=" M 583.48 335.24 C 584.46 336.34 585.53 337.35 586.52 338.44 C 588.74 340.41 587.58 343.67 587.71 346.25 C 584.34 395.33 580.99 444.42 577.57 493.49 C 574.88 494.46 572.34 495.77 569.64 496.68 C 564.91 497.79 560.10 498.51 555.36 499.59 C 548.27 494.09 539.79 490.34 533.57 483.80 C 520.52 454.18 507.28 424.63 494.11 395.06 C 494.40 394.47 494.98 393.29 495.27 392.70 C 499.26 389.01 504.06 386.41 508.59 383.48 C 519.35 376.60 530.10 369.71 540.85 362.81 C 555.01 353.54 569.63 344.96 583.48 335.24 Z"/>
+        <path fill-opacity="0.4393" stroke-opacity="0.4393" d=" M 433.68 842.17 C 448.92 837.79 463.85 832.35 479.01 827.69 C 488.83 848.96 499.05 870.04 508.51 891.47 C 493.97 901.52 479.45 911.63 465.16 922.04 C 454.79 895.37 443.79 868.94 433.68 842.17 Z"/>
+        <path fill-opacity="0.3961" stroke-opacity="0.3961" d=" M 548.99 0 L 752.49 0 C 751.57 1.16 751.04 2.54 750.61 3.94 C 750.16 5.19 749.66 6.42 749.13 7.64 C 719.08 25.92 689.52 45.01 659.60 63.50 C 656.73 65.18 653.97 67.02 651.37 69.08 C 655.42 91.72 659.79 114.31 664 136.92 C 664.77 141.83 666.66 146.76 665.62 151.78 C 651.11 157.78 637.30 165.39 622.97 171.81 C 610.97 170.72 598.96 169.67 586.97 168.53 C 580.17 133.62 573.05 98.77 566.26 63.85 C 565.60 60.52 565.32 56.80 562.76 54.28 C 556.83 47.69 550.76 41.24 544.95 34.54 C 546.25 23.02 548.07 11.56 548.99 0 Z"/>
+        <path fill-opacity="0.3687" stroke-opacity="0.3687" d=" M 586.97 168.53 C 598.96 169.67 610.97 170.72 622.97 171.81 C 633.32 193.14 643.74 214.44 653.61 235.98 C 648.65 244.69 642.86 252.90 637.62 261.44 C 617.19 268.02 596.43 273.61 575.89 279.86 C 571.29 281.46 565.79 281.59 562.33 285.44 C 561.34 283.91 560.14 282.51 558.82 281.26 C 548.06 271.42 537.09 261.81 526.52 251.76 C 538.52 231.18 550.38 210.51 562.41 189.96 C 570.40 182.60 578.90 175.81 586.97 168.53 Z"/>
+        <path fill-opacity="0.3412" stroke-opacity="0.3412" d=" M 512.43 774.71 C 515.79 773.78 519.13 772.81 522.46 771.80 C 527.25 776.63 532.88 780.51 538.16 784.78 C 551.94 795.69 565.68 806.65 579.53 817.48 C 583.79 820.92 588.31 824.07 592.20 827.94 C 592.18 829.33 592.15 830.72 592.12 832.13 C 590.98 839.36 589.97 846.61 588.75 853.84 C 575.55 867.75 562.90 882.18 549.54 895.94 C 535.74 896.31 522.21 892.68 508.51 891.47 C 499.05 870.04 488.83 848.96 479.01 827.69 C 490.14 810.02 501.34 792.40 512.43 774.71 Z"/>
+        <path fill-opacity="0.3334" stroke-opacity="0.3334" d=" M 508.51 891.47 C 522.21 892.68 535.74 896.31 549.54 895.94 C 550.96 909.71 554.66 923.17 556.88 936.84 C 557.08 938.56 557.22 940.29 557.38 942.04 C 547.38 951.07 536.31 958.85 526.01 967.53 C 508.78 968.54 491.54 969.34 474.31 970.32 C 473.64 980.19 474.22 990.10 474 1000 L 472.82 1000 C 472.82 991.67 472.77 983.34 472.87 975.02 C 472.78 972.79 473.14 970.27 471.58 968.46 C 465.10 960.12 458.08 952.20 451.83 943.68 C 456.37 936.52 460.56 929.15 465.16 922.04 C 479.45 911.63 493.97 901.52 508.51 891.47 Z"/>
+        <path fill-opacity="0.3216" stroke-opacity="0.3216" d=" M 575.89 279.86 C 596.43 273.61 617.19 268.02 637.62 261.44 C 649.11 279.16 662.99 295.22 674.57 312.89 C 669.49 320.50 664.96 328.47 659.86 336.06 C 653.09 339.62 646.32 343.23 639.31 346.27 C 631.42 347.71 623.67 344.91 615.87 344.16 C 607.08 343.27 598.47 341.13 589.67 340.37 C 588.99 342.32 588.24 344.25 587.71 346.25 C 587.58 343.67 588.74 340.41 586.52 338.44 C 585.53 337.35 584.46 336.34 583.48 335.24 C 576.13 318.78 569.52 301.98 562.33 285.44 C 565.79 281.59 571.29 281.46 575.89 279.86 Z"/>
+        <path fill-opacity="0.3138" stroke-opacity="0.3138" d=" M 589.67 340.37 C 598.47 341.13 607.08 343.27 615.87 344.16 C 623.67 344.91 631.42 347.71 639.31 346.27 C 639.01 352.18 641.28 357.74 642.65 363.39 C 651.70 398.56 660.94 433.68 670.10 468.83 C 671.32 473.15 672.40 477.53 673.10 481.98 C 671.85 483.92 670.76 485.95 669.63 487.95 C 638.97 490.28 608.24 491.42 577.57 493.49 C 580.99 444.42 584.34 395.33 587.71 346.25 C 588.24 344.25 588.99 342.32 589.67 340.37 Z"/>
+        <path fill-opacity="0.3059" stroke-opacity="0.3059" d=" M 474.31 970.32 C 491.54 969.34 508.78 968.54 526.01 967.53 C 528.79 978.42 531.84 989.24 535.09 1000 L 474 1000 C 474.22 990.10 473.64 980.19 474.31 970.32 Z"/>
+        <path fill-opacity="0.302" stroke-opacity="0.302" d=" M 555.36 499.59 C 560.10 498.51 564.91 497.79 569.64 496.68 C 591.15 547.16 611.72 598.03 633.23 648.51 C 632.96 649.01 632.42 650.02 632.14 650.52 C 628.14 651.22 624.08 651.24 620.05 651.15 C 608.68 650.98 597.35 652.06 585.99 652.11 C 572.75 652 559.51 652.48 546.31 653.29 C 546.11 658.33 545.82 663.38 544.85 668.34 C 544.69 663.26 545.66 658.17 545.15 653.11 C 543.06 649.85 539.62 647.76 537.46 644.58 C 536.48 641.43 536.58 638.08 536.37 634.83 C 534.99 612.90 533.82 590.96 532.51 569.03 C 532.47 561.85 531.09 554.71 531.63 547.53 C 539.53 531.54 547.53 515.61 555.36 499.59 Z"/>
+        <path fill-opacity="0.2902" stroke-opacity="0.2902" d=" M 659.60 63.50 C 689.52 45.01 719.08 25.92 749.13 7.64 C 746.17 14.12 744.09 20.95 741.61 27.61 C 726.43 69.59 711.39 111.61 696.08 153.54 C 685.90 153.39 675.80 150.55 665.62 151.78 C 666.66 146.76 664.77 141.83 664 136.92 C 659.79 114.31 655.42 91.72 651.37 69.08 C 653.97 67.02 656.73 65.18 659.60 63.50 Z"/>
+        <path fill-opacity="0.2746" stroke-opacity="0.2746" d=" M 665.62 151.78 C 675.80 150.55 685.90 153.39 696.08 153.54 C 702.53 158.23 709.03 162.85 715.68 167.28 C 717.91 168.86 720.74 170.41 720.95 173.49 C 716.99 189.35 712.80 205.17 708.55 220.96 C 702.71 227.74 695.30 233.01 689.72 240.03 C 694.43 258.79 700.76 277.13 705.65 295.85 C 695.53 301.97 684.56 306.57 674.57 312.89 C 662.99 295.22 649.11 279.16 637.62 261.44 C 642.86 252.90 648.65 244.69 653.61 235.98 C 643.74 214.44 633.32 193.14 622.97 171.81 C 637.30 165.39 651.11 157.78 665.62 151.78 Z"/>
+        <path fill-opacity="0.2667" stroke-opacity="0.2667" d=" M 633.23 648.51 C 636.96 652.72 642.83 653.38 647.86 655.15 C 655.21 657.70 662.83 659.66 669.81 663.16 L 670.43 664.19 C 665.52 670.04 659.35 674.61 653.88 679.89 C 637.25 694.84 621.03 710.27 604.11 724.89 C 602.47 726.05 600.74 727.07 598.95 727.97 C 580.06 728.51 561.27 730.89 542.39 731.40 C 543.11 710.37 544.21 689.37 544.85 668.34 C 545.82 663.38 546.11 658.33 546.31 653.29 C 559.51 652.48 572.75 652 585.99 652.11 C 597.35 652.06 608.68 650.98 620.05 651.15 C 624.08 651.24 628.14 651.22 632.14 650.52 C 632.42 650.02 632.96 649.01 633.23 648.51 Z"/>
+        <path fill-opacity="0.2471" stroke-opacity="0.2471" d=" M 542.39 731.40 C 561.27 730.89 580.06 728.51 598.95 727.97 C 602.54 748.12 605.51 768.37 609.47 788.45 C 611.30 797.84 612.25 807.43 615.07 816.61 C 608.49 819.78 601.98 823.09 595.50 826.47 C 593.13 827.36 592.63 829.94 592.12 832.13 C 592.15 830.72 592.18 829.33 592.20 827.94 C 588.31 824.07 583.79 820.92 579.53 817.48 C 565.68 806.65 551.94 795.69 538.16 784.78 C 532.88 780.51 527.25 776.63 522.46 771.80 C 528.94 758.25 534.92 744.44 542.39 731.40 Z"/>
+        <path fill-opacity="0.2471" stroke-opacity="0.2471" d=" M 556.88 936.84 C 557.66 939.47 558.49 942.39 560.93 944 C 571.58 951.44 582.47 958.56 593.27 965.78 C 596.97 967.84 596.04 972.66 596.15 976.20 C 595.57 984.13 594.99 992.06 594.47 1000 L 535.09 1000 C 531.84 989.24 528.79 978.42 526.01 967.53 C 536.31 958.85 547.38 951.07 557.38 942.04 C 557.22 940.29 557.08 938.56 556.88 936.84 Z"/>
+        <path fill-opacity="0.2393" stroke-opacity="0.2393" d=" M 577.57 493.49 C 608.24 491.42 638.97 490.28 669.63 487.95 C 672.64 492.67 676.16 497.03 679.42 501.58 C 681.82 504.89 682.08 509.10 682.98 512.96 C 686.01 527.26 689.06 541.56 692.18 555.85 C 694.79 566.71 694.12 577.96 695.28 589 C 695.40 597.90 696.86 606.75 696.49 615.66 C 687.62 631.50 678.62 647.28 669.81 663.16 C 662.83 659.66 655.21 657.70 647.86 655.15 C 642.83 653.38 636.96 652.72 633.23 648.51 C 611.72 598.03 591.15 547.16 569.64 496.68 C 572.34 495.77 574.88 494.46 577.57 493.49 Z"/>
+        <path fill-opacity="0.2236" stroke-opacity="0.2236" d=" M 598.95 727.97 C 600.74 727.07 602.47 726.05 604.11 724.89 C 605.28 730.81 609.93 734.93 613.55 739.44 C 619.31 746.36 624.56 753.68 630.34 760.59 C 639.19 771.33 647.40 782.57 656.31 793.26 C 651.21 797.42 646.65 802.22 641.58 806.42 C 632.98 810.38 623.89 813.17 615.07 816.61 C 612.25 807.43 611.30 797.84 609.47 788.45 C 605.51 768.37 602.54 748.12 598.95 727.97 Z"/>
+        <path fill-opacity="0.2236" stroke-opacity="0.2236" d=" M 639.31 346.27 C 646.32 343.23 653.09 339.62 659.86 336.06 C 686.51 356.31 713.55 376.05 740.33 396.14 C 737.83 405.13 735.79 414.24 733.43 423.26 C 726.43 430.99 718.38 437.67 711.03 445.06 C 698.51 457.49 685.27 469.21 673.10 481.98 C 672.40 477.53 671.32 473.15 670.10 468.83 C 660.94 433.68 651.70 398.56 642.65 363.39 C 641.28 357.74 639.01 352.18 639.31 346.27 Z"/>
+        <path fill-opacity="0.204" stroke-opacity="0.204" d=" M 670.43 664.19 C 673.37 669.51 676.64 674.69 680.28 679.57 C 680.07 685.74 678.68 691.78 677.73 697.87 C 672.88 727.26 667.93 756.63 663.09 786.02 C 663.02 789.97 658.96 791.26 656.31 793.26 C 647.40 782.57 639.19 771.33 630.34 760.59 C 624.56 753.68 619.31 746.36 613.55 739.44 C 609.93 734.93 605.28 730.81 604.11 724.89 C 621.03 710.27 637.25 694.84 653.88 679.89 C 659.35 674.61 665.52 670.04 670.43 664.19 Z"/>
+        <path fill-opacity="0.204" stroke-opacity="0.204" d=" M 749.13 7.64 C 749.66 6.42 750.16 5.19 750.61 3.94 C 750.67 6.58 751.26 9.18 752.36 11.59 C 755.89 19.76 759.32 27.98 762.75 36.20 C 764.72 42.32 765.62 48.72 766.93 55.01 C 773.01 86.59 779.53 118.10 785.40 149.72 C 778.91 155.99 772.99 162.83 766.44 169.04 L 765.86 169.66 C 753.56 169.96 741.28 171.12 728.96 170.89 C 726.04 170.77 722.99 171.20 720.95 173.49 C 720.74 170.41 717.91 168.86 715.68 167.28 C 709.03 162.85 702.53 158.23 696.08 153.54 C 711.39 111.61 726.43 69.59 741.61 27.61 C 744.09 20.95 746.17 14.12 749.13 7.64 Z"/>
+        <path fill-opacity="0.1961" stroke-opacity="0.1961" d=" M 549.54 895.94 C 562.90 882.18 575.55 867.75 588.75 853.84 C 611.64 877.83 634.46 901.89 657.15 926.06 C 656.36 929.33 655.59 932.60 654.83 935.87 C 654.19 938.27 652.78 940.46 650.40 941.42 C 633.66 949.65 616.96 957.96 600.28 966.30 C 596.10 967.73 596.74 972.66 596.15 976.20 C 596.04 972.66 596.97 967.84 593.27 965.78 C 582.47 958.56 571.58 951.44 560.93 944 C 558.49 942.39 557.66 939.47 556.88 936.84 C 554.66 923.17 550.96 909.71 549.54 895.94 Z"/>
+        <path fill-opacity="0.1922" stroke-opacity="0.1922" d=" M 689.72 240.03 C 695.30 233.01 702.71 227.74 708.55 220.96 C 729.63 237.23 751.13 252.97 772.39 269.02 C 774.53 273.76 776.69 278.50 778.34 283.45 C 772.10 290.31 765.48 296.90 759.75 304.18 C 758.77 315.38 760.52 326.70 760.51 337.95 C 760.45 347.13 761.52 356.26 761.54 365.43 C 761.72 367.63 760.46 369.50 759.20 371.16 C 752.89 379.47 746.40 387.65 740.33 396.14 C 713.55 376.05 686.51 356.31 659.86 336.06 C 664.96 328.47 669.49 320.50 674.57 312.89 C 684.56 306.57 695.53 301.97 705.65 295.85 C 700.76 277.13 694.43 258.79 689.72 240.03 Z"/>
+        <path fill-opacity="0.1726" stroke-opacity="0.1726" d=" M 728.96 170.89 C 741.28 171.12 753.56 169.96 765.86 169.66 C 767.88 202.79 770.11 235.91 772.39 269.02 C 751.13 252.97 729.63 237.23 708.55 220.96 C 712.80 205.17 716.99 189.35 720.95 173.49 C 722.99 171.20 726.04 170.77 728.96 170.89 Z"/>
+        <path fill-opacity="0.1373" stroke-opacity="0.1373" d=" M 615.07 816.61 C 623.89 813.17 632.98 810.38 641.58 806.42 C 645.25 814.64 651.10 821.57 655.80 829.20 C 662.57 839.43 669.51 849.54 676.01 859.95 C 683.53 871.53 691.70 882.72 698.41 894.81 C 684.54 905.07 670.88 915.62 657.15 926.06 C 634.46 901.89 611.64 877.83 588.75 853.84 C 589.97 846.61 590.98 839.36 592.12 832.13 C 592.63 829.94 593.13 827.36 595.50 826.47 C 601.98 823.09 608.49 819.78 615.07 816.61 Z"/>
+        <path fill-opacity="0.1295" stroke-opacity="0.1295" d=" M 650.40 941.42 C 652.78 940.46 654.19 938.27 654.83 935.87 C 654.11 940.20 656.63 943.95 659.34 947.04 C 659.81 955.51 657.31 963.73 656.19 972.06 C 654.57 981.35 653.10 990.68 651.63 1000 L 594.47 1000 C 594.99 992.06 595.57 984.13 596.15 976.20 C 596.74 972.66 596.10 967.73 600.28 966.30 C 616.96 957.96 633.66 949.65 650.40 941.42 Z"/>
+        <path fill-opacity="0.1099" stroke-opacity="0.1099" d=" M 762.75 36.20 C 766.71 41.26 771.97 45.04 776.93 49.06 C 798.92 67.11 821.26 84.72 843.22 102.80 C 851.79 109.79 860.76 116.35 868.75 124.02 C 863.32 131.42 858.08 138.97 852.75 146.45 C 840.17 147.38 827.57 148.12 814.96 148.25 C 805.13 149.30 795.23 148.69 785.40 149.72 C 779.53 118.10 773.01 86.59 766.93 55.01 C 765.62 48.72 764.72 42.32 762.75 36.20 Z"/>
+        <path fill-opacity="0.1099" stroke-opacity="0.1099" d=" M 765.86 169.66 L 766.44 169.04 C 772.86 175.47 779.26 181.93 786.19 187.83 C 793.68 195.35 801.97 202.02 809.24 209.77 C 815.06 215.97 821.92 221.08 827.75 227.28 C 832.77 232.60 838.67 236.99 843.78 242.23 C 851.02 249.65 858.99 256.30 866.37 263.58 C 867.88 265.06 868.96 266.92 869.91 268.80 C 847.35 272.31 824.78 275.77 802.23 279.32 C 794.26 280.71 786.20 281.51 778.34 283.45 C 776.69 278.50 774.53 273.76 772.39 269.02 C 770.11 235.91 767.88 202.79 765.86 169.66 Z"/>
+        <path fill-opacity="0.0981" stroke-opacity="0.0981" d=" M 659.34 947.04 C 666.64 954.72 675.44 960.72 683.61 967.40 C 686.99 969.43 686.98 973.49 686.86 976.98 C 686.69 984.65 686.91 992.33 686.56 1000 L 651.63 1000 C 653.10 990.68 654.57 981.35 656.19 972.06 C 657.31 963.73 659.81 955.51 659.34 947.04 Z"/>
+        <path fill-opacity="0.0981" stroke-opacity="0.0981" d=" M 680.28 679.57 C 687.62 684.43 696.11 687.13 703.96 691.05 C 722.31 699.32 740.63 707.71 759 715.95 C 762.03 718.58 764.89 721.40 767.81 724.15 C 770.49 726.35 772.43 729.42 771.89 733.04 C 769.33 746.88 766.91 760.75 764.61 774.64 C 764.05 778.01 763.04 781.33 761.34 784.31 C 757.72 790.74 754.18 797.21 750.52 803.62 C 749.47 805.68 747.92 807.89 748.63 810.32 C 750.24 817.07 752.40 823.68 754.30 830.36 C 749.73 838.49 743.41 845.43 738.03 853.02 C 728.16 866.13 718.43 879.35 708.50 892.42 C 705.14 893.21 701.73 893.85 698.41 894.81 C 691.70 882.72 683.53 871.53 676.01 859.95 C 669.51 849.54 662.57 839.43 655.80 829.20 C 651.10 821.57 645.25 814.64 641.58 806.42 C 646.65 802.22 651.21 797.42 656.31 793.26 C 658.96 791.26 663.02 789.97 663.09 786.02 C 667.93 756.63 672.88 727.26 677.73 697.87 C 678.68 691.78 680.07 685.74 680.28 679.57 Z"/>
+        <path fill-opacity="0.0942" stroke-opacity="0.0942" d=" M 752.49 0 L 873.98 0 C 876.68 6.74 879 13.64 881.62 20.41 C 884.17 26.93 884.36 34.01 885.38 40.86 C 888.28 61.72 890.87 82.62 893.89 103.47 C 886.04 110.94 876.82 116.79 868.75 124.02 C 860.76 116.35 851.79 109.79 843.22 102.80 C 821.26 84.72 798.92 67.11 776.93 49.06 C 771.97 45.04 766.71 41.26 762.75 36.20 C 759.32 27.98 755.89 19.76 752.36 11.59 C 751.26 9.18 750.67 6.58 750.61 3.94 C 751.04 2.54 751.57 1.16 752.49 0 Z"/>
+        <path fill-opacity="0.0902" stroke-opacity="0.0902" d=" M 814.96 148.25 C 827.57 148.12 840.17 147.38 852.75 146.45 C 858.94 167.78 866.25 188.79 873.07 209.93 C 878.63 227.75 884.77 245.39 890.20 263.25 C 889.15 265.06 888.17 266.92 887.29 268.81 C 881.49 268.88 875.70 268.56 869.91 268.80 C 868.96 266.92 867.88 265.06 866.37 263.58 C 858.99 256.30 851.02 249.65 843.78 242.23 C 838.67 236.99 832.77 232.60 827.75 227.28 C 821.92 221.08 815.06 215.97 809.24 209.77 C 801.97 202.02 793.68 195.35 786.19 187.83 C 779.26 181.93 772.86 175.47 766.44 169.04 C 772.99 162.83 778.91 155.99 785.40 149.72 C 795.23 148.69 805.13 149.30 814.96 148.25 Z"/>
+        <path fill-opacity="0.0863" stroke-opacity="0.0863" d=" M 711.03 445.06 C 718.38 437.67 726.43 430.99 733.43 423.26 C 738.41 425.93 743.61 428.13 748.88 430.14 C 768.70 438.32 788.46 446.63 808.31 454.74 C 812.63 456.62 817.39 457.76 821.21 460.63 C 822.11 462.68 822.15 464.98 822.32 467.19 C 820.49 484.05 818.56 500.89 816.77 517.75 C 817 524.38 810.75 528.04 808.89 533.89 C 806.01 541.30 802.91 548.62 799.98 556.01 C 797.54 562.18 794.18 568.14 793.58 574.87 C 792.35 587.55 790.89 600.21 789.56 612.88 C 788.95 614.74 788.18 616.55 787.51 618.40 C 777.69 617.60 767.85 616.72 757.99 616.99 C 745.96 617.26 733.99 615.75 721.96 615.93 C 713.46 616.06 704.97 614.27 696.49 615.66 C 696.86 606.75 695.40 597.90 695.28 589 C 694.12 577.96 694.79 566.71 692.18 555.85 C 689.06 541.56 686.01 527.26 682.98 512.96 C 682.08 509.10 681.82 504.89 679.42 501.58 C 676.16 497.03 672.64 492.67 669.63 487.95 C 670.76 485.95 671.85 483.92 673.10 481.98 C 685.27 469.21 698.51 457.49 711.03 445.06 Z"/>
+        <path fill-opacity="0.0746" stroke-opacity="0.0746" d=" M 696.49 615.66 C 704.97 614.27 713.46 616.06 721.96 615.93 C 733.99 615.75 745.96 617.26 757.99 616.99 C 767.85 616.72 777.69 617.60 787.51 618.40 C 777.55 650.78 768.67 683.48 759 715.95 C 740.63 707.71 722.31 699.32 703.96 691.05 C 696.11 687.13 687.62 684.43 680.28 679.57 C 676.64 674.69 673.37 669.51 670.43 664.19 L 669.81 663.16 C 678.62 647.28 687.62 631.50 696.49 615.66 Z"/>
+        <path fill-opacity="0.0746" stroke-opacity="0.0746" d=" M 869.91 268.80 C 875.70 268.56 881.49 268.88 887.29 268.81 C 886.50 273.37 886.89 278.07 885.72 282.57 C 876.65 314.58 867.66 346.61 858.72 378.65 C 857.40 387.68 864.96 395.07 865.78 403.83 C 865.33 406.05 864.08 407.99 863.01 409.95 C 856.26 421.20 850.06 432.78 843.28 444.01 C 837.58 449.10 831.44 453.68 825.64 458.64 C 822.98 460.65 822.73 464.15 822.32 467.19 C 822.15 464.98 822.11 462.68 821.21 460.63 C 817.39 457.76 812.63 456.62 808.31 454.74 C 788.46 446.63 768.70 438.32 748.88 430.14 C 743.61 428.13 738.41 425.93 733.43 423.26 C 735.79 414.24 737.83 405.13 740.33 396.14 C 746.40 387.65 752.89 379.47 759.20 371.16 C 760.46 369.50 761.72 367.63 761.54 365.43 C 761.52 356.26 760.45 347.13 760.51 337.95 C 760.52 326.70 758.77 315.38 759.75 304.18 C 765.48 296.90 772.10 290.31 778.34 283.45 C 786.20 281.51 794.26 280.71 802.23 279.32 C 824.78 275.77 847.35 272.31 869.91 268.80 Z"/>
+        <path fill-opacity="0.0667" stroke-opacity="0.0667" d=" M 698.41 894.81 C 701.73 893.85 705.14 893.21 708.50 892.42 C 713.85 898.11 719.92 903.07 725.25 908.79 C 732.04 916.01 739.89 922.12 746.75 929.26 C 752.61 935.29 758.94 940.86 764.30 947.36 C 758.51 952.88 752.97 958.67 746.93 963.92 C 743.30 967.28 739.36 970.38 736.29 974.28 C 734.56 976.45 734.77 979.39 734.68 982.01 C 734.75 988 734.87 994 734.71 1000 L 686.56 1000 C 686.91 992.33 686.69 984.65 686.86 976.98 C 686.98 973.49 686.99 969.43 683.61 967.40 C 675.44 960.72 666.64 954.72 659.34 947.04 C 656.63 943.95 654.11 940.20 654.83 935.87 C 655.59 932.60 656.36 929.33 657.15 926.06 C 670.88 915.62 684.54 905.07 698.41 894.81 Z"/>
+        <path fill-opacity="0.0471" stroke-opacity="0.0471" d=" M 787.51 618.40 C 788.18 616.55 788.95 614.74 789.56 612.88 C 789.88 614.38 790.15 615.94 790.82 617.36 C 794.07 619.90 798.13 621.09 801.67 623.19 C 805.40 628.31 808.55 633.82 811.83 639.23 C 817.87 649.15 824.12 658.93 830.19 668.84 C 833.45 674.34 837.55 679.47 839.28 685.74 C 836.01 694.64 832.64 703.52 829.63 712.52 C 825.16 716.10 819.26 716.46 813.95 717.96 C 801.60 721.33 789.17 724.40 776.82 727.73 C 774 728.09 772.74 730.65 771.89 733.04 C 772.43 729.42 770.49 726.35 767.81 724.15 C 764.89 721.40 762.03 718.58 759 715.95 C 768.67 683.48 777.55 650.78 787.51 618.40 Z"/>
+        <path fill-opacity="0.0432" stroke-opacity="0.0432" d=" M 754.30 830.36 C 760.41 835.62 767.69 839.19 774.38 843.62 C 793.35 855.31 812.26 867.09 831.20 878.84 C 834.71 881.16 839.88 882.84 840.16 887.80 C 835.77 902.44 832.15 917.30 828.05 932.03 C 826.65 937.67 821.99 941.47 818.08 945.42 C 808.76 946.55 799.37 945.61 790.03 946.14 C 781.47 946.93 772.87 946.89 764.30 947.36 C 758.94 940.86 752.61 935.29 746.75 929.26 C 739.89 922.12 732.04 916.01 725.25 908.79 C 719.92 903.07 713.85 898.11 708.50 892.42 C 718.43 879.35 728.16 866.13 738.03 853.02 C 743.41 845.43 749.73 838.49 754.30 830.36 Z"/>
+        <path fill-opacity="0.0353" stroke-opacity="0.0353" d=" M 808.89 533.89 C 810.75 528.04 817 524.38 816.77 517.75 C 816.73 520.32 817.11 522.87 817.56 525.40 C 832.54 532.40 848.09 538.17 863.22 544.85 C 865.98 545.63 865.90 548.79 866.30 551.10 C 862.94 566.99 860.24 583 856.85 598.88 C 856.09 601.52 854.54 604.04 851.66 604.67 C 838.22 609.05 824.97 613.99 811.60 618.56 C 808.12 619.72 804.84 621.37 801.67 623.19 C 798.13 621.09 794.07 619.90 790.82 617.36 C 790.15 615.94 789.88 614.38 789.56 612.88 C 790.89 600.21 792.35 587.55 793.58 574.87 C 794.18 568.14 797.54 562.18 799.98 556.01 C 802.91 548.62 806.01 541.30 808.89 533.89 Z"/>
+        <path fill-opacity="0.0314" stroke-opacity="0.0314" d=" M 893.89 103.47 C 906.72 109.97 920.98 112.62 934.39 117.61 C 947.25 122.33 960.45 126.10 973.36 130.67 C 974.09 136.90 973.52 143.23 974.75 149.42 C 975.16 156.15 978.35 164.36 973.07 169.95 C 950.88 194.15 929.29 218.90 907.14 243.13 C 901.51 249.85 894.98 255.86 890.20 263.25 C 884.77 245.39 878.63 227.75 873.07 209.93 C 866.25 188.79 858.94 167.78 852.75 146.45 C 858.08 138.97 863.32 131.42 868.75 124.02 C 876.82 116.79 886.04 110.94 893.89 103.47 Z"/>
+        <path fill-opacity="0.0275" stroke-opacity="0.0275" d=" M 790.03 946.14 C 799.37 945.61 808.76 946.55 818.08 945.42 C 817.60 963.61 818.21 981.81 817.75 1000 L 734.71 1000 C 734.87 994 734.75 988 734.68 982.01 C 734.77 979.39 734.56 976.45 736.29 974.28 C 739.36 970.38 743.30 967.28 746.93 963.92 C 752.97 958.67 758.51 952.88 764.30 947.36 C 772.87 946.89 781.47 946.93 790.03 946.14 Z"/>
+        <path fill-opacity="0.0236" stroke-opacity="0.0236" d=" M 873.98 0 L 1000 0 L 1000 103.37 C 993.93 110.15 987.92 117.01 981.22 123.19 C 978.82 125.72 975.31 128.07 975.22 131.91 C 975.04 137.75 975.28 143.60 974.75 149.42 C 973.52 143.23 974.09 136.90 973.36 130.67 C 960.45 126.10 947.25 122.33 934.39 117.61 C 920.98 112.62 906.72 109.97 893.89 103.47 C 890.87 82.62 888.28 61.72 885.38 40.86 C 884.36 34.01 884.17 26.93 881.62 20.41 C 879 13.64 876.68 6.74 873.98 0 Z"/>
+        <path fill-opacity="0.0197" stroke-opacity="0.0197" d=" M 813.95 717.96 C 819.26 716.46 825.16 716.10 829.63 712.52 C 832.23 717.98 837.20 721.57 841.62 725.46 C 855.50 738.57 869.89 751.14 883.88 764.14 C 887.48 767.46 892.20 770.22 893.70 775.19 C 895.08 779.49 895.87 783.95 896.79 788.37 C 897.04 790.36 897.79 792.67 896.47 794.46 C 894.23 797.83 891.15 800.52 888.69 803.72 C 885.29 807.93 883.06 812.88 880.64 817.67 C 871.47 834.90 862.59 852.27 853.59 869.60 C 851.55 873.40 849.91 877.61 846.52 880.46 C 844.06 882.58 841.54 884.78 840.16 887.80 C 839.88 882.84 834.71 881.16 831.20 878.84 C 812.26 867.09 793.35 855.31 774.38 843.62 C 767.69 839.19 760.41 835.62 754.30 830.36 C 752.40 823.68 750.24 817.07 748.63 810.32 C 747.92 807.89 749.47 805.68 750.52 803.62 C 754.18 797.21 757.72 790.74 761.34 784.31 C 763.04 781.33 764.05 778.01 764.61 774.64 C 766.91 760.75 769.33 746.88 771.89 733.04 C 772.74 730.65 774 728.09 776.82 727.73 C 789.17 724.40 801.60 721.33 813.95 717.96 Z"/>
+        <path fill-opacity="0.0197" stroke-opacity="0.0197" d=" M 825.64 458.64 C 831.44 453.68 837.58 449.10 843.28 444.01 C 848.20 449.37 853.71 454.12 859.06 459.03 C 878.31 476.08 896.94 493.83 916.28 510.78 C 920.39 514.58 920.49 520.85 919.86 526.02 C 918.54 530.85 915.41 536.24 910.06 537.19 C 896.89 539.99 883.68 542.68 870.57 545.70 C 867.74 546 866.93 548.78 866.30 551.10 C 865.90 548.79 865.98 545.63 863.22 544.85 C 848.09 538.17 832.54 532.40 817.56 525.40 C 817.11 522.87 816.73 520.32 816.77 517.75 C 818.56 500.89 820.49 484.05 822.32 467.19 C 822.73 464.15 822.98 460.65 825.64 458.64 Z"/>
+        <path fill-opacity="0.0157" stroke-opacity="0.0157" d=" M 851.66 604.67 C 854.54 604.04 856.09 601.52 856.85 598.88 C 856.82 602.45 857.75 606.09 860.32 608.70 C 865.38 614.29 870.41 619.92 875.17 625.79 C 881.34 633.49 888.28 640.56 894.26 648.42 C 892.01 651.58 888.48 653.35 885.26 655.34 C 874.38 662.07 863.58 668.92 852.86 675.89 C 848.21 678.98 842.80 681.24 839.28 685.74 C 837.55 679.47 833.45 674.34 830.19 668.84 C 824.12 658.93 817.87 649.15 811.83 639.23 C 808.55 633.82 805.40 628.31 801.67 623.19 C 804.84 621.37 808.12 619.72 811.60 618.56 C 824.97 613.99 838.22 609.05 851.66 604.67 Z"/>
+    </g>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/resources/runner/lines.svg b/third_party/blink/perf_tests/MotionMark/resources/runner/lines.svg
new file mode 100644
index 0000000..83458b8
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/runner/lines.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg viewBox="0 0 1052 1251" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <g fill-opacity="0.5" fill="white">
+        <polygon points="221.761719 0 223.761719 0 2.12833345 1250.36328 0.128333454 1250.36328"/>
+        <polygon points="261.761719 0 265.761719 0 44.1283335 1250.36328 40.1283335 1250.36328"/>
+        <polygon points="301.761719 0 307.761719 0 86.1283335 1250.36328 80.1283335 1250.36328"/>
+        <polygon points="341.761719 0 349.761719 0 128.128333 1250.36328 120.128333 1250.36328"/>
+        <polygon points="381.761719 0 391.761719 0 170.128333 1250.36328 160.128333 1250.36328"/>
+        <polygon points="421.761719 0 433.761719 0 212.128333 1250.36328 200.128333 1250.36328"/>
+        <polygon points="461.761719 0 475.761719 0 254.128333 1250.36328 240.128333 1250.36328"/>
+        <polygon points="501.761719 0 517.761719 0 296.128333 1250.36328 280.128333 1250.36328"/>
+        <polygon points="541.761719 0 559.761719 0 338.128333 1250.36328 320.128333 1250.36328"/>
+        <polygon points="581.761719 0 601.761719 0 380.128333 1250.36328 360.128333 1250.36328"/>
+        <polygon points="621.761719 0 643.761719 0 422.128333 1250.36328 400.128333 1250.36328"/>
+        <polygon points="661.761719 0 685.761719 0 464.128333 1250.36328 440.128333 1250.36328"/>
+        <polygon points="701.761719 0 727.761719 0 506.128333 1250.36328 480.128333 1250.36328"/>
+        <polygon points="741.761719 0 769.761719 0 548.128333 1250.36328 520.128333 1250.36328"/>
+        <polygon points="781.761719 0 811.761719 0 590.128333 1250.36328 560.128333 1250.36328"/>
+        <polygon points="821.761719 0 853.761719 0 632.128333 1250.36328 600.128333 1250.36328"/>
+        <polygon points="861.761719 0 895.761719 0 674.128333 1250.36328 640.128333 1250.36328"/>
+        <polygon points="901.761719 0 937.761719 0 716.128333 1250.36328 680.128333 1250.36328"/>
+        <polygon points="941.761719 0 979.76172 0 758.128333 1250.36328 720.128333 1250.36328"/>
+        <polygon points="981.76172 0 1021.76172 0 800.128333 1250.36328 760.128333 1250.36328"/>
+    </g>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/resources/runner/logo.svg b/third_party/blink/perf_tests/MotionMark/resources/runner/logo.svg
new file mode 100644
index 0000000..a7d0eaf
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/runner/logo.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <symbol id="root" viewBox="0 0 6882 1698">
+        <path d="M 1314 1681 L 1466 1681 L 1549 1282 C 1555 1254 1566 1229 1582 1205 C 1598 1181 1614 1162 1629 1147 C 1644 1132 1662 1119 1683 1108 C 1704 1097 1729 1092 1758 1092 C 1790 1092 1812 1100 1824 1117 C 1836 1134 1842 1154 1842 1177 C 1842 1197 1840 1219 1835 1241 C 1830 1263 1826 1283 1822 1301 L 1743 1680 L 1895 1680 L 1979 1277 C 1983 1257 1989 1237 2000 1215 C 2010 1193 2024 1173 2040 1155 C 2056 1137 2076 1122 2099 1110 C 2122 1098 2148 1092 2177 1092 C 2197 1092 2213 1095 2225 1101 C 2237 1107 2247 1114 2254 1124 C 2261 1133 2266 1144 2268 1156 C 2270 1168 2271 1180 2271 1191 C 2270 1208 2268 1224 2265 1238 C 2262 1253 2259 1264 2258 1272 L 2173 1680 L 2325 1680 L 2413 1240 C 2416 1228 2418 1213 2420 1197 C 2422 1181 2423 1167 2423 1154 C 2423 1098 2407 1054 2375 1021 C 2343 988 2294 972 2227 972 C 2179 972 2136 984 2098 1007 C 2060 1030 2025 1059 1994 1095 C 1984 1050 1963 1018 1931 1000 C 1899 982 1862 973 1819 973 C 1771 973 1727 983 1686 1004 C 1646 1025 1611 1054 1583 1091 L 1580 1088 L 1600 991 L 1456 991 L 1313 1680 L 1314 1681 Z" fill-opacity="0.6" fill="black"/>
+        <path d="M 2673 1426 C 2690 1410 2711 1399 2736 1391 C 2760 1383 2787 1379 2815 1377 C 2843 1375 2868 1373 2889 1372 C 2906 1370 2923 1367 2941 1363 C 2959 1359 2973 1351 2984 1340 L 2987 1343 C 2982 1376 2974 1407 2965 1436 C 2956 1465 2943 1490 2926 1511 C 2910 1532 2889 1549 2863 1562 C 2838 1574 2806 1581 2769 1581 C 2755 1581 2741 1579 2726 1576 C 2712 1573 2699 1568 2687 1561 C 2675 1554 2666 1545 2658 1534 C 2650 1523 2647 1509 2647 1492 C 2647 1464 2656 1442 2673 1426 L 2673 1426 Z M 3155 1237 L 3155 1237 C 3164 1198 3168 1163 3168 1133 C 3168 1121 3166 1105 3163 1087 C 3159 1069 3149 1051 3133 1034 C 3117 1017 3091 1003 3056 991 C 3021 979 2972 973 2910 973 C 2869 973 2831 977 2795 984 C 2759 992 2727 1004 2698 1023 C 2670 1041 2646 1065 2626 1094 C 2606 1123 2593 1159 2585 1201 L 2729 1201 C 2740 1158 2760 1130 2791 1115 C 2822 1100 2858 1093 2901 1093 C 2932 1093 2959 1099 2982 1110 C 3005 1121 3017 1143 3017 1176 C 3017 1202 3011 1223 2998 1239 C 2985 1255 2965 1265 2937 1266 C 2887 1270 2837 1274 2785 1278 C 2747 1281 2710 1286 2676 1295 C 2641 1304 2611 1318 2584 1336 C 2557 1355 2536 1378 2520 1407 C 2504 1436 2496 1472 2496 1514 C 2496 1544 2502 1571 2513 1594 C 2525 1617 2540 1636 2560 1651 C 2580 1666 2603 1678 2629 1686 C 2655 1694 2682 1698 2710 1698 C 2753 1698 2794 1691 2835 1677 C 2876 1663 2911 1641 2942 1610 C 2944 1637 2953 1658 2970 1674 C 2987 1690 3008 1698 3034 1698 C 3054 1698 3074 1696 3094 1692 C 3114 1688 3133 1684 3153 1679 L 3177 1570 C 3168 1571 3159 1572 3150 1575 C 3141 1577 3132 1578 3123 1578 C 3111 1578 3102 1575 3098 1570 C 3094 1565 3091 1557 3091 1547 C 3091 1537 3093 1527 3096 1515 L 3105 1479 L 3156 1235 L 3155 1237 Z" fill-opacity="0.6" fill="black"/>
+        <path d="M 3232 1681 L 3384 1681 L 3448 1376 C 3455 1341 3465 1308 3477 1277 C 3489 1246 3506 1218 3526 1194 C 3546 1170 3570 1151 3599 1137 C 3628 1123 3662 1116 3701 1116 C 3710 1116 3719 1116 3728 1117 C 3737 1118 3746 1119 3755 1121 L 3787 976 C 3775 974 3762 973 3750 973 C 3738 973 3726 972 3713 972 C 3689 972 3666 977 3644 986 C 3622 995 3602 1007 3583 1022 C 3564 1037 3547 1053 3532 1072 C 3516 1091 3503 1109 3493 1128 L 3490 1125 L 3518 990 L 3374 990 L 3231 1679 L 3232 1681 Z" fill-opacity="0.6" fill="black"/>
+
+        <polygon fill-opacity="0.6" fill="black" points="3726 1681 3878 1681 3927 1446 4044 1346 4166 1681 4334 1681 4166 1245 4470 992 4278 992 3966 1270 3963 1268 4075 729 3923 729"/>
+        <polygon fill-opacity="0.1" fill="black" points="4915 1368 4961 1118 1429 1118 1457 986 6867 986"/>
+
+        <polygon fill="black" points="4930 1298 4976 1048 1444 1048 1472 916 6882 916"/>
+
+        <polygon fill="currentColor" points="1403 263 1257 263 965 1679 1118 1679"/>
+        <polygon fill-opacity="0.8" fill="currentColor" points="1007 263 930 263 639 1679 722 1679"/>
+        <polygon fill-opacity="0.6" fill="currentColor" points="653 263 618 263 326 1679 368 1679"/>
+        <polygon fill-opacity="0.4" fill="currentColor" points="305 263 291 263 0 1679 21 1679"/>
+
+        <path d="M 1466 952 L 1618 952 L 1701 553 C 1707 525 1718 500 1734 476 C 1750 452 1766 433 1781 418 C 1796 403 1814 390 1835 379 C 1856 368 1881 363 1910 363 C 1942 363 1964 371 1976 388 C 1988 405 1994 425 1994 448 C 1994 468 1992 490 1987 512 C 1982 534 1978 554 1974 572 L 1895 951 L 2047 951 L 2131 548 C 2135 528 2141 508 2152 486 C 2162 464 2176 444 2192 426 C 2208 408 2228 393 2251 381 C 2274 369 2300 363 2329 363 C 2349 363 2365 366 2377 372 C 2389 378 2399 385 2406 395 C 2413 404 2418 415 2420 427 C 2422 439 2423 451 2423 462 C 2422 479 2420 495 2417 509 C 2414 524 2411 535 2410 543 L 2325 951 L 2477 951 L 2565 511 C 2568 499 2570 484 2572 468 C 2574 452 2575 438 2575 425 C 2575 369 2559 325 2527 292 C 2495 259 2446 243 2379 243 C 2331 243 2288 255 2250 278 C 2212 301 2177 330 2146 366 C 2136 321 2115 289 2083 271 C 2051 253 2014 244 1971 244 C 1923 244 1879 254 1838 275 C 1798 296 1763 325 1735 362 L 1732 359 L 1752 262 L 1608 262 L 1465 951 L 1466 952 Z" fill="black"/>
+        <path d="M 3180 415 C 3205 449 3218 491 3218 542 C 3218 577 3213 612 3204 649 C 3195 686 3180 719 3161 749 C 3141 779 3117 803 3088 822 C 3059 841 3025 851 2986 851 C 2931 851 2891 834 2865 800 C 2840 766 2827 724 2827 673 C 2827 638 2832 603 2841 566 C 2850 530 2865 496 2884 467 C 2904 437 2928 413 2957 393 C 2986 373 3020 364 3059 364 C 3114 364 3154 381 3180 415 L 3180 415 Z M 3141 938 L 3141 938 C 3189 916 3231 885 3265 847 C 3299 808 3325 763 3343 710 C 3361 658 3370 601 3370 541 C 3370 444 3344 371 3291 320 C 3239 270 3164 245 3068 245 C 3008 245 2954 257 2906 280 C 2858 303 2816 334 2782 373 C 2748 412 2721 457 2703 508 C 2684 559 2675 613 2675 670 C 2675 767 2701 841 2754 893 C 2806 945 2881 971 2977 971 C 3038 971 3093 960 3142 938 L 3141 938 Z" fill="black"/>
+        <path d="M 3620 263 L 3500 263 L 3476 376 L 3596 376 L 3517 753 C 3515 759 3513 770 3511 786 C 3509 802 3508 817 3508 830 C 3508 846 3510 862 3514 877 C 3518 893 3525 906 3535 918 C 3545 930 3559 940 3577 947 C 3595 954 3617 958 3645 958 C 3665 958 3685 957 3708 954 C 3730 951 3751 948 3771 943 L 3796 831 C 3781 835 3766 837 3753 837 C 3739 837 3727 838 3715 838 C 3692 838 3677 833 3670 824 C 3663 815 3660 802 3660 787 C 3660 779 3661 768 3664 755 C 3667 742 3670 727 3673 712 L 3744 375 L 3881 375 L 3905 262 L 3768 262 L 3811 55 L 3663 55 L 3620 262 L 3620 263 Z" fill="black"/>
+        <path d="M 4046 144 L 4197 144 L 4226 0 L 4075 0 L 4046 144 L 4046 144 Z M 3878 952 L 3878 952 L 4030 952 L 4173 263 L 4021 263 L 3878 952 L 3878 952 Z" fill="black"/>
+        <path d="M 4736 415 C 4761 449 4774 491 4774 542 C 4774 577 4769 612 4760 649 C 4751 686 4736 719 4717 749 C 4697 779 4673 803 4644 822 C 4615 841 4581 851 4542 851 C 4487 851 4447 834 4421 800 C 4396 766 4383 724 4383 673 C 4383 638 4388 603 4397 566 C 4406 530 4421 496 4440 467 C 4460 437 4484 413 4513 393 C 4542 373 4576 364 4615 364 C 4670 364 4710 381 4736 415 L 4736 415 Z M 4697 938 L 4697 938 C 4745 916 4787 885 4821 847 C 4855 808 4881 763 4899 710 C 4917 658 4926 601 4926 541 C 4926 444 4900 371 4847 320 C 4795 270 4720 245 4624 245 C 4564 245 4510 257 4462 280 C 4414 303 4372 334 4338 373 C 4304 412 4277 457 4259 508 C 4240 559 4231 613 4231 670 C 4231 767 4257 841 4310 893 C 4362 945 4437 971 4533 971 C 4594 971 4649 960 4698 938 L 4697 938 Z" fill="black"/>
+        <path d="M 4990 952 L 5142 952 L 5219 579 C 5225 551 5235 523 5248 497 C 5261 471 5276 449 5294 431 C 5313 412 5334 397 5357 384 C 5381 371 5407 365 5438 365 C 5466 365 5487 369 5501 377 C 5516 385 5526 395 5532 406 C 5538 417 5542 428 5542 439 C 5542 450 5543 458 5543 464 C 5543 474 5542 484 5540 495 C 5538 506 5535 517 5533 528 L 5445 953 L 5597 953 L 5689 513 C 5692 501 5693 486 5694 470 C 5695 454 5695 440 5695 427 C 5695 371 5679 327 5646 294 C 5614 261 5563 245 5493 245 C 5445 245 5400 256 5359 277 C 5318 298 5283 328 5256 366 L 5253 363 L 5274 263 L 5131 263 L 4988 952 L 4990 952 Z" fill="black"/>
+    </symbol>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/resources/runner/motionmark.css b/third_party/blink/perf_tests/MotionMark/resources/runner/motionmark.css
new file mode 100644
index 0000000..84a5d418
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/runner/motionmark.css
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2018-2020 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.
+ */
+/* Outer harness */
+html,
+body {
+    min-height: 100%;
+}
+
+body {
+    background-color: hsl(0, 0%, 95%);
+
+    font-family: "Helvetica Neue", Helvetica, Verdana, sans-serif;
+    font-size: 15px;
+
+    cursor: default;
+
+    -webkit-user-select: none;
+}
+
+body.showing-intro,
+body.showing-results {
+    background-color: hsl(35, 100%, 100%);
+    background-image: url(crystal.svg), url(lines.svg);
+    background-size: auto 225%, auto 100%;
+    background-repeat: no-repeat;
+
+    animation: background-fade 1s ease-in 1s, background-color 60s linear infinite 2s;
+    animation-play-state: paused;
+
+    will-change: background-color;
+}
+
+body.showing-test-container {
+    overflow: hidden;
+}
+
+body.images-loaded {
+    animation-play-state: running;
+}
+
+@media screen and (min-width: 667px) {
+    body {
+        font-size: 24px;
+    }
+
+    body.showing-intro,
+    body.showing-results {
+        background-size: 200% 100%, 150% auto;
+    }
+}
+
+@media screen and (min-width: 1025px) {
+    body.showing-intro,
+    body.showing-results {
+        background-size: 150% 100%, 150% auto;
+    }
+}
+
+::selection {
+    background-color: black;
+    color: white;
+}
+
+.hidden {
+    display: none;
+}
+
+section {
+    display: none;
+}
+
+section.selected {
+    display: block;
+}
+
+.logo {
+    position: relative;
+}
+
+.logo svg {
+    width: 350px;
+    height: 88px;
+
+    max-width: 100%;
+
+    color: hsl(35, 100%, 50%);
+
+    animation: foreground-color 60s linear infinite 2s;
+    animation-play-state: paused;
+
+    will-change: color;
+}
+
+.logo div {
+    transform: skewX(-10deg);
+    margin-left: 1em;
+}
+
+body.images-loaded .logo svg {
+    animation-play-state: running;
+}
+
+@media screen and (min-width: 667px) {
+    .logo svg {
+        width: 525px;
+        height: 130px;
+        padding-left: .4em;
+    }
+
+    .logo div {
+        position: absolute;
+        left: 360px;
+        bottom: 0.2em;
+        font-size: 75%;
+    }
+}
+
+section .body {
+    margin: 2em 1em 0;
+    max-width: 350px;
+}
+
+section .body p {
+    margin: 1em 0;
+    line-height: 1.5em;
+    max-width: 60vw;
+
+    -webkit-user-select: text;
+    cursor: text;
+}
+
+@media screen and (min-width: 667px) {
+    section .body {
+        margin-left: 2.5em;
+        max-width: 500px;
+        transform: skewX(-10deg);
+    }
+
+    section button {
+        transform: none;
+    }
+}
+
+button {
+    background-color: hsl(35, 100%, 50%);
+    color: white;
+
+    padding: 0.25em;
+    margin: 1.5em -0.25em 0 0;
+
+    min-width: 50%;
+
+    border: none;
+
+    font-family: inherit;
+    font-size: inherit;
+
+    transform: skewX(-10deg);
+
+    transition: 100ms filter ease-in-out;
+
+    animation: background-color 60s linear infinite 2s;
+    animation-play-state: paused;
+
+    will-change: background-color;
+}
+
+body.images-loaded button {
+    animation-play-state: running;
+}
+
+button:hover {
+    filter: brightness(115%);
+}
+
+button:active {
+    filter: brightness(130%);
+}
+
+button:disabled {
+    opacity: 0.5;
+    filter: none !important;
+}
+
+@media print {
+    button {
+        display: none;
+    }
+}
+
+.portrait-orientation-check {
+    display: none;
+}
+
+@media screen and (max-device-width: 1025px) and (orientation: portrait) {
+    .portrait-orientation-check {
+        display: block;
+    }
+}
+
+@media screen and (max-device-width: 1025px) and (orientation: portrait) {
+    .landscape-orientation-check {
+        /* This keeps the button color animation in sync with page, while display: none does not. */
+        visibility: hidden;
+    }
+}
+
+@keyframes background-fade {
+    100% {
+        background-color: hsl(35, 100%, 50%);
+    }
+}
+
+@keyframes background-color {
+    0%, 10% {
+        background-color: hsl(35, 100%, 50%);
+    }
+
+    12%, 20% {
+        background-color: hsl(75, 100%, 30%);
+    }
+
+    22%, 30% {
+        background-color: hsl(115, 100%, 30%);
+    }
+
+    32%, 40% {
+        background-color: hsl(155, 100%, 30%);
+    }
+
+    42%, 50% {
+        background-color: hsl(195, 100%, 30%);
+    }
+
+    52%, 60% {
+        background-color: hsl(235, 100%, 30%);
+    }
+
+    62%, 70% {
+        background-color: hsl(275, 100%, 30%);
+    }
+
+    72%, 80% {
+        background-color: hsl(315, 100%, 30%);
+    }
+
+    82%, 90% {
+        background-color: hsl(355, 100%, 30%);
+    }
+
+    92%, 100% {
+        background-color: hsl(395, 100%, 50%);
+    }
+}
+
+@keyframes foreground-color {
+    0%, 10% {
+        color: hsl(35, 100%, 50%);
+    }
+
+    12%, 20% {
+        color: hsl(75, 100%, 30%);
+    }
+
+    22%, 30% {
+        color: hsl(115, 100%, 30%);
+    }
+
+    32%, 40% {
+        color: hsl(155, 100%, 30%);
+    }
+
+    42%, 50% {
+        color: hsl(195, 100%, 30%);
+    }
+
+    52%, 60% {
+        color: hsl(235, 100%, 30%);
+    }
+
+    62%, 70% {
+        color: hsl(275, 100%, 30%);
+    }
+
+    72%, 80% {
+        color: hsl(315, 100%, 30%);
+    }
+
+    82%, 90% {
+        color: hsl(355, 100%, 30%);
+    }
+
+    92%, 100% {
+        color: hsl(395, 100%, 50%);
+    }
+}
+
+/* Intro section, About page */
+
+#intro, #about {
+    padding: 2em;
+}
+
+#intro {
+    opacity: 0;
+    transition: opacity 500ms ease-in;
+}
+
+body.images-loaded #intro {
+    opacity: 1;
+}
+
+#about .body {
+    transform: none;
+    margin: 0;
+    max-width: initial;
+}
+
+#about li {
+    line-height: 1.5em;
+}
+
+#about button {
+    padding: .75em 2em;
+    margin: 1.5em auto 0;
+    min-width: initial;
+    transform: skewX(-10deg);
+}
+#about h3 {
+    margin-top: 3em;
+}
+#about #log {
+    font-size: .9em;
+    list-style-type: none;
+    margin-left: 0;
+    padding-left: 0;
+}
+#about #log li {
+    margin-top: .5em;
+}
+
+@media screen and (min-width: 667px) {
+    #about .body {
+        font-size: .7em;
+        margin: 1em;
+    }
+
+    #about ol, #about ul {
+        padding-left: 3em;
+    }
+}
+
+
+#intro a, #about a,
+#intro a:visited, #about a:visited {
+    color: black;
+}
+
+/* Running test section */
+
+.frame-container {
+    position: absolute;
+
+    top: 50%;
+    left: 50%;
+}
+
+.frame-container > iframe {
+    width: 100%;
+    height: 100%;
+
+    border: 0;
+    margin: 0;
+}
+
+body.small .frame-container {
+    width: 568px;
+    height: 320px;
+    margin-left: -284px;
+    margin-top: -160px;
+}
+
+body.medium .frame-container {
+    width: 900px;
+    height: 600px;
+    margin-left: -450px;
+    margin-top: -300px;
+}
+
+body.large .frame-container {
+    width: 1600px;
+    height: 800px;
+    margin-left: -800px;
+    margin-top: -400px;
+}
+
+/* Results section */
+
+#results {
+    padding: 2em;
+}
+
+#results .body {
+    -webkit-user-select: text;
+}
+
+#results .score-container {
+    padding-bottom: 2em;
+}
+
+#results .table-container {
+    position: relative;
+}
+
+#results .table-container > div {
+    margin-left: 40%;
+}
+
+#results .score {
+    font-size: 5em;
+    font-weight: bold;
+    font-style: italic;
+    line-height: 1;
+    margin: 0;
+}
+
+#results .confidence {
+    font-size: 2em;
+    font-style: italic;
+    line-height: 1;
+    margin: 0;
+    text-indent: 1.75em;
+    color: hsl(0, 0%, 40%);
+    padding-bottom: .3em;
+}
+
+#results table {
+    border-spacing: 0;
+    margin: 0;
+    padding: 0;
+    min-width: 25%;
+}
+
+#results table td,
+#results table th {
+    padding: 0.25em;
+}
+
+#results table td.suites-separator {
+    padding: 0;
+}
+
+#results table tr:nth-child(even) {
+    background-color: hsla(0, 0%, 0%, 0.05);
+}
+
+#results #results-header {
+    top: 0;
+    left: 0;
+    width: 40%;
+    position: absolute;
+}
+
+#results #results-score {
+    float: left;
+}
+
+#results #results-data span {
+    font-size: .75em;
+    color: hsl(0, 0%, 40%);
+}
+
+#results #results-header td,
+#results #results-header th {
+    text-align: right;
+    padding-right: 1em !important;
+    padding-left: 0.5em !important;
+}
+
+#results #results-score td,
+#results #results-score th {
+    text-align: left;
+    padding-right: 0.5em !important;
+}
+
+#results #results-score td {
+    cursor: text;
+}
+
+@media screen and (min-width: 667px) {
+    #results .score,
+    #results .confidence {
+        font-style: normal;
+    }
+}
+
+.detail span {
+    display: none;
+}
+
+body.small .detail .small,
+body.medium .detail .medium,
+body.large .detail .large {
+    display: initial;
+}
+
+#overlay {
+    position: fixed;
+
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+
+    background: hsla(0, 0%, 100%, 0.9);
+}
+
+@supports (-webkit-backdrop-filter: blur(10px)) {
+    #overlay {
+        background: hsla(0, 0%, 100%, 0.7);
+        -webkit-backdrop-filter: blur(20px);
+    }
+}
+
+#overlay > div {
+    position: absolute;
+
+    width: 500px;
+    height: 500px;
+
+    margin-top: -250px;
+    margin-left: -250px;
+
+    top: 50%;
+    left: 50%;
+}
+
+#overlay > div div {
+    overflow: scroll;
+
+    font-size: 12px;
+    -webkit-user-select: text;
+    cursor: text;
+
+    max-height: 250px;
+
+    border: 1px solid hsla(0, 0%, 0%, 0.1);
+    padding: 1em;
+}
diff --git a/third_party/blink/perf_tests/MotionMark/resources/runner/motionmark.js b/third_party/blink/perf_tests/MotionMark/resources/runner/motionmark.js
new file mode 100644
index 0000000..a89ccd4
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/runner/motionmark.js
@@ -0,0 +1,668 @@
+/*
+ * Copyright (C) 2018-2020 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.
+ */
+ ResultsDashboard = Utilities.createClass(
+    function(version, options, testData)
+    {
+        this._iterationsSamplers = [];
+        this._options = options;
+        this._results = null;
+        this._version = version;
+        this._targetFrameRate = options["frame-rate"] || 60;
+        this._systemFrameRate = options["system-frame-rate"] || 60;
+        if (testData) {
+            this._iterationsSamplers = testData;
+            this._processData();
+        }
+    }, {
+
+    push: function(suitesSamplers)
+    {
+        this._iterationsSamplers.push(suitesSamplers);
+    },
+
+    _processData: function()
+    {
+        this._results = {};
+        this._results[Strings.json.results.iterations] = [];
+
+        var iterationsScores = [];
+        this._iterationsSamplers.forEach(function(iteration, index) {
+            var testsScores = [];
+            var testsLowerBoundScores = [];
+            var testsUpperBoundScores = [];
+
+            var result = {};
+            this._results[Strings.json.results.iterations][index] = result;
+
+            var suitesResult = {};
+            result[Strings.json.results.tests] = suitesResult;
+
+            for (var suiteName in iteration) {
+                var suiteData = iteration[suiteName];
+
+                var suiteResult = {};
+                suitesResult[suiteName] = suiteResult;
+
+                for (var testName in suiteData) {
+                    if (!suiteData[testName][Strings.json.result])
+                        this.calculateScore(suiteData[testName]);
+
+                    suiteResult[testName] = suiteData[testName][Strings.json.result];
+                    delete suiteData[testName][Strings.json.result];
+
+                    testsScores.push(suiteResult[testName][Strings.json.score]);
+                    testsLowerBoundScores.push(suiteResult[testName][Strings.json.scoreLowerBound]);
+                    testsUpperBoundScores.push(suiteResult[testName][Strings.json.scoreUpperBound]);
+                }
+            }
+
+            result[Strings.json.score] = Statistics.geometricMean(testsScores);
+            result[Strings.json.scoreLowerBound] = Statistics.geometricMean(testsLowerBoundScores);
+            result[Strings.json.scoreUpperBound] = Statistics.geometricMean(testsUpperBoundScores);
+            iterationsScores.push(result[Strings.json.score]);
+        }, this);
+
+        this._results[Strings.json.version] = this._version;
+        this._results[Strings.json.fps] = this._targetFrameRate;
+        this._results[Strings.json.score] = Statistics.sampleMean(iterationsScores.length, iterationsScores.reduce(function(a, b) { return a + b; }));
+        this._results[Strings.json.scoreLowerBound] = this._results[Strings.json.results.iterations][0][Strings.json.scoreLowerBound];
+        this._results[Strings.json.scoreUpperBound] = this._results[Strings.json.results.iterations][0][Strings.json.scoreUpperBound];
+    },
+
+    calculateScore: function(data)
+    {
+        var result = {};
+        data[Strings.json.result] = result;
+        var samples = data[Strings.json.samples];
+
+        function findRegression(series, profile) {
+            var minIndex = Math.round(.025 * series.length);
+            var maxIndex = Math.round(.975 * (series.length - 1));
+            var minComplexity = series.getFieldInDatum(minIndex, Strings.json.complexity);
+            var maxComplexity = series.getFieldInDatum(maxIndex, Strings.json.complexity);
+
+            if (Math.abs(maxComplexity - minComplexity) < 20 && maxIndex - minIndex < 20) {
+                minIndex = 0;
+                maxIndex = series.length - 1;
+                minComplexity = series.getFieldInDatum(minIndex, Strings.json.complexity);
+                maxComplexity = series.getFieldInDatum(maxIndex, Strings.json.complexity);
+            }
+
+            var complexityIndex = series.fieldMap[Strings.json.complexity];
+            var frameLengthIndex = series.fieldMap[Strings.json.frameLength];
+            var regressionOptions = { desiredFrameLength: 1000/this._targetFrameRate };
+            if (profile)
+                regressionOptions.preferredProfile = profile;
+            return {
+                minComplexity: minComplexity,
+                maxComplexity: maxComplexity,
+                samples: series.slice(minIndex, maxIndex + 1),
+                regression: new Regression(
+                    series.data,
+                    function (data, i) { return data[i][complexityIndex]; },
+                    function (data, i) { return data[i][frameLengthIndex]; },
+                    minIndex, maxIndex, regressionOptions)
+            };
+        }
+
+        // Convert these samples into SampleData objects if needed
+        [Strings.json.complexity, Strings.json.controller].forEach(function(seriesName) {
+            var series = samples[seriesName];
+            if (series && !(series instanceof SampleData))
+                samples[seriesName] = new SampleData(series.fieldMap, series.data);
+        });
+
+        var isRampController = this._options["controller"] == "ramp";
+        var predominantProfile = "";
+        if (isRampController) {
+            var profiles = {};
+            data[Strings.json.controller].forEach(function(regression) {
+                if (regression[Strings.json.regressions.profile]) {
+                    var profile = regression[Strings.json.regressions.profile];
+                    profiles[profile] = (profiles[profile] || 0) + 1;
+                }
+            });
+
+            var maxProfileCount = 0;
+            for (var profile in profiles) {
+                if (profiles[profile] > maxProfileCount) {
+                    predominantProfile = profile;
+                    maxProfileCount = profiles[profile];
+                }
+            }
+        }
+
+        var regressionResult = findRegression(samples[Strings.json.complexity], predominantProfile);
+        var calculation = regressionResult.regression;
+        result[Strings.json.complexity] = {};
+        result[Strings.json.complexity][Strings.json.regressions.segment1] = [
+            [regressionResult.minComplexity, calculation.s1 + calculation.t1 * regressionResult.minComplexity],
+            [calculation.complexity, calculation.s1 + calculation.t1 * calculation.complexity]
+        ];
+        result[Strings.json.complexity][Strings.json.regressions.segment2] = [
+            [calculation.complexity, calculation.s2 + calculation.t2 * calculation.complexity],
+            [regressionResult.maxComplexity, calculation.s2 + calculation.t2 * regressionResult.maxComplexity]
+        ];
+        result[Strings.json.complexity][Strings.json.complexity] = calculation.complexity;
+        result[Strings.json.complexity][Strings.json.measurements.stdev] = Math.sqrt(calculation.error / samples[Strings.json.complexity].length);
+
+        result[Strings.json.fps] = data.targetFPS || 60;
+
+        if (isRampController) {
+            var timeComplexity = new Experiment;
+            data[Strings.json.controller].forEach(function(regression) {
+                timeComplexity.sample(regression[Strings.json.complexity]);
+            });
+
+            var experimentResult = {};
+            result[Strings.json.controller] = experimentResult;
+            experimentResult[Strings.json.score] = timeComplexity.mean();
+            experimentResult[Strings.json.measurements.average] = timeComplexity.mean();
+            experimentResult[Strings.json.measurements.stdev] = timeComplexity.standardDeviation();
+            experimentResult[Strings.json.measurements.percent] = timeComplexity.percentage();
+
+            const bootstrapIterations = 2500;
+            var bootstrapResult = Regression.bootstrap(regressionResult.samples.data, bootstrapIterations, function(resampleData) {
+                var complexityIndex = regressionResult.samples.fieldMap[Strings.json.complexity];
+                resampleData.sort(function(a, b) {
+                    return a[complexityIndex] - b[complexityIndex];
+                });
+
+                var resample = new SampleData(regressionResult.samples.fieldMap, resampleData);
+                var bootstrapRegressionResult = findRegression(resample, predominantProfile);
+                return bootstrapRegressionResult.regression.complexity;
+            }, .8);
+
+            result[Strings.json.complexity][Strings.json.bootstrap] = bootstrapResult;
+            result[Strings.json.score] = bootstrapResult.median;
+            result[Strings.json.scoreLowerBound] = bootstrapResult.confidenceLow;
+            result[Strings.json.scoreUpperBound] = bootstrapResult.confidenceHigh;
+        } else {
+            var marks = data[Strings.json.marks];
+            var samplingStartIndex = 0, samplingEndIndex = -1;
+            if (Strings.json.samplingStartTimeOffset in marks)
+                samplingStartIndex = marks[Strings.json.samplingStartTimeOffset].index;
+            if (Strings.json.samplingEndTimeOffset in marks)
+                samplingEndIndex = marks[Strings.json.samplingEndTimeOffset].index;
+
+            var averageComplexity = new Experiment;
+            var averageFrameLength = new Experiment;
+            var controllerSamples = samples[Strings.json.controller];
+            controllerSamples.forEach(function (sample, i) {
+                if (i >= samplingStartIndex && (samplingEndIndex == -1 || i < samplingEndIndex)) {
+                    averageComplexity.sample(controllerSamples.getFieldInDatum(sample, Strings.json.complexity));
+                    var smoothedFrameLength = controllerSamples.getFieldInDatum(sample, Strings.json.smoothedFrameLength);
+                    if (smoothedFrameLength && smoothedFrameLength != -1)
+                        averageFrameLength.sample(smoothedFrameLength);
+                }
+            });
+
+            var experimentResult = {};
+            result[Strings.json.controller] = experimentResult;
+            experimentResult[Strings.json.measurements.average] = averageComplexity.mean();
+            experimentResult[Strings.json.measurements.concern] = averageComplexity.concern(Experiment.defaults.CONCERN);
+            experimentResult[Strings.json.measurements.stdev] = averageComplexity.standardDeviation();
+            experimentResult[Strings.json.measurements.percent] = averageComplexity.percentage();
+
+            experimentResult = {};
+            result[Strings.json.frameLength] = experimentResult;
+            experimentResult[Strings.json.measurements.average] = 1000 / averageFrameLength.mean();
+            experimentResult[Strings.json.measurements.concern] = averageFrameLength.concern(Experiment.defaults.CONCERN);
+            experimentResult[Strings.json.measurements.stdev] = averageFrameLength.standardDeviation();
+            experimentResult[Strings.json.measurements.percent] = averageFrameLength.percentage();
+
+            result[Strings.json.score] = averageComplexity.score(Experiment.defaults.CONCERN);
+            result[Strings.json.scoreLowerBound] = result[Strings.json.score] - averageFrameLength.standardDeviation();
+            result[Strings.json.scoreUpperBound] = result[Strings.json.score] + averageFrameLength.standardDeviation();
+        }
+    },
+
+    get data()
+    {
+        return this._iterationsSamplers;
+    },
+
+    get results()
+    {
+        if (this._results)
+            return this._results[Strings.json.results.iterations];
+        this._processData();
+        return this._results[Strings.json.results.iterations];
+    },
+
+    get options()
+    {
+        return this._options;
+    },
+
+    get version()
+    {
+        return this._version;
+    },
+
+    _getResultsProperty: function(property)
+    {
+        if (this._results)
+            return this._results[property];
+        this._processData();
+        return this._results[property];
+    },
+
+    get score()
+    {
+        return this._getResultsProperty(Strings.json.score);
+    },
+
+    get scoreLowerBound()
+    {
+        return this._getResultsProperty(Strings.json.scoreLowerBound);
+    },
+
+    get scoreUpperBound()
+    {
+        return this._getResultsProperty(Strings.json.scoreUpperBound);
+    }
+});
+
+ResultsTable = Utilities.createClass(
+    function(element, headers)
+    {
+        this.element = element;
+        this._headers = headers;
+
+        this._flattenedHeaders = [];
+        this._headers.forEach(function(header) {
+            if (header.disabled)
+                return;
+
+            if (header.children)
+                this._flattenedHeaders = this._flattenedHeaders.concat(header.children);
+            else
+                this._flattenedHeaders.push(header);
+        }, this);
+
+        this._flattenedHeaders = this._flattenedHeaders.filter(function (header) {
+            return !header.disabled;
+        });
+
+        this.clear();
+    }, {
+
+    clear: function()
+    {
+        this.element.textContent = "";
+    },
+
+    _addHeader: function()
+    {
+        var thead = Utilities.createElement("thead", {}, this.element);
+        var row = Utilities.createElement("tr", {}, thead);
+
+        this._headers.forEach(function (header) {
+            if (header.disabled)
+                return;
+
+            var th = Utilities.createElement("th", {}, row);
+            if (header.title != Strings.text.graph)
+                th.innerHTML = header.title;
+            if (header.children)
+                th.colSpan = header.children.length;
+        });
+    },
+
+    _addBody: function()
+    {
+        this.tbody = Utilities.createElement("tbody", {}, this.element);
+    },
+
+    _addEmptyRow: function()
+    {
+        var row = Utilities.createElement("tr", {}, this.tbody);
+        this._flattenedHeaders.forEach(function (header) {
+            return Utilities.createElement("td", { class: "suites-separator" }, row);
+        });
+    },
+
+    _addTest: function(testName, testResult, options)
+    {
+        var row = Utilities.createElement("tr", {}, this.tbody);
+
+        this._flattenedHeaders.forEach(function (header) {
+            var td = Utilities.createElement("td", {}, row);
+            if (header.text == Strings.text.testName) {
+                td.textContent = testName;
+            } else if (typeof header.text == "string") {
+                var data = testResult[header.text];
+                if (typeof data == "number")
+                    data = data.toFixed(2);
+                td.innerHTML = data;
+            } else
+                td.innerHTML = header.text(testResult);
+        }, this);
+    },
+
+    _addIteration: function(iterationResult, iterationData, options)
+    {
+        var testsResults = iterationResult[Strings.json.results.tests];
+        for (var suiteName in testsResults) {
+            this._addEmptyRow();
+            var suiteResult = testsResults[suiteName];
+            var suiteData = iterationData[suiteName];
+            for (var testName in suiteResult)
+                this._addTest(testName, suiteResult[testName], options, suiteData[testName]);
+        }
+    },
+
+    showIterations: function(dashboard)
+    {
+        this.clear();
+        this._addHeader();
+        this._addBody();
+
+        var iterationsResults = dashboard.results;
+        iterationsResults.forEach(function(iterationResult, index) {
+            this._addIteration(iterationResult, dashboard.data[index], dashboard.options);
+        }, this);
+    }
+});
+
+window.benchmarkRunnerClient = {
+    iterationCount: 1,
+    options: null,
+    results: null,
+
+    initialize: function(suites, options)
+    {
+        this.options = options;
+    },
+
+    willStartFirstIteration: function()
+    {
+        this.results = new ResultsDashboard(Strings.version, this.options);
+    },
+
+    didRunSuites: function(suitesSamplers)
+    {
+        this.results.push(suitesSamplers);
+    },
+
+    didRunTest: function(testData)
+    {
+        this.results.calculateScore(testData);
+    },
+
+    didFinishLastIteration: function()
+    {
+        benchmarkController.showResults();
+    }
+};
+
+window.sectionsManager =
+{
+    showSection: function(sectionIdentifier, pushState)
+    {
+        var sections = document.querySelectorAll("main > section");
+        for (var i = 0; i < sections.length; ++i) {
+            document.body.classList.remove("showing-" + sections[i].id);
+        }
+        document.body.classList.add("showing-" + sectionIdentifier);
+
+        var currentSectionElement = document.querySelector("section.selected");
+        console.assert(currentSectionElement);
+
+        var newSectionElement = document.getElementById(sectionIdentifier);
+        console.assert(newSectionElement);
+
+        currentSectionElement.classList.remove("selected");
+        newSectionElement.classList.add("selected");
+
+        if (pushState)
+            history.pushState({section: sectionIdentifier}, document.title);
+    },
+
+    setSectionVersion: function(sectionIdentifier, version)
+    {
+        document.querySelector("#" + sectionIdentifier + " .version").textContent = version;
+    },
+
+    setSectionScore: function(sectionIdentifier, score, confidence, fps)
+    {
+        if (fps && score)
+            document.querySelector("#" + sectionIdentifier + " .score").textContent = `${score} @ ${fps}fps`;
+        if (confidence)
+            document.querySelector("#" + sectionIdentifier + " .confidence").textContent = confidence;
+    },
+
+    populateTable: function(tableIdentifier, headers, dashboard)
+    {
+        var table = new ResultsTable(document.getElementById(tableIdentifier), headers);
+        table.showIterations(dashboard);
+    }
+};
+
+window.benchmarkController = {
+    benchmarkDefaultParameters: {
+        "test-interval": 30,
+        "display": "minimal",
+        "tiles": "big",
+        "controller": "ramp",
+        "kalman-process-error": 1,
+        "kalman-measurement-error": 4,
+        "time-measurement": "performance",
+        "warmup-length": 2000,
+        "warmup-frame-count": 30,
+        "first-frame-minimum-length": 0
+    },
+
+    initialize: function()
+    {
+        document.title = Strings.text.title.replace("%s", Strings.version);
+        document.querySelectorAll(".version").forEach(function(e) {
+            e.textContent = Strings.version;
+        });
+        benchmarkController.addOrientationListenerIfNecessary();
+    },
+
+    determineCanvasSize: function() {
+        var match = window.matchMedia("(max-device-width: 760px)");
+        if (match.matches) {
+            document.body.classList.add("small");
+            return;
+        }
+
+        match = window.matchMedia("(max-device-width: 1600px)");
+        if (match.matches) {
+            document.body.classList.add("medium");
+            return;
+        }
+
+        match = window.matchMedia("(max-width: 1600px)");
+        if (match.matches) {
+            document.body.classList.add("medium");
+            return;
+        }
+
+        document.body.classList.add("large");
+    },
+
+    addOrientationListenerIfNecessary: function() {
+        if (!("orientation" in window))
+            return;
+
+        this.orientationQuery = window.matchMedia("(orientation: landscape)");
+        this._orientationChanged(this.orientationQuery);
+        this.orientationQuery.addListener(this._orientationChanged);
+    },
+
+    _orientationChanged: function(match)
+    {
+        benchmarkController.isInLandscapeOrientation = match.matches;
+        if (match.matches)
+            document.querySelector(".start-benchmark p").classList.add("hidden");
+        else
+            document.querySelector(".start-benchmark p").classList.remove("hidden");
+        benchmarkController.updateStartButtonState();
+    },
+
+    updateStartButtonState: function()
+    {
+        document.getElementById("run-benchmark").disabled = !this.isInLandscapeOrientation;
+    },
+
+    _startBenchmark: function(suites, options, frameContainerID)
+    {
+        benchmarkController.determineCanvasSize();
+
+        var configuration = document.body.className.match(/small|medium|large/);
+        if (configuration)
+            options[Strings.json.configuration] = configuration[0];
+
+        benchmarkRunnerClient.initialize(suites, options);
+        var frameContainer = document.getElementById(frameContainerID);
+        var runner = new BenchmarkRunner(suites, frameContainer, benchmarkRunnerClient);
+        runner.runMultipleIterations();
+
+        sectionsManager.showSection("test-container");
+    },
+
+    startBenchmark: function()
+    {
+        var options = this.benchmarkDefaultParameters;
+        this._startBenchmark(Suites, options, "test-container");
+    },
+
+    showResults: function()
+    {
+        if (!this.addedKeyEvent) {
+            document.addEventListener("keypress", this.handleKeyPress, false);
+            this.addedKeyEvent = true;
+        }
+
+        var dashboard = benchmarkRunnerClient.results;
+        var score = dashboard.score;
+        var confidence = "±" + (Statistics.largestDeviationPercentage(dashboard.scoreLowerBound, score, dashboard.scoreUpperBound) * 100).toFixed(2) + "%";
+        var fps = dashboard._systemFrameRate;
+        sectionsManager.setSectionVersion("results", dashboard.version);
+        sectionsManager.setSectionScore("results", score.toFixed(2), confidence, fps);
+        sectionsManager.populateTable("results-header", Headers.testName, dashboard);
+        sectionsManager.populateTable("results-score", Headers.score, dashboard);
+        sectionsManager.populateTable("results-data", Headers.details, dashboard);
+        sectionsManager.showSection("results", true);
+    },
+
+    handleKeyPress: function(event)
+    {
+        switch (event.charCode)
+        {
+        case 27:  // esc
+            benchmarkController.hideDebugInfo();
+            break;
+        case 106: // j
+            benchmarkController.showDebugInfo();
+            break;
+        case 115: // s
+            benchmarkController.selectResults(event.target);
+            break;
+        }
+    },
+
+    hideDebugInfo: function()
+    {
+        var overlay = document.getElementById("overlay");
+        if (!overlay)
+            return;
+        document.body.removeChild(overlay);
+    },
+
+    showDebugInfo: function()
+    {
+        if (document.getElementById("overlay"))
+            return;
+
+        var overlay = Utilities.createElement("div", {
+            id: "overlay"
+        }, document.body);
+        var container = Utilities.createElement("div", {}, overlay);
+
+        var header = Utilities.createElement("h3", {}, container);
+        header.textContent = "Debug Output";
+
+        var data = Utilities.createElement("div", {}, container);
+        data.textContent = "Please wait...";
+        setTimeout(function() {
+            var output = {
+                version: benchmarkRunnerClient.results.version,
+                options: benchmarkRunnerClient.results.options,
+                data: benchmarkRunnerClient.results.data
+            };
+            data.textContent = JSON.stringify(output, function(key, value) {
+                if (typeof value === 'number')
+                    return Utilities.toFixedNumber(value, 3);
+                return value;
+            }, 1);
+        }, 0);
+        data.onclick = function() {
+            var selection = window.getSelection();
+            selection.removeAllRanges();
+            var range = document.createRange();
+            range.selectNode(data);
+            selection.addRange(range);
+        };
+
+        var button = Utilities.createElement("button", {}, container);
+        button.textContent = "Done";
+        button.onclick = function() {
+            benchmarkController.hideDebugInfo();
+        };
+    },
+
+    selectResults: function(target)
+    {
+        target.selectRange = ((target.selectRange || 0) + 1) % 3;
+
+        var selection = window.getSelection();
+        selection.removeAllRanges();
+        var range = document.createRange();
+        switch (target.selectRange) {
+            case 0: {
+                range.selectNode(document.getElementById("results-score"));
+                break;
+            }
+            case 1: {
+                range.setStart(document.querySelector("#results .score"), 0);
+                range.setEndAfter(document.querySelector("#results-score"), 0);
+                break;
+            }
+            case 2: {
+                range.selectNodeContents(document.querySelector("#results .score"));
+                break;
+            }
+        }
+        selection.addRange(range);
+    }
+};
+
+window.addEventListener("load", function() { benchmarkController.initialize(); });
+
diff --git a/third_party/blink/perf_tests/MotionMark/resources/runner/tests.js b/third_party/blink/perf_tests/MotionMark/resources/runner/tests.js
new file mode 100644
index 0000000..33987f3b
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/runner/tests.js
@@ -0,0 +1,77 @@
+var Headers = {
+    testName: [
+        {
+            title: "<span onclick='benchmarkController.showDebugInfo()'>" + Strings.text.testName + "</span>",
+            text: Strings.text.testName
+        }
+    ],
+    score: [
+        {
+            title: Strings.text.score,
+            text: Strings.json.score
+        }
+    ],
+    details: [
+        {
+            title: "&nbsp;",
+            text: function(data) {
+                var bootstrap = data[Strings.json.complexity][Strings.json.bootstrap];
+                return "<span>±" + (Statistics.largestDeviationPercentage(bootstrap.confidenceLow, bootstrap.median, bootstrap.confidenceHigh) * 100).toFixed(2) + "%</span>";
+            }
+        }
+    ]
+};
+
+var Suite = function(name, tests) {
+    this.name = name;
+    this.tests = tests;
+};
+
+var Suites = [];
+
+Suites.push(new Suite("MotionMark",
+    [
+        {
+            url: "master/multiply.html", // nocheck
+            name: "Multiply"
+        },
+        {
+            url: "master/canvas-stage.html?pathType=arcs", // nocheck
+            name: "Canvas Arcs"
+        },
+        {
+            url: "master/leaves.html", // nocheck
+            name: "Leaves"
+        },
+        {
+            url: "master/canvas-stage.html?pathType=linePath", // nocheck
+            name: "Paths"
+        },
+        {
+            url: "master/canvas-stage.html?pathType=line&lineCap=square", // nocheck
+            name: "Canvas Lines"
+        },
+        {
+            url: "master/image-data.html", // nocheck
+            name: "Images"
+        },
+        {
+            url: "master/design.html", // nocheck
+            name: "Design"
+        },
+        {
+            url: "master/suits.html", // nocheck
+            name: "Suits"
+        },
+    ]
+));
+
+function suiteFromName(name)
+{
+    return Suites.find(function(suite) { return suite.name == name; });
+}
+
+function testFromName(suite, name)
+{
+    return suite.tests.find(function(test) { return test.name == name; });
+}
diff --git a/third_party/blink/perf_tests/MotionMark/resources/statistics.js b/third_party/blink/perf_tests/MotionMark/resources/statistics.js
new file mode 100644
index 0000000..14c254a
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/statistics.js
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+Pseudo =
+{
+    initialRandomSeed: 49734321,
+    randomSeed: 49734321,
+
+    resetRandomSeed: function()
+    {
+        Pseudo.randomSeed = Pseudo.initialRandomSeed;
+    },
+
+    random: function()
+    {
+        var randomSeed = Pseudo.randomSeed;
+        randomSeed = ((randomSeed + 0x7ed55d16) + (randomSeed << 12))  & 0xffffffff;
+        randomSeed = ((randomSeed ^ 0xc761c23c) ^ (randomSeed >>> 19)) & 0xffffffff;
+        randomSeed = ((randomSeed + 0x165667b1) + (randomSeed << 5))   & 0xffffffff;
+        randomSeed = ((randomSeed + 0xd3a2646c) ^ (randomSeed << 9))   & 0xffffffff;
+        randomSeed = ((randomSeed + 0xfd7046c5) + (randomSeed << 3))   & 0xffffffff;
+        randomSeed = ((randomSeed ^ 0xb55a4f09) ^ (randomSeed >>> 16)) & 0xffffffff;
+        Pseudo.randomSeed = randomSeed;
+        return (randomSeed & 0xfffffff) / 0x10000000;
+    }
+};
+
+Statistics =
+{
+    sampleMean: function(numberOfSamples, sum)
+    {
+        if (numberOfSamples < 1)
+            return 0;
+        return sum / numberOfSamples;
+    },
+
+    // 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/
+    unbiasedSampleStandardDeviation: function(numberOfSamples, sum, squareSum)
+    {
+        if (numberOfSamples < 2)
+            return 0;
+        return Math.sqrt((squareSum - sum * sum / numberOfSamples) / (numberOfSamples - 1));
+    },
+
+    geometricMean: function(values)
+    {
+        if (!values.length)
+            return 0;
+        var roots = values.map(function(value) { return Math.pow(value, 1 / values.length); })
+        return roots.reduce(function(a, b) { return a * b; });
+    },
+
+    // Cumulative distribution function
+    cdf: function(value, mean, standardDeviation)
+    {
+        return 0.5 * (1 + Statistics.erf((value - mean) / (Math.sqrt(2 * standardDeviation * standardDeviation))));
+    },
+
+    // Approximation of Gauss error function, Abramowitz and Stegun 7.1.26
+    erf: function(value)
+    {
+          var sign = (value >= 0) ? 1 : -1;
+          value = Math.abs(value);
+
+          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 * value);
+          var y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * Math.exp(-value * value);
+          return sign * y;
+    },
+
+    largestDeviationPercentage: function(low, mean, high)
+    {
+        return Math.max(Math.abs(low / mean - 1), (high / mean - 1));
+    }
+};
+
+Experiment = Utilities.createClass(
+    function(includeConcern)
+    {
+        if (includeConcern)
+            this._maxHeap = Heap.createMaxHeap(Experiment.defaults.CONCERN_SIZE);
+        this.reset();
+    }, {
+
+    reset: function()
+    {
+        this._sum = 0;
+        this._squareSum = 0;
+        this._numberOfSamples = 0;
+        if (this._maxHeap)
+            this._maxHeap.init();
+    },
+
+    get sampleCount()
+    {
+        return this._numberOfSamples;
+    },
+
+    sample: function(value)
+    {
+        this._sum += value;
+        this._squareSum += value * value;
+        if (this._maxHeap)
+            this._maxHeap.push(value);
+        ++this._numberOfSamples;
+    },
+
+    mean: function()
+    {
+        return Statistics.sampleMean(this._numberOfSamples, this._sum);
+    },
+
+    standardDeviation: function()
+    {
+        return Statistics.unbiasedSampleStandardDeviation(this._numberOfSamples, this._sum, this._squareSum);
+    },
+
+    cdf: function(value)
+    {
+        return Statistics.cdf(value, this.mean(), this.standardDeviation());
+    },
+
+    percentage: function()
+    {
+        var mean = this.mean();
+        return mean ? this.standardDeviation() * 100 / mean : 0;
+    },
+
+    concern: function(percentage)
+    {
+        if (!this._maxHeap)
+            return this.mean();
+
+        var size = Math.ceil(this._numberOfSamples * percentage / 100);
+        var values = this._maxHeap.values(size);
+        return values.length ? values.reduce(function(a, b) { return a + b; }) / values.length : 0;
+    },
+
+    score: function(percentage)
+    {
+        return Statistics.geometricMean([this.mean(), Math.max(this.concern(percentage), 1)]);
+    }
+});
+
+Experiment.defaults =
+{
+    CONCERN: 5,
+    CONCERN_SIZE: 100,
+};
+
+Regression = Utilities.createClass(
+    function(samples, getComplexity, getFrameLength, startIndex, endIndex, options)
+    {
+        var targetFrameRate = options["frame-rate"] || 60;
+        var desiredFrameLength = options.desiredFrameLength || 1000/targetFrameRate;
+        var bestProfile;
+
+        if (!options.preferredProfile || options.preferredProfile == Strings.json.profiles.slope) {
+            var slope = this._calculateRegression(samples, getComplexity, getFrameLength, startIndex, endIndex, {
+                shouldClip: true,
+                s1: desiredFrameLength,
+                t1: 0
+            });
+            if (!bestProfile || slope.error < bestProfile.error) {
+                bestProfile = slope;
+                this.profile = Strings.json.profiles.slope;
+            }
+        }
+        if (!options.preferredProfile || options.preferredProfile == Strings.json.profiles.flat) {
+            var flat = this._calculateRegression(samples, getComplexity, getFrameLength, startIndex, endIndex, {
+                shouldClip: true,
+                s1: desiredFrameLength,
+                t1: 0,
+                t2: 0
+            });
+
+            if (!bestProfile || flat.error < bestProfile.error) {
+                bestProfile = flat;
+                this.profile = Strings.json.profiles.flat;
+            }
+        }
+
+        this.startIndex = Math.min(startIndex, endIndex);
+        this.endIndex = Math.max(startIndex, endIndex);
+
+        this.complexity = bestProfile.complexity;
+        this.s1 = bestProfile.s1;
+        this.t1 = bestProfile.t1;
+        this.s2 = bestProfile.s2;
+        this.t2 = bestProfile.t2;
+        this.stdev1 = bestProfile.stdev1;
+        this.stdev2 = bestProfile.stdev2;
+        this.n1 = bestProfile.n1;
+        this.n2 = bestProfile.n2;
+        this.error = bestProfile.error;
+    }, {
+
+    valueAt: function(complexity)
+    {
+        if (this.n1 == 1 || complexity > this.complexity)
+            return this.s2 + this.t2 * complexity;
+        return this.s1 + this.t1 * complexity;
+    },
+
+    // A generic two-segment piecewise regression calculator. Based on Kundu/Ubhaya
+    //
+    // Minimize sum of (y - y')^2
+    // where                        y = s1 + t1*x
+    //                              y = s2 + t2*x
+    //                y' = s1 + t1*x' = s2 + t2*x'   if x_0 <= x' <= x_n
+    //
+    // Allows for fixing s1, t1, s2, t2
+    //
+    // x is assumed to be complexity, y is frame length. Can be used for pure complexity-FPS
+    // analysis or for ramp controllers since complexity monotonically decreases with time.
+    _calculateRegression: function(samples, getComplexity, getFrameLength, startIndex, endIndex, options)
+    {
+        if (startIndex == endIndex) {
+            // Only one sample point; we can't calculate any regression.
+            var x = getComplexity(samples, startIndex);
+            return {
+                complexity: x,
+                s1: x,
+                t1: 0,
+                s2: x,
+                t2: 0,
+                error1: 0,
+                error2: 0
+            };
+        }
+
+        // x is expected to increase in complexity
+        var iterationDirection = endIndex > startIndex ? 1 : -1;
+        var lowComplexity = getComplexity(samples, startIndex);
+        var highComplexity = getComplexity(samples, endIndex);
+        var a1 = 0, b1 = 0, c1 = 0, d1 = 0, h1 = 0, k1 = 0;
+        var a2 = 0, b2 = 0, c2 = 0, d2 = 0, h2 = 0, k2 = 0;
+
+        // Iterate from low to high complexity
+        for (var i = startIndex; iterationDirection * (endIndex - i) > -1; i += iterationDirection) {
+            var x = getComplexity(samples, i);
+            var y = getFrameLength(samples, i);
+            a2 += 1;
+            b2 += x;
+            c2 += x * x;
+            d2 += y;
+            h2 += y * x;
+            k2 += y * y;
+        }
+
+        var s1_best, t1_best, s2_best, t2_best, n1_best, n2_best, error1_best, error2_best, x_best, x_prime;
+
+        function setBest(s1, t1, error1, s2, t2, error2, splitIndex, x_prime, x)
+        {
+            s1_best = s1;
+            t1_best = t1;
+            error1_best = error1;
+            s2_best = s2;
+            t2_best = t2;
+            error2_best = error2;
+            // Number of samples included in the first segment, inclusive of splitIndex
+            n1_best = iterationDirection * (splitIndex - startIndex) + 1;
+            // Number of samples included in the second segment
+            n2_best = iterationDirection * (endIndex - splitIndex);
+            if (!options.shouldClip || (x_prime >= lowComplexity && x_prime <= highComplexity))
+                x_best = x_prime;
+            else {
+                // Discontinuous piecewise regression
+                x_best = x;
+            }
+        }
+
+        // Iterate from startIndex to endIndex - 1, inclusive
+        for (var i = startIndex; iterationDirection * (endIndex - i) > 0; i += iterationDirection) {
+            var x = getComplexity(samples, i);
+            var y = getFrameLength(samples, i);
+            var xx = x * x;
+            var yx = y * x;
+            var yy = y * y;
+            // a1, b1, etc. is sum from startIndex to i, inclusive
+            a1 += 1;
+            b1 += x;
+            c1 += xx;
+            d1 += y;
+            h1 += yx;
+            k1 += yy;
+            // a2, b2, etc. is sum from i+1 to endIndex, inclusive
+            a2 -= 1;
+            b2 -= x;
+            c2 -= xx;
+            d2 -= y;
+            h2 -= yx;
+            k2 -= yy;
+
+            var A = c1*d1 - b1*h1;
+            var B = a1*h1 - b1*d1;
+            var C = a1*c1 - b1*b1;
+            var D = c2*d2 - b2*h2;
+            var E = a2*h2 - b2*d2;
+            var F = a2*c2 - b2*b2;
+            var s1 = options.s1 !== undefined ? options.s1 : (A / C);
+            var t1 = options.t1 !== undefined ? options.t1 : (B / C);
+            var s2 = options.s2 !== undefined ? options.s2 : (D / F);
+            var t2 = options.t2 !== undefined ? options.t2 : (E / F);
+            // Assumes that the two segments meet
+            var x_prime = (s1 - s2) / (t2 - t1);
+
+            var error1 = (k1 + a1*s1*s1 + c1*t1*t1 - 2*d1*s1 - 2*h1*t1 + 2*b1*s1*t1) || Number.MAX_VALUE;
+            var error2 = (k2 + a2*s2*s2 + c2*t2*t2 - 2*d2*s2 - 2*h2*t2 + 2*b2*s2*t2) || Number.MAX_VALUE;
+
+            if (i == startIndex) {
+                setBest(s1, t1, error1, s2, t2, error2, i, x_prime, x);
+                continue;
+            }
+
+            if (C == 0 || F == 0)
+                continue;
+
+            // Projected point is not between this and the next sample
+            if (x_prime > getComplexity(samples, i + iterationDirection) || x_prime < x) {
+                // Calculate lambda, which divides the weight of this sample between the two lines
+
+                // These values remove the influence of this sample
+                var I = c1 - 2*b1*x + a1*xx;
+                var H = C - I;
+                var G = A + B*x - C*y;
+
+                var J = D + E*x - F*y;
+                var K = c2 - 2*b2*x + a2*xx;
+
+                var lambda = (G*F + G*K - H*J) / (I*J + G*K);
+                if (lambda > 0 && lambda < 1) {
+                    var lambda1 = 1 - lambda;
+                    s1 = options.s1 !== undefined ? options.s1 : ((A - lambda1*(-h1*x + d1*xx + c1*y - b1*yx)) / (C - lambda1*I));
+                    t1 = options.t1 !== undefined ? options.t1 : ((B - lambda1*(h1 - d1*x - b1*y + a1*yx)) / (C - lambda1*I));
+                    s2 = options.s2 !== undefined ? options.s2 : ((D + lambda1*(-h2*x + d2*xx + c2*y - b2*yx)) / (F + lambda1*K));
+                    t2 = options.t2 !== undefined ? options.t2 : ((E + lambda1*(h2 - d2*x - b2*y + a2*yx)) / (F + lambda1*K));
+                    x_prime = (s1 - s2) / (t2 - t1);
+
+                    error1 = ((k1 + a1*s1*s1 + c1*t1*t1 - 2*d1*s1 - 2*h1*t1 + 2*b1*s1*t1) - lambda1 * Math.pow(y - (s1 + t1*x), 2)) || Number.MAX_VALUE;
+                    error2 = ((k2 + a2*s2*s2 + c2*t2*t2 - 2*d2*s2 - 2*h2*t2 + 2*b2*s2*t2) + lambda1 * Math.pow(y - (s2 + t2*x), 2)) || Number.MAX_VALUE;
+                } else if (t1 != t2)
+                    continue;
+            }
+
+            if (error1 + error2 < error1_best + error2_best)
+                setBest(s1, t1, error1, s2, t2, error2, i, x_prime, x);
+        }
+
+        return {
+            complexity: x_best,
+            s1: s1_best,
+            t1: t1_best,
+            stdev1: Math.sqrt(error1_best / n1_best),
+            s2: s2_best,
+            t2: t2_best,
+            stdev2: Math.sqrt(error2_best / n2_best),
+            error: error1_best + error2_best,
+            n1: n1_best,
+            n2: n2_best
+        };
+    }
+});
+
+Utilities.extendObject(Regression, {
+    bootstrap: function(samples, iterationCount, processResample, confidencePercentage)
+    {
+        var sampleLength = samples.length;
+        var resample = new Array(sampleLength);
+
+        var bootstrapEstimator = new Experiment;
+        var bootstrapData = new Array(iterationCount);
+
+        Pseudo.resetRandomSeed();
+        for (var i = 0; i < iterationCount; ++i) {
+            for (var j = 0; j < sampleLength; ++j)
+                resample[j] = samples[Math.floor(Pseudo.random() * sampleLength)];
+
+            var resampleResult = processResample(resample);
+            bootstrapEstimator.sample(resampleResult);
+            bootstrapData[i] = resampleResult;
+        }
+
+        bootstrapData.sort(function(a, b) { return a - b; });
+        return {
+            confidenceLow: bootstrapData[Math.round((iterationCount - 1) * (1 - confidencePercentage) / 2)],
+            confidenceHigh: bootstrapData[Math.round((iterationCount - 1) * (1 + confidencePercentage) / 2)],
+            median: bootstrapData[Math.round(iterationCount / 2)],
+            mean: bootstrapEstimator.mean(),
+            data: bootstrapData,
+            confidencePercentage: confidencePercentage
+        };
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/resources/strings.js b/third_party/blink/perf_tests/MotionMark/resources/strings.js
new file mode 100644
index 0000000..32a22c8
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/resources/strings.js
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015-2020 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 Strings = {
+    version: "1.3",
+    text: {
+        testName: "Test Name",
+        score: "Score",
+        title: "MotionMark %s",
+    },
+    json: {
+        version: "version",
+
+        marks: "marks",
+        samplingStartTimeOffset: "Start sampling",
+        samplingEndTimeOffset: "End sampling",
+
+        samples: "samples",
+        dataFieldMap: "dataFieldMap",
+        controller: "controller",
+        time: "time",
+        complexity: "complexity",
+        frameLength: "frameLength",
+        smoothedFrameLength: "smoothedFrameLength",
+
+        result: "result",
+        configuration: "configuration",
+        score: "score",
+        scoreLowerBound: "scoreLowerBound",
+        scoreUpperBound: "scoreUpperBound",
+        fps: "fps",
+        bootstrap: "bootstrap",
+        measurements: {
+            average: "average",
+            concern: "concern",
+            stdev: "stdev",
+            percent: "percent"
+        },
+
+        regressions: {
+            startIndex: "startIndex",
+            endIndex: "endIndex",
+            segment1: "segment1",
+            segment2: "segment2",
+            profile: "profile"
+        },
+
+        profiles: {
+            slope: "slope",
+            flat: "flat"
+        },
+
+        results: {
+            iterations: "iterationsResults",
+            tests: "testsResults"
+        }
+    }
+};
diff --git a/third_party/blink/perf_tests/MotionMark/tests/3d/resources/webgl.js b/third_party/blink/perf_tests/MotionMark/tests/3d/resources/webgl.js
new file mode 100644
index 0000000..33dc0fe
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/3d/resources/webgl.js
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+WebGLStage = Utilities.createSubclass(Stage,
+    function(element, options)
+    {
+        Stage.call(this);
+    },
+    {
+
+        initialize: function(benchmark, options)
+        {
+            Stage.prototype.initialize.call(this, benchmark, options);
+
+            this._numTriangles = 0;
+            this._bufferSize = 0;
+
+            this._gl = this.element.getContext("webgl");
+            var gl = this._gl;
+
+            gl.clearColor(0, 0, 0, 1);
+
+            // Create the vertex shader object.
+            var vertexShader = gl.createShader(gl.VERTEX_SHADER);
+
+            // The source code for the shader is extracted from the <script> element above.
+            gl.shaderSource(vertexShader, this._getFunctionSource("vertex"));
+
+            // Compile the shader.
+            gl.compileShader(vertexShader);
+            if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
+                // We failed to compile. Output to the console and quit.
+                console.error("Vertex Shader failed to compile.");
+                console.error(gl.getShaderInfoLog(vertexShader));
+                return;
+            }
+
+            // Now do the fragment shader.
+            var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
+            gl.shaderSource(fragmentShader, this._getFunctionSource("fragment"));
+            gl.compileShader(fragmentShader);
+            if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
+                console.error("Fragment Shader failed to compile.");
+                console.error(gl.getShaderInfoLog(fragmentShader));
+                return;
+            }
+
+            // We have two compiled shaders. Time to make the program.
+            var program = gl.createProgram();
+            gl.attachShader(program, vertexShader);
+            gl.attachShader(program, fragmentShader);
+            gl.linkProgram(program);
+
+            if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+                console.error("Unable to link shaders into program.");
+                return;
+            }
+
+            // Our program has two inputs. We have a single uniform "color",
+            // and one vertex attribute "position".
+
+            gl.useProgram(program);
+            this._uScale = gl.getUniformLocation(program, "scale");
+            this._uTime = gl.getUniformLocation(program, "time");
+            this._uOffsetX = gl.getUniformLocation(program, "offsetX");
+            this._uOffsetY = gl.getUniformLocation(program, "offsetY");
+            this._uScalar = gl.getUniformLocation(program, "scalar");
+            this._uScalarOffset = gl.getUniformLocation(program, "scalarOffset");
+
+            this._aPosition = gl.getAttribLocation(program, "position");
+            gl.enableVertexAttribArray(this._aPosition);
+
+            this._aColor = gl.getAttribLocation(program, "color");
+            gl.enableVertexAttribArray(this._aColor);
+
+            this._positionData = new Float32Array([
+                // x y z 1
+                   0,  0.1, 0, 1,
+                -0.1, -0.1, 0, 1,
+                 0.1, -0.1, 0, 1
+            ]);
+            this._positionBuffer = gl.createBuffer();
+            gl.bindBuffer(gl.ARRAY_BUFFER, this._positionBuffer);
+            gl.bufferData(gl.ARRAY_BUFFER, this._positionData, gl.STATIC_DRAW);
+
+            this._colorData = new Float32Array([
+                1, 0, 0, 1,
+                0, 1, 0, 1,
+                0, 0, 1, 1
+            ]);
+            this._colorBuffer = gl.createBuffer();
+            gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer);
+            gl.bufferData(gl.ARRAY_BUFFER, this._colorData, gl.STATIC_DRAW);
+
+            this._resetIfNecessary();
+        },
+
+        _getFunctionSource: function(id)
+        {
+            return document.getElementById(id).text;
+        },
+
+        _resetIfNecessary: function()
+        {
+            if (this._numTriangles <= this._bufferSize)
+                return;
+
+            if (!this._bufferSize)
+                this._bufferSize = 128;
+
+            while (this._numTriangles > this._bufferSize)
+                this._bufferSize *= 4;
+
+            this._uniformData = new Float32Array(this._bufferSize * 6);
+            for (var i = 0; i < this._bufferSize; ++i) {
+                this._uniformData[i * 6 + 0] = Stage.random(0.2, 0.4);
+                this._uniformData[i * 6 + 1] = 0;
+                this._uniformData[i * 6 + 2] = Stage.random(-0.9, 0.9);
+                this._uniformData[i * 6 + 3] = Stage.random(-0.9, 0.9);
+                this._uniformData[i * 6 + 4] = Stage.random(0.5, 2);
+                this._uniformData[i * 6 + 5] = Stage.random(0, 10);
+            }
+        },
+
+        tune: function(count)
+        {
+            if (!count)
+                return;
+
+            this._numTriangles += count;
+            this._numTriangles = Math.max(this._numTriangles, 0);
+
+            this._resetIfNecessary();
+        },
+
+        animate: function(timeDelta)
+        {
+            var gl = this._gl;
+
+            gl.clear(gl.COLOR_BUFFER_BIT);
+
+            if (!this._startTime)
+                this._startTime = Stage.dateCounterValue(1000);
+            var elapsedTime = Stage.dateCounterValue(1000) - this._startTime;
+
+            for (var i = 0; i < this._numTriangles; ++i) {
+
+                this._uniformData[i * 6 + 1] = elapsedTime;
+
+                var uniformDataOffset = i * 6;
+                gl.uniform1f(this._uScale, this._uniformData[uniformDataOffset++]);
+                gl.uniform1f(this._uTime, this._uniformData[uniformDataOffset++]);
+                gl.uniform1f(this._uOffsetX, this._uniformData[uniformDataOffset++]);
+                gl.uniform1f(this._uOffsetY, this._uniformData[uniformDataOffset++]);
+                gl.uniform1f(this._uScalar, this._uniformData[uniformDataOffset++]);
+                gl.uniform1f(this._uScalarOffset, this._uniformData[uniformDataOffset++]);
+
+                gl.bindBuffer(gl.ARRAY_BUFFER, this._positionBuffer);
+                gl.vertexAttribPointer(this._aPosition, 4, gl.FLOAT, false, 0, 0);
+
+                gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer);
+                gl.vertexAttribPointer(this._aColor, 4, gl.FLOAT, false, 0, 0);
+
+                gl.drawArrays(gl.TRIANGLES, 0, 3);
+            }
+
+        },
+
+        complexity: function()
+        {
+            return this._numTriangles;
+        }
+    }
+);
+
+WebGLBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new WebGLStage(), options);
+    }
+);
+
+window.benchmarkClass = WebGLBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/3d/resources/webgpu.js b/third_party/blink/perf_tests/MotionMark/tests/3d/resources/webgpu.js
new file mode 100644
index 0000000..f848d1c
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/3d/resources/webgpu.js
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+const whlslShaders = `
+struct VertexOutput {
+  float4 position : SV_Position;
+  float4 color : attribute(1);
+}
+
+vertex VertexOutput vertexMain(float4 position : attribute(0),
+                                float4 color : attribute(1),
+                                constant float[] timeUniform : register(b0, space0),
+                                constant float[] uniforms : register(b0, space1)) {
+  float scale = uniforms[0];
+  float offsetX = uniforms[1];
+  float offsetY = uniforms[2];
+  float scalar = uniforms[3];
+  float scalarOffset = uniforms[4];
+  float time = timeUniform[0];
+
+  float fade = fmod(scalarOffset + time * scalar / 10.0, 1.0);
+  if (fade < 0.5) {
+      fade = fade * 2.0;
+  } else {
+      fade = (1.0 - fade) * 2.0;
+  }
+  float xpos = position.x * scale;
+  float ypos = position.y * scale;
+  float angle = 3.14159 * 2.0 * fade;
+  float xrot = xpos * cos(angle) - ypos * sin(angle);
+  float yrot = xpos * sin(angle) + ypos * cos(angle);
+  xpos = xrot + offsetX;
+  ypos = yrot + offsetY;
+
+  VertexOutput out;
+  out.position = float4(xpos, ypos, 0.0, 1.0);
+  out.color = float4(fade, 1.0 - fade, 0.0, 1.0) + color;
+  return out;
+}
+
+fragment float4 fragmentMain(float4 inColor : attribute(1)) : SV_Target 0 {
+    return inColor;
+}
+`;
+
+(function() {
+
+WebGLStage = Utilities.createSubclass(Stage,
+    function(element, options)
+    {
+        Stage.call(this);
+    },
+    {
+        initialize: function(benchmark, options)
+        {
+            Stage.prototype.initialize.call(this, benchmark, options);
+
+            this._numTriangles = 0;
+
+            const gpuContext = this.element.getContext('gpu');
+
+            navigator.gpu.requestAdapter({ powerPreference: "low-power" }).then(adapter => {
+                return adapter.requestDevice().then(device => {
+                    this._device = device;
+
+                    const swapChainFormat = "bgra8unorm";
+                    this._swapChain = gpuContext.configureSwapChain({
+                        device: device,
+                        format: swapChainFormat,
+                        usage: GPUTextureUsage.OUTPUT_ATTACHMENT
+                    });
+
+                    this._timeBindGroupLayout = device.createBindGroupLayout({
+                        bindings: [
+                            { binding: 0, visibility: GPUShaderStageBit.VERTEX, type: "uniform-buffer" },
+                        ],
+                    });
+
+                    this._bindGroupLayout = device.createBindGroupLayout({
+                        bindings: [
+                            { binding: 0, visibility: GPUShaderStageBit.VERTEX, type: "uniform-buffer" },
+                        ],
+                    });
+
+                    const vec4Size = 4 * Float32Array.BYTES_PER_ELEMENT;
+
+                    const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [this._timeBindGroupLayout, this._bindGroupLayout] });
+                    const shaderModule = device.createShaderModule({ code: whlslShaders, isWHLSL: true });
+
+                    const pipelineDesc = {
+                        layout: pipelineLayout,
+                        vertexStage: {
+                            module: shaderModule,
+                            entryPoint: "vertexMain",
+                        },
+                        fragmentStage: {
+                            module: shaderModule,
+                            entryPoint: "fragmentMain"
+                        },
+
+                        primitiveTopology: "triangle-list",
+
+                        vertexInput: {
+                            indexFormat: "uint32",
+                            vertexBuffers: [{
+                                // vertex buffer
+                                stride: 2 * vec4Size,
+                                stepMode: "vertex",
+                                attributeSet: [{
+                                    // vertex positions
+                                    shaderLocation: 0,
+                                    offset: 0,
+                                    format: "float4"
+                                }, {
+                                    // vertex colors
+                                    shaderLocation: 1,
+                                    offset: vec4Size,
+                                    format: "float4"
+                                }],
+                            }],
+                        },
+
+                        rasterizationState: {
+                            frontFace: 'ccw',
+                            cullMode: 'none',
+                        },
+
+                        colorStates: [{
+                            format: swapChainFormat,
+                            alphaBlend: {},
+                            colorBlend: {},
+                        }],
+                    };
+
+                    this._pipeline = device.createRenderPipeline(pipelineDesc);
+
+                    const [vertexBuffer, vertexArrayBuffer] = device.createBufferMapped({
+                        size: 2 * 3 * vec4Size,
+                        usage: GPUBufferUsage.VERTEX
+                    });
+                    const vertexWriteBuffer = new Float32Array(vertexArrayBuffer);
+                    vertexWriteBuffer.set([
+                    // position data  /**/ color data
+                    0, 0.1, 0, 1,     /**/ 1, 0, 0, 1,
+                    -0.1, -0.1, 0, 1, /**/ 0, 1, 0, 1,
+                    0.1, -0.1, 0, 1,  /**/ 0, 0, 1, 1,
+                    ]);
+                    vertexBuffer.unmap();
+
+                    this._vertexBuffer = vertexBuffer;
+                    this._timeMappedBuffers = [];
+
+                    this._resetIfNecessary();
+
+                    benchmark._initPromise.resolve();
+                });
+            });
+        },
+
+        _getFunctionSource: function(id)
+        {
+            return document.getElementById(id).text;
+        },
+
+        _resetIfNecessary: function()
+        {
+            if (this._bindGroups != undefined && this._numTriangles <= this._bindGroups.length)
+                return;
+
+            const numTriangles = this._numTriangles;
+
+            const device = this._device;
+
+            // Minimum buffer offset alignment is 256 bytes.
+            const uniformBytes = 5 * Float32Array.BYTES_PER_ELEMENT;
+            const alignedUniformBytes = Math.ceil(uniformBytes / 256) * 256;
+            const alignedUniformFloats = alignedUniformBytes / Float32Array.BYTES_PER_ELEMENT;
+
+            const [uniformBuffer, uniformArrayBuffer] = device.createBufferMapped({
+                size: numTriangles * alignedUniformBytes + Float32Array.BYTES_PER_ELEMENT,
+                usage: GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.UNIFORM
+            });
+            const uniformWriteArray = new Float32Array(uniformArrayBuffer);
+
+            this._bindGroups = new Array(numTriangles);
+            for (let i = 0; i < numTriangles; ++i) {
+                uniformWriteArray[alignedUniformFloats * i + 0] = Stage.random(0.2, 0.4);   // scale
+                uniformWriteArray[alignedUniformFloats * i + 1] = Stage.random(-0.9, 0.9);  // offsetX
+                uniformWriteArray[alignedUniformFloats * i + 2] = Stage.random(-0.9, 0.9);  // offsetY
+                uniformWriteArray[alignedUniformFloats * i + 3] = Stage.random(0.5, 2);     // scalar
+                uniformWriteArray[alignedUniformFloats * i + 4] = Stage.random(0, 10);      // scalarOffset
+
+                this._bindGroups[i] = device.createBindGroup({
+                  layout: this._bindGroupLayout,
+                  bindings: [{
+                    binding: 0,
+                    resource: {
+                      buffer: uniformBuffer,
+                      offset: i * alignedUniformBytes,
+                      size: 6 * Float32Array.BYTES_PER_ELEMENT,
+                    }
+                  }]
+                });
+            }
+
+            uniformBuffer.unmap();
+
+            this._timeOffset = numTriangles * alignedUniformBytes;
+            this._timeBindGroup = device.createBindGroup({
+            layout: this._timeBindGroupLayout,
+            bindings: [{
+                binding: 0,
+                resource: {
+                    buffer: uniformBuffer,
+                    offset: this._timeOffset,
+                    size: Float32Array.BYTES_PER_ELEMENT,
+                    }
+                }]
+            });
+
+            this._uniformBuffer = uniformBuffer;
+        },
+
+        tune: function(count)
+        {
+            if (!count)
+                return;
+
+            this._numTriangles += count;
+            this._numTriangles = Math.max(this._numTriangles, 0);
+
+            this._resetIfNecessary();
+        },
+
+        animate: function(timeDelta)
+        {
+            const device = this._device;
+
+            if (!this._startTime)
+                this._startTime = Stage.dateCounterValue(1000);
+
+            const elapsedTimeData = new Float32Array([Stage.dateCounterValue(1000) - this._startTime]);
+
+            // Update time uniform
+            let mappedBuffer;
+
+            if (this._timeMappedBuffers.length === 0) {
+                mappedBuffer = device.createBufferMapped({
+                    size: Float32Array.BYTES_PER_ELEMENT,
+                    usage: GPUBufferUsage.TRANSFER_SRC | GPUBufferUsage.MAP_WRITE
+                });
+            } else
+                mappedBuffer = this._timeMappedBuffers.shift();
+
+            const [timeStagingBuffer, timeStagingArrayBuffer] = mappedBuffer;
+
+            const writeArray = new Float32Array(timeStagingArrayBuffer);
+            writeArray.set(elapsedTimeData);
+            timeStagingBuffer.unmap();
+
+            const commandEncoder = device.createCommandEncoder({});
+            commandEncoder.copyBufferToBuffer(timeStagingBuffer, 0, this._uniformBuffer, this._timeOffset, elapsedTimeData.byteLength);
+
+            const renderPassDescriptor = {
+                colorAttachments: [{
+                    loadOp: "clear",
+                    storeOp: "store",
+                    clearColor: { r: 1, g: 1, b: 1, a: 1.0 },
+                    attachment: this._swapChain.getCurrentTexture().createDefaultView(),
+                }],
+            };
+
+            const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
+            passEncoder.setPipeline(this._pipeline);
+            passEncoder.setVertexBuffers(0, [this._vertexBuffer], [0]);
+            passEncoder.setBindGroup(0, this._timeBindGroup);
+            for (let i = 0; i < this._numTriangles; ++i) {
+                passEncoder.setBindGroup(1, this._bindGroups[i]);
+                passEncoder.draw(3, 1, 0, 0);
+            }
+            passEncoder.endPass();
+
+            device.getQueue().submit([commandEncoder.finish()]);
+
+            timeStagingBuffer.mapWriteAsync().then(arrayBuffer => {
+                mappedBuffer[1] = arrayBuffer;
+                this._timeMappedBuffers.push(mappedBuffer);
+            });
+        },
+
+        complexity: function()
+        {
+            return this._numTriangles;
+        }
+    }
+);
+
+WebGLBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new WebGLStage(), options);
+    }, {
+
+    waitUntilReady: function() {
+        this._initPromise = new SimplePromise;
+        return this._initPromise;
+    },
+});
+
+window.benchmarkClass = WebGLBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/3d/triangles-webgl.html b/third_party/blink/perf_tests/MotionMark/tests/3d/triangles-webgl.html
new file mode 100644
index 0000000..8ce2a37
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/3d/triangles-webgl.html
@@ -0,0 +1,93 @@
+<!--
+  Copyright (C) 2015-2019 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        #stage {
+            background-color: #000;
+        }
+    </style>
+</head>
+<body>
+    <canvas id="stage"></canvas>
+    <script id="vertex" type="x-shader/x-glsl">
+attribute vec4 position;
+attribute vec4 color;
+
+uniform float scale;
+uniform float time;
+uniform float offsetX;
+uniform float offsetY;
+uniform float scalar;
+uniform float scalarOffset;
+
+varying vec4 v_color;
+
+void main() {
+
+    float fade = mod(scalarOffset + time * scalar / 10.0, 1.0);
+
+    if (fade < 0.5) {
+        fade = fade * 2.0;
+    } else {
+        fade = (1.0 - fade) * 2.0;
+    }
+
+    float xpos = position.x * scale;
+    float ypos = position.y * scale;
+
+    float angle = 3.14159 * 2.0 * fade;
+    float xrot = xpos * cos(angle) - ypos * sin(angle);
+    float yrot = xpos * sin(angle) + ypos * cos(angle);
+
+    xpos = xrot + offsetX;
+    ypos = yrot + offsetY;
+
+    v_color = vec4(fade, 1.0 - fade, 0.0, 1.0) + color;
+    gl_Position = vec4(xpos, ypos, 0.0, 1.0);
+}
+    </script>
+    <script id="fragment" type="x-shader/x-glsl">
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+varying vec4 v_color;
+
+void main() {
+    gl_FragColor = v_color;
+}
+    </script>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/webgl.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/3d/triangles-webgpu.html b/third_party/blink/perf_tests/MotionMark/tests/3d/triangles-webgpu.html
new file mode 100644
index 0000000..e8929b0d
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/3d/triangles-webgpu.html
@@ -0,0 +1,45 @@
+<!--
+  Copyright (C) 2019 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        #stage {
+            background-color: #fff;
+        }
+    </style>
+</head>
+<body>
+    <canvas id="stage"></canvas>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/webgpu.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-canvas-images.html b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-canvas-images.html
new file mode 100644
index 0000000..90264c94
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-canvas-images.html
@@ -0,0 +1,50 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        img.hidden {
+            position: absolute;
+            visibility: hidden;
+        }
+    </style>
+</head>
+<body>
+    <img class="hidden" src="../resources/yin-yang.svg">
+    <img class="hidden" src="../resources/yin-yang.png">
+    <canvas id="stage"></canvas>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/bouncing-particles.js"></script>
+    <script src="resources/bouncing-canvas-particles.js"></script>
+    <script src="resources/bouncing-canvas-images.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-canvas-shapes.html b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-canvas-shapes.html
new file mode 100644
index 0000000..63c3feebd7
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-canvas-shapes.html
@@ -0,0 +1,42 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <canvas id="stage"></canvas>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/bouncing-particles.js"></script>
+    <script src="resources/bouncing-canvas-particles.js"></script>
+    <script src="resources/bouncing-canvas-shapes.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-css-images.html b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-css-images.html
new file mode 100644
index 0000000..b52a2b9
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-css-images.html
@@ -0,0 +1,46 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        img {
+            position: absolute;
+        }
+    </style>
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/bouncing-particles.js"></script>
+    <script src="resources/bouncing-css-images.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-css-shapes.html b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-css-shapes.html
new file mode 100644
index 0000000..00df8d6
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-css-shapes.html
@@ -0,0 +1,57 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        .circle {
+            position: absolute;
+            background-color: #000000;
+            border-radius: 50% 50%;
+        }
+        .rect {
+            position: absolute;
+            background-color: #000000;
+        }
+        .star {
+            -webkit-clip-path: polygon(50% 0%, 38% 38%, 0% 38%, 30% 60%, 18% 100%, 50% 75%, 82% 100%, 70% 60%, 100% 38%, 62% 38%);
+            -ms-clip-path: polygon(50% 0%, 38% 38%, 0% 38%, 30% 60%, 18% 100%, 50% 75%, 82% 100%, 70% 60%, 100% 38%, 62% 38%);
+            clip-path: polygon(50% 0%, 38% 38%, 0% 38%, 30% 60%, 18% 100%, 50% 75%, 82% 100%, 70% 60%, 100% 38%, 62% 38%);
+        }
+    </style>
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/bouncing-particles.js"></script>
+    <script src="resources/bouncing-css-shapes.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-svg-images.html b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-svg-images.html
new file mode 100644
index 0000000..351cd6b
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-svg-images.html
@@ -0,0 +1,42 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <svg id="stage"></svg>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/bouncing-particles.js"></script>
+    <script src="resources/bouncing-svg-particles.js"></script>
+    <script src="resources/bouncing-svg-images.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-svg-shapes.html b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-svg-shapes.html
new file mode 100644
index 0000000..233f649
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-svg-shapes.html
@@ -0,0 +1,42 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <svg id="stage"></svg>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/bouncing-particles.js"></script>
+    <script src="resources/bouncing-svg-particles.js"></script>
+    <script src="resources/bouncing-svg-shapes.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-tagged-images.html b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-tagged-images.html
new file mode 100644
index 0000000..fc0e2f9
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/bouncing-tagged-images.html
@@ -0,0 +1,46 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        img {
+            position: absolute;
+        }
+    </style>
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/bouncing-particles.js"></script>
+    <script src="resources/bouncing-tagged-images.js"></script>
+</head>
+<body>
+    <div id="stage"></div>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-images.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-images.js
new file mode 100644
index 0000000..c39ec4d
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-images.js
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+BouncingCanvasImage = Utilities.createSubclass(BouncingCanvasParticle,
+    function(stage)
+    {
+        BouncingCanvasParticle.call(this, stage, "image");
+        this._imageElement = stage.imageElement;
+    }, {
+
+    _draw: function()
+    {
+        this.context.save();
+            this.applyRotation();
+            this.context.drawImage(this._imageElement, 0, 0, this.size.x, this.size.y);
+        this.context.restore();
+    }
+});
+
+BouncingCanvasImagesStage = Utilities.createSubclass(BouncingCanvasParticlesStage,
+    function()
+    {
+        BouncingCanvasParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        BouncingCanvasParticlesStage.prototype.initialize.call(this, benchmark, options);
+        var imageSrc = options["imageSrc"] || "resources/yin-yang.svg";
+        this.imageElement = document.querySelector(".hidden[src=\"" + imageSrc + "\"]");
+    },
+
+    createParticle: function()
+    {
+        return new BouncingCanvasImage(this);
+    }
+});
+
+BouncingCanvasImagesBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new BouncingCanvasImagesStage(), options);
+    }
+);
+
+window.benchmarkClass = BouncingCanvasImagesBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-particles.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-particles.js
new file mode 100644
index 0000000..ce12c72
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-particles.js
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+BouncingCanvasParticle = Utilities.createSubclass(BouncingParticle,
+    function(stage, shape)
+    {
+        BouncingParticle.call(this, stage);
+        this.context = stage.context;
+        this._shape = shape;
+        this._clip = stage.clip;
+    }, {
+
+    applyRotation: function()
+    {
+        if (this._shape == "circle")
+            return;
+
+        this.context.translate(this.size.x / 2, this.size.y / 2);
+        this.context.rotate(this.rotater.degree() * Math.PI / 180);
+        this.context.translate(-this.size.x / 2, -this.size.y / 2);
+    },
+
+    applyClipping: function()
+    {
+        var clipPoints = BouncingCanvasParticle.clips[this._clip];
+        if (!clipPoints)
+            return;
+
+        this.context.beginPath();
+        clipPoints.forEach(function(point, index) {
+            var point = this.size.multiply(point);
+            if (!index)
+                this.context.moveTo(point.x, point.y);
+            else
+                this.context.lineTo(point.x, point.y);
+        }, this);
+
+        this.context.closePath();
+        this.context.clip();
+    },
+
+    _draw: function()
+    {
+        throw "Not implemented";
+    },
+
+    animate: function(timeDelta)
+    {
+        BouncingParticle.prototype.animate.call(this, timeDelta);
+        this.context.save();
+            this.context.translate(this.position.x, this.position.y);
+            this._draw();
+        this.context.restore();
+    }
+});
+
+BouncingCanvasParticle.clips = {
+    star: [
+        new Point(0.50, 0.00),
+        new Point(0.38, 0.38),
+        new Point(0.00, 0.38),
+        new Point(0.30, 0.60),
+        new Point(0.18, 1.00),
+        new Point(0.50, 0.75),
+        new Point(0.82, 1.00),
+        new Point(0.70, 0.60),
+        new Point(1.00, 0.38),
+        new Point(0.62, 0.38)
+    ]
+};
+
+BouncingCanvasParticlesStage = Utilities.createSubclass(BouncingParticlesStage,
+    function()
+    {
+        BouncingParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        BouncingParticlesStage.prototype.initialize.call(this, benchmark, options);
+        this.context = this.element.getContext("2d");
+    },
+
+    animate: function(timeDelta)
+    {
+        this.context.clearRect(0, 0, this.size.x, this.size.y);
+        this.particles.forEach(function(particle) {
+            particle.animate(timeDelta);
+        });
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-shapes.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-shapes.js
new file mode 100644
index 0000000..f3d0d81
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-shapes.js
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+BouncingCanvasShape = Utilities.createSubclass(BouncingCanvasParticle,
+    function(stage)
+    {
+        BouncingCanvasParticle.call(this, stage, stage.shape);
+        this._fill = stage.fill;
+        this._color0 = Stage.randomColor();
+        this._color1 = Stage.randomColor();
+    }, {
+
+    _applyFill: function()
+    {
+        switch (this._fill) {
+        case "gradient":
+            var gradient = this.context.createLinearGradient(0, 0, this.size.width, 0);
+            gradient.addColorStop(0, this._color0);
+            gradient.addColorStop(1, this._color1);
+            this.context.fillStyle = gradient;
+            break;
+
+        case "solid":
+        default:
+            this.context.fillStyle = this._color0;
+            break;
+        }
+    },
+
+    _drawShape: function()
+    {
+        this.context.beginPath();
+
+        switch (this._shape) {
+        case "rect":
+            this.context.rect(0, 0, this.size.width, this.size.height);
+            break;
+
+        case "circle":
+        default:
+            var center = this.size.center;
+            var radius = Math.min(this.size.x, this.size.y) / 2;
+            this.context.arc(center.x, center.y, radius, 0, Math.PI * 2, true);
+            break;
+        }
+
+        this.context.fill();
+    },
+
+    _draw: function()
+    {
+        this.context.save();
+            this._applyFill();
+            this.applyRotation();
+            this.applyClipping();
+            this._drawShape();
+        this.context.restore();
+    }
+});
+
+BouncingCanvasShapesStage = Utilities.createSubclass(BouncingCanvasParticlesStage,
+    function ()
+    {
+        BouncingCanvasParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        BouncingCanvasParticlesStage.prototype.initialize.call(this, benchmark, options);
+        this.parseShapeParameters(options);
+    },
+
+    createParticle: function()
+    {
+        return new BouncingCanvasShape(this);
+    }
+});
+
+BouncingCanvasShapesBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new BouncingCanvasShapesStage(), options);
+    }
+);
+
+window.benchmarkClass = BouncingCanvasShapesBenchmark;
+
+})();
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-css-images.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-css-images.js
new file mode 100644
index 0000000..2f3fa53
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-css-images.js
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+BouncingCssImage = Utilities.createSubclass(BouncingParticle,
+    function(stage)
+    {
+        BouncingParticle.call(this, stage);
+
+        this.element = document.createElement("img");
+        this.element.style.width = this.size.x + "px";
+        this.element.style.height = this.size.y + "px";
+        this.element.setAttribute("src", stage.imageSrc);
+
+        stage.element.appendChild(this.element);
+        this._move();
+    }, {
+
+    _move: function()
+    {
+        this.element.style.transform = "translate(" + this.position.x + "px," + this.position.y + "px) " + this.rotater.rotateZ();
+    },
+
+    animate: function(timeDelta)
+    {
+        BouncingParticle.prototype.animate.call(this, timeDelta);
+        this._move();
+    }
+});
+
+BouncingCssImagesStage = Utilities.createSubclass(BouncingParticlesStage,
+    function()
+    {
+        BouncingParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        BouncingParticlesStage.prototype.initialize.call(this, benchmark, options);
+        this.imageSrc = options["imageSrc"] || "../resources/yin-yang.svg";
+    },
+
+    createParticle: function()
+    {
+        return new BouncingCssImage(this);
+    },
+
+    particleWillBeRemoved: function(particle)
+    {
+        particle.element.remove();
+    }
+});
+
+BouncingCssImagesBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new BouncingCssImagesStage(), options);
+    }
+);
+
+window.benchmarkClass = BouncingCssImagesBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-css-shapes.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-css-shapes.js
new file mode 100644
index 0000000..19ebca0
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-css-shapes.js
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+BouncingCssShape = Utilities.createSubclass(BouncingParticle,
+    function(stage)
+    {
+        BouncingParticle.call(this, stage);
+
+        this.element = this._createSpan(stage);
+
+        switch (stage.fill) {
+        case "solid":
+        default:
+            this.element.style.backgroundColor = Stage.randomColor();
+            break;
+
+        case "gradient":
+            this.element.style.background = "linear-gradient(" + Stage.randomColor() + ", " + Stage.randomColor() + ")";
+            break;
+        }
+
+        if (stage.blend)
+            this.element.style.mixBlendMode = Stage.randomStyleMixBlendMode();
+
+        // Some browsers have not un-prefixed the css filter yet.
+        if (stage.filter)
+            Utilities.setElementPrefixedProperty(this.element, "filter", Stage.randomStyleFilter());
+
+        this._move();
+    }, {
+
+    _createSpan: function(stage)
+    {
+        var span = document.createElement("span");
+        span.className = stage.shape + " " + stage.clip;
+        span.style.width = this.size.x + "px";
+        span.style.height = this.size.y + "px";
+        stage.element.appendChild(span);
+        return span;
+    },
+
+    _move: function()
+    {
+        this.element.style.transform = "translate(" + this.position.x + "px," + this.position.y + "px)" + this.rotater.rotateZ();
+    },
+
+    animate: function(timeDelta)
+    {
+        BouncingParticle.prototype.animate.call(this, timeDelta);
+        this.rotater.next(timeDelta);
+        this._move();
+    }
+});
+
+BouncingCssShapesStage = Utilities.createSubclass(BouncingParticlesStage,
+    function()
+    {
+        BouncingParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        BouncingParticlesStage.prototype.initialize.call(this, benchmark, options);
+        this.parseShapeParameters(options);
+    },
+
+    createParticle: function()
+    {
+        return new BouncingCssShape(this);
+    },
+
+    particleWillBeRemoved: function(particle)
+    {
+        particle.element.remove();
+    }
+});
+
+BouncingCssShapesBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new BouncingCssShapesStage(), options);
+    }
+);
+
+window.benchmarkClass = BouncingCssShapesBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-particles.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-particles.js
new file mode 100644
index 0000000..393d4b22
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-particles.js
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+function BouncingParticle(stage)
+{
+    this._stageSize = stage.size;
+    this.size = stage.particleSize;
+
+    this.position = Stage.randomPosition(stage.size.subtract(stage.particleSize));
+    this._angle = Stage.randomAngle();
+    this._velocity = Stage.randomVelocity(stage.maxVelocity);
+    this.rotater = Stage.randomRotater();
+}
+
+BouncingParticle.prototype =
+{
+    get center()
+    {
+        return this.position.add(this.size.center);
+    },
+
+    animate: function(timeDelta)
+    {
+        this.position = this.position.move(this._angle, this._velocity, timeDelta);
+        this.rotater.next(timeDelta);
+
+        // If particle is going to move off right side
+        if (this.position.x + this.size.x > this._stageSize.x) {
+            // If direction is East-South, go West-South.
+            if (this._angle >= 0 && this._angle < Math.PI / 2)
+                this._angle = Math.PI - this._angle;
+            // If angle is East-North, go West-North.
+            else if (this._angle > Math.PI / 2 * 3)
+                this._angle = this._angle - (this._angle - Math.PI / 2 * 3) * 2;
+            // Make sure the particle does not go outside the stage boundaries.
+            this.position.x = this._stageSize.x - this.size.x;
+        }
+
+        // If particle is going to move off left side
+        if (this.position.x < 0) {
+            // If angle is West-South, go East-South.
+            if (this._angle > Math.PI / 2 && this._angle < Math.PI)
+                this._angle = Math.PI - this._angle;
+            // If angle is West-North, go East-North.
+            else if (this._angle > Math.PI && this._angle < Math.PI / 2 * 3)
+                this._angle = this._angle + (Math.PI / 2 * 3 - this._angle) * 2;
+            // Make sure the particle does not go outside the stage boundaries.
+            this.position.x = 0;
+        }
+
+        // If particle is going to move off bottom side
+        if (this.position.y + this.size.y > this._stageSize.y) {
+            // If direction is South, go North.
+            if (this._angle > 0 && this._angle < Math.PI)
+                this._angle = Math.PI * 2 - this._angle;
+            // Make sure the particle does not go outside the stage boundaries.
+            this.position.y = this._stageSize.y - this.size.y;
+        }
+
+        // If particle is going to move off top side
+        if (this.position.y < 0) {
+            // If direction is North, go South.
+            if (this._angle > Math.PI && this._angle < Math.PI * 2)
+                this._angle = this._angle - (this._angle - Math.PI) * 2;
+            // Make sure the particle does not go outside the stage boundaries.
+            this.position.y = 0;
+        }
+    }
+}
+
+BouncingParticlesStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+        this.particles = [];
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+        this.particleSize = new Point(parseInt(options["particleWidth"]) || 10, parseInt(options["particleHeight"]) || 10);
+        this.maxVelocity = Math.max(parseInt(options["maxVelocity"]) || 500, 100);
+    },
+
+    parseShapeParameters: function(options)
+    {
+        this.shape = options["shape"] || "circle";
+        this.fill = options["fill"] || "solid";
+        this.clip = options["clip"] || "";
+        this.blend = options["blend"] || false;
+        this.filter = options["filter"] || false;
+    },
+
+    animate: function(timeDelta)
+    {
+        this.particles.forEach(function(particle) {
+            particle.animate(timeDelta);
+        });
+    },
+
+    tune: function(count)
+    {
+        if (count == 0)
+            return;
+
+        if (count > 0) {
+            for (var i = 0; i < count; ++i)
+                this.particles.push(this.createParticle());
+            return;
+        }
+
+        count = Math.min(-count, this.particles.length);
+
+        if (typeof(this.particleWillBeRemoved) == "function") {
+            for (var i = 0; i < count; ++i)
+                this.particleWillBeRemoved(this.particles[this.particles.length - 1 - i]);
+        }
+
+        this.particles.splice(-count, count);
+    },
+
+    complexity: function()
+    {
+        return this.particles.length;
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-images.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-images.js
new file mode 100644
index 0000000..7ae9308
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-images.js
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+BouncingSvgImage = Utilities.createSubclass(BouncingSvgParticle,
+    function(stage)
+    {
+        BouncingSvgParticle.call(this, stage, "image");
+
+        var attrs = { x: 0, y: 0, width: this.size.x, height: this.size.y };
+        var xlinkAttrs = { href: stage.imageSrc };
+        this.element = Utilities.createSVGElement("image", attrs, xlinkAttrs, stage.element);
+        this._move();
+    }
+);
+
+BouncingSvgImagesStage = Utilities.createSubclass(BouncingSvgParticlesStage,
+    function()
+    {
+        BouncingSvgParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        BouncingSvgParticlesStage.prototype.initialize.call(this, benchmark, options);
+        this.imageSrc = options["imageSrc"] || "resources/yin-yang.svg";
+    },
+
+    createParticle: function()
+    {
+        return new BouncingSvgImage(this);
+    }
+});
+
+BouncingSvgImagesBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new BouncingSvgImagesStage(), options);
+    }
+);
+
+window.benchmarkClass = BouncingSvgImagesBenchmark;
+
+})();
+
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-particles.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-particles.js
new file mode 100644
index 0000000..ae10dfdd
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-particles.js
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+BouncingSvgParticle = Utilities.createSubclass(BouncingParticle,
+    function(stage, shape)
+    {
+        BouncingParticle.call(this, stage);
+        this._shape = shape;
+    }, {
+
+    _applyClipping: function(stage)
+    {
+        if (stage.clip != "star")
+            return;
+
+        stage.ensureClipStarIsCreated();
+        this.element.setAttribute("clip-path", "url(#star-clip)");
+    },
+
+    _move: function()
+    {
+        var transform = "translate(" + this.position.x + ", " + this.position.y + ")";
+        if (this._shape != "circle")
+            transform += this.rotater.rotate(this.size.center);
+        this.element.setAttribute("transform", transform);
+    },
+
+    animate: function(timeDelta)
+    {
+        BouncingParticle.prototype.animate.call(this, timeDelta);
+        this._move();
+    }
+});
+
+BouncingSvgParticlesStage = Utilities.createSubclass(BouncingParticlesStage,
+    function()
+    {
+        BouncingParticlesStage.call(this);
+    }, {
+
+    _createDefs: function()
+    {
+        return Utilities.createSVGElement("defs", {}, {}, this.element);
+    },
+
+    _ensureDefsIsCreated: function()
+    {
+        return this.element.querySelector("defs") || this._createDefs();
+    },
+
+    _createClipStar: function()
+    {
+        var attrs = { id: "star-clip", clipPathUnits: "objectBoundingBox" };
+        var clipPath  = Utilities.createSVGElement("clipPath", attrs, {}, this._ensureDefsIsCreated());
+
+        attrs = { d: "M.50,0L.38,.38L0,.38L.30,.60L.18,1L.50,.75L.82,1L.70,.60L1,.38L.62,.38z" };
+        Utilities.createSVGElement("path", attrs, {}, clipPath);
+        return clipPath;
+    },
+
+    ensureClipStarIsCreated: function()
+    {
+        return this.element.querySelector("#star-clip") || this._createClipStar();
+    },
+
+    particleWillBeRemoved: function(particle)
+    {
+        particle.element.remove();
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-shapes.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-shapes.js
new file mode 100644
index 0000000..91be977c
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-svg-shapes.js
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+BouncingSvgShape = Utilities.createSubclass(BouncingSvgParticle,
+    function(stage)
+    {
+        BouncingSvgParticle.call(this, stage, stage.shape);
+        this._fill = stage.fill;
+
+        this._createShape(stage);
+        this._applyClipping(stage);
+        this._applyFill(stage);
+
+        this._move();
+    }, {
+
+    _createShape: function(stage)
+    {
+        switch (this._shape) {
+        case "rect":
+            var attrs = { x: 0, y: 0, width: this.size.x, height: this.size.y };
+            this.element = Utilities.createSVGElement("rect", attrs, {}, stage.element);
+            break;
+
+        case "circle":
+        default:
+            var attrs = { cx: this.size.x / 2, cy: this.size.y / 2, r: Math.min(this.size.x, this.size.y) / 2 };
+            this.element = Utilities.createSVGElement("circle", attrs, {}, stage.element);
+            break;
+        }
+    },
+
+    _applyFill: function(stage)
+    {
+        switch (this._fill) {
+        case "gradient":
+            var gradient = stage.createGradient(2);
+            this.element.setAttribute("fill", "url(#" + gradient.getAttribute("id") + ")");
+            break;
+
+        case "solid":
+        default:
+            this.element.setAttribute("fill", Stage.randomColor());
+            break;
+        }
+    }
+});
+
+BouncingSvgShapesStage = Utilities.createSubclass(BouncingSvgParticlesStage,
+    function()
+    {
+        BouncingSvgParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        BouncingSvgParticlesStage.prototype.initialize.call(this, benchmark, options);
+        this.parseShapeParameters(options);
+        this._gradientsCount = 0;
+    },
+
+    createGradient: function(stops)
+    {
+        var attrs = { id: "gradient-" + ++this._gradientsCount };
+        var gradient = Utilities.createSVGElement("linearGradient", attrs, {}, this._ensureDefsIsCreated());
+
+        for (var i = 0; i < stops; ++i) {
+            attrs = { offset: i * 100 / (stops - 1) + "%", 'stop-color': Stage.randomColor() };
+            Utilities.createSVGElement("stop", attrs, {}, gradient);
+        }
+
+        return gradient;
+    },
+
+    createParticle: function()
+    {
+        return new BouncingSvgShape(this);
+    },
+
+    particleWillBeRemoved: function(particle)
+    {
+        BouncingSvgParticlesStage.prototype.particleWillBeRemoved.call(this, particle);
+
+        var fill = particle.element.getAttribute("fill");
+        if (fill.indexOf("url(#") != 0)
+            return;
+
+        var gradient = this.element.querySelector(fill.substring(4, fill.length - 1));
+        this._ensureDefsIsCreated().removeChild(gradient);
+    }
+});
+
+BouncingSvgShapesBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new BouncingSvgShapesStage(), options);
+    }
+);
+
+window.benchmarkClass = BouncingSvgShapesBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-tagged-images.js b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-tagged-images.js
new file mode 100644
index 0000000..d8be60f
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/bouncing-tagged-images.js
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+BouncingTaggedImage = Utilities.createSubclass(BouncingParticle,
+    function(stage)
+    {
+        BouncingParticle.call(this, stage);
+
+        this.element = document.createElement("img");
+        this.element.style.width = this.size.x + "px";
+        this.element.style.height = this.size.y + "px";
+        this.element.setAttribute("src", Stage.randomElementInArray(stage.images).src);
+
+        stage.element.appendChild(this.element);
+        this._move();
+    }, {
+
+    _move: function()
+    {
+        this.element.style.transform = "translate(" + this.position.x + "px," + this.position.y + "px) " + this.rotater.rotateZ();
+    },
+
+    animate: function(timeDelta)
+    {
+        BouncingParticle.prototype.animate.call(this, timeDelta);
+        this._move();
+    }
+});
+
+BouncingTaggedImagesStage = Utilities.createSubclass(BouncingParticlesStage,
+
+    function()
+    {
+        BouncingParticlesStage.call(this);
+    }, {
+
+    imageSrcs: [
+        "image1",
+        "image2",
+        "image3",
+        "image4",
+        "image5",
+    ],
+    images: [],
+
+    initialize: function(benchmark, options)
+    {
+        BouncingParticlesStage.prototype.initialize.call(this, benchmark, options);
+
+        var lastPromise;
+        var images = this.images;
+        this.imageSrcs.forEach(function(imageSrc) {
+            var promise = this._loadImage("resources/" + imageSrc + ".jpg");
+            if (!lastPromise)
+                lastPromise = promise;
+            else {
+                lastPromise = lastPromise.then(function(img) {
+                    images.push(img);
+                    return promise;
+                });
+            }
+        }, this);
+
+        lastPromise.then(function(img) {
+            images.push(img);
+            benchmark.readyPromise.resolve();
+        });
+    },
+
+    _loadImage: function(src) {
+        var img = new Image;
+        var promise = new SimplePromise;
+
+        img.onload = function(e) {
+            promise.resolve(e.target);
+        };
+
+        img.src = src;
+        return promise;
+    },
+
+    createParticle: function()
+    {
+        return new BouncingTaggedImage(this);
+    },
+
+    particleWillBeRemoved: function(particle)
+    {
+        particle.element.remove();
+    }
+});
+
+BouncingTaggedImagesBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new BouncingTaggedImagesStage(), options);
+    }, {
+
+    waitUntilReady: function() {
+        this.readyPromise = new SimplePromise;
+        return this.readyPromise;
+    }
+});
+
+window.benchmarkClass = BouncingTaggedImagesBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image1.jpg b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image1.jpg
new file mode 100644
index 0000000..ea7a4c13
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image1.jpg
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image2.jpg b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image2.jpg
new file mode 100644
index 0000000..697272d
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image2.jpg
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image3.jpg b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image3.jpg
new file mode 100644
index 0000000..6e5964e
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image3.jpg
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image4.jpg b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image4.jpg
new file mode 100644
index 0000000..806f548
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image4.jpg
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image5.jpg b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image5.jpg
new file mode 100644
index 0000000..d7971f6
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/bouncing-particles/resources/image5.jpg
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/compositing-transforms.html b/third_party/blink/perf_tests/MotionMark/tests/dom/compositing-transforms.html
new file mode 100644
index 0000000..f94d299
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/compositing-transforms.html
@@ -0,0 +1,48 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        img {
+            position: absolute;
+            width: 80px;
+            height: 80px;
+        }
+    </style>
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="../bouncing-particles/resources/bouncing-particles.js"></script>
+    <script src="resources/compositing-transforms.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/focus.html b/third_party/blink/perf_tests/MotionMark/tests/dom/focus.html
new file mode 100644
index 0000000..cef614e
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/focus.html
@@ -0,0 +1,75 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+
+    #stage {
+        background-color: #201A1F;
+        z-index: -10000;
+    }
+
+    #stage > div {
+        position: absolute;
+        overflow: hidden;
+    }
+    #stage div div {
+        position: absolute;
+        background-color: #DEDADD;
+        border-radius: 50%;
+    }
+
+    #center-text {
+        font-size: 90%;
+        transform: translate3d(-50%, -50%, 0);
+    }
+
+    #center-text span {
+        position: absolute;
+        color: #201A1F;
+        font-weight: 400;
+        font-size: 2em;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+    }
+
+    </style>
+</head>
+<body>
+    <div id="stage">
+        <div id="center-text"><div><span>focus</span></div></div>
+    </div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/focus.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/leaves.html b/third_party/blink/perf_tests/MotionMark/tests/dom/leaves.html
new file mode 100644
index 0000000..3349268
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/leaves.html
@@ -0,0 +1,50 @@
+<!--
+  Copyright (C) 2015-2018 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        #stage {
+            background-color: #33282B;
+        }
+        #stage img {
+            position: absolute;
+        }
+    </style>
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="../master/resources/particles.js"></script> <!-- nocheck -->
+    <script src="../master/resources/leaves.js"></script> <!-- nocheck -->
+    <script src="resources/leaves.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/multiply.html b/third_party/blink/perf_tests/MotionMark/tests/dom/multiply.html
new file mode 100644
index 0000000..def555a
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/multiply.html
@@ -0,0 +1,78 @@
+<!--
+  Copyright (C) 2018 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+
+    #stage {
+        background-color: #222;
+    }
+
+    #stage div {
+        position: absolute;
+    }
+
+    #stage .div-0 {
+        border-top-right-radius: 100%;
+    }
+
+    #stage .div-1 {
+        border-top-left-radius: 100%;
+    }
+
+    #stage .div-2 {
+        border-bottom-left-radius: 100%;
+    }
+
+    #stage .div-3 {
+        border-bottom-right-radius: 100%;
+    }
+
+    #stage .div-4 {
+        border-bottom-left-radius: 100%;
+        border-top-right-radius: 100%;
+    }
+
+    #stage .div-5 {
+        border-bottom-right-radius: 100%;
+        border-top-left-radius: 100%;
+    }
+    </style>
+</head>
+<body>
+    <div id="stage">
+    </div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="../master/resources/multiply.js"></script> <!-- nocheck -->
+    <script src="resources/multiply.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/particles.html b/third_party/blink/perf_tests/MotionMark/tests/dom/particles.html
new file mode 100644
index 0000000..c1bb8783
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/particles.html
@@ -0,0 +1,48 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        #stage div {
+            position: absolute;
+            -webkit-mask-image: url(../resources/star.svg);
+            mask: url(../resources/star.svg#star-mask);
+        }
+    </style>
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="../master/resources/particles.js"></script> <!-- nocheck -->
+    <script src="resources/dom-particles.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/resources/compositing-transforms.js b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/compositing-transforms.js
new file mode 100644
index 0000000..c92fadfe
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/compositing-transforms.js
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+BouncingCompositedImage = Utilities.createSubclass(BouncingParticle,
+    function(stage)
+    {
+        BouncingParticle.call(this, stage);
+
+        this.element = document.createElement("img");
+        this.element.style.width = this.size.x + "px";
+        this.element.style.height = this.size.y + "px";
+        this.element.setAttribute("src", stage.imageSrc);
+
+        if (stage.useFilters)
+            this.element.style.filter = "hue-rotate(" + Stage.randomAngle() + "rad)";
+
+        stage.element.appendChild(this.element);
+        this._move();
+    }, {
+
+    _move: function()
+    {
+        this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px, 0) " + this.rotater.rotateZ();
+    },
+
+    animate: function(timeDelta)
+    {
+        BouncingParticle.prototype.animate.call(this, timeDelta);
+        this._move();
+    }
+});
+
+CompositingTransformsStage = Utilities.createSubclass(BouncingParticlesStage,
+    function()
+    {
+        BouncingParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        BouncingParticlesStage.prototype.initialize.call(this, benchmark, options);
+
+        this.imageSrc = options["imageSrc"] || "../resources/yin-yang.svg";
+        this.useFilters = options["filters"] == "yes";
+    },
+
+    createParticle: function()
+    {
+        return new BouncingCompositedImage(this);
+    },
+
+    particleWillBeRemoved: function(particle)
+    {
+        particle.element.remove();
+    }
+});
+
+CompositedTransformsBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new CompositingTransformsStage(), options);
+    }
+);
+
+window.benchmarkClass = CompositedTransformsBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/resources/dom-particles.js b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/dom-particles.js
new file mode 100644
index 0000000..985de3c9
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/dom-particles.js
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+DOMParticle = Utilities.createSubclass(Particle,
+    function(stage)
+    {
+        this.element = document.createElement("div");
+        stage.element.appendChild(this.element);
+
+        Particle.call(this, stage);
+    }, {
+
+    reset: function()
+    {
+        Particle.prototype.reset.call(this);
+
+        this.position = Stage.randomElementInArray(this.stage.emitLocation);
+
+        var angle = Stage.randomInt(0, this.stage.emitSteps) / this.stage.emitSteps * Math.PI * 2 + Stage.dateCounterValue(100) * this.stage.emissionSpin;
+        this.velocity = new Point(Math.sin(angle), Math.cos(angle))
+            .multiply(Stage.random(.5, 2.5));
+
+        this.element.style.width = this.size.x + "px";
+        this.element.style.height = this.size.y + "px";
+        this.stage.colorOffset = (this.stage.colorOffset + 1) % 360;
+        this.element.style.backgroundColor = "hsl(" + this.stage.colorOffset + ", 70%, 45%)";
+    },
+
+    move: function()
+    {
+        this.element.style.transform = "translate(" + this.position.x + "px, " + this.position.y + "px)" + this.rotater.rotateZ();
+    }
+});
+
+DOMParticleStage = Utilities.createSubclass(ParticlesStage,
+    function()
+    {
+        ParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark)
+    {
+        ParticlesStage.prototype.initialize.call(this, benchmark);
+        this.emissionSpin = Stage.random(0, 3);
+        this.emitSteps = Stage.randomInt(4, 6);
+        this.emitLocation = [
+            new Point(this.size.x * .25, this.size.y * .333),
+            new Point(this.size.x * .5, this.size.y * .25),
+            new Point(this.size.x * .75, this.size.y * .333)
+        ];
+        this.colorOffset = Stage.randomInt(0, 359);
+    },
+
+    createParticle: function()
+    {
+        return new DOMParticle(this);
+    },
+
+    willRemoveParticle: function(particle)
+    {
+        particle.element.remove();
+    }
+});
+
+DOMParticleBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new DOMParticleStage(), options);
+    }
+);
+
+window.benchmarkClass = DOMParticleBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/resources/focus.js b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/focus.js
new file mode 100644
index 0000000..c268d98
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/focus.js
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+var maxVerticalOffset = 50;
+var minimumDiameter = 30;
+var centerDiameter = 90;
+var sizeVariance = 60;
+var travelDistance = 50;
+
+var opacityMultiplier = 30;
+
+var FocusElement = Utilities.createClass(
+    function(stage)
+    {
+        var size = minimumDiameter + sizeVariance;
+
+        // Size and blurring are a function of depth.
+        this._depth = Pseudo.random();
+        var distance = Utilities.lerp(this._depth, 0, sizeVariance);
+        size -= distance;
+
+        var top = Stage.random(0, stage.size.height - size) - stage.maxBlurValue * 3;
+        var left = Stage.random(0, stage.size.width - size) - stage.maxBlurValue * 3;
+
+        this.container = document.createElement('div');
+        this.container.style.width = (size + stage.maxBlurValue * 6) + "px";
+        this.container.style.height = (size + stage.maxBlurValue * 6) + "px";
+        this.container.style.top = top + "px";
+        this.container.style.left = left + "px";
+        this.container.style.zIndex = Math.round((1 - this._depth) * 10);
+
+        this.particle = Utilities.createElement("div", {}, this.container);
+        this.particle.style.width = size + "px";
+        this.particle.style.height = size + "px";
+        this.particle.style.top = (stage.maxBlurValue * 3) + "px";
+        this.particle.style.left = (stage.maxBlurValue * 3) + "px";
+
+        var depthMultiplier = Utilities.lerp(1 - this._depth, 0.8, 1);
+        this._sinMultiplier = Pseudo.random() * Stage.randomSign() * depthMultiplier * travelDistance;
+        this._cosMultiplier = Pseudo.random() * Stage.randomSign() * depthMultiplier * travelDistance;
+    }, {
+
+    hide: function()
+    {
+        this.container.style.display = "none";
+    },
+
+    show: function()
+    {
+        this.container.style.display = "block";
+    },
+
+    animate: function(stage, sinFactor, cosFactor)
+    {
+        var top = sinFactor * this._sinMultiplier;
+        var left = cosFactor * this._cosMultiplier;
+
+        Utilities.setElementPrefixedProperty(this.container, "filter", "blur(" + stage.getBlurValue(this._depth) + "px) opacity(" + stage.getOpacityValue(this._depth) + "%)");
+        this.container.style.transform = "translate3d(" + left + "%, " + top + "%, 0)";
+    }
+});
+
+var FocusStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+    }, {
+
+    movementDuration: 2500,
+    focusDuration: 1000,
+
+    centerObjectDepth: 0.0,
+
+    minBlurValue: 1.5,
+    maxBlurValue: 15,
+    maxCenterObjectBlurValue: 5,
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+
+        this._testElements = [];
+        this._focalPoint = 0.5;
+        this._offsetIndex = 0;
+
+        this._centerElement = document.getElementById("center-text");
+        this._centerElement.style.width = (centerDiameter + this.maxCenterObjectBlurValue * 6) + "px";
+        this._centerElement.style.height = (centerDiameter + this.maxCenterObjectBlurValue * 6) + "px";
+        this._centerElement.style.zIndex = Math.round(10 * this.centerObjectDepth);
+
+        var particle = document.querySelector("#center-text div");
+        particle.style.width = centerDiameter + "px";
+        particle.style.height = centerDiameter + "px";
+        particle.style.top = (this.maxCenterObjectBlurValue * 3) + "px";
+        particle.style.left = (this.maxCenterObjectBlurValue * 3) + "px";
+
+        var blur = this.getBlurValue(this.centerObjectDepth, true);
+        Utilities.setElementPrefixedProperty(this._centerElement, "filter", "blur(" + blur + "px)");
+    },
+
+    complexity: function()
+    {
+        return 1 + this._offsetIndex;
+    },
+
+    tune: function(count)
+    {
+        if (count == 0)
+            return;
+
+        if (count < 0) {
+            this._offsetIndex = Math.max(0, this._offsetIndex + count);
+            for (var i = this._offsetIndex; i < this._testElements.length; ++i)
+                this._testElements[i].hide();
+            return;
+        }
+
+        var newIndex = this._offsetIndex + count;
+        for (var i = this._testElements.length; i < newIndex; ++i) {
+            var obj = new FocusElement(this);
+            this._testElements.push(obj);
+            this.element.appendChild(obj.container);
+        }
+        for (var i = this._offsetIndex; i < newIndex; ++i)
+            this._testElements[i].show();
+        this._offsetIndex = newIndex;
+    },
+
+    animate: function()
+    {
+        var time = this._benchmark.timestamp;
+        var sinFactor = Math.sin(time / this.movementDuration);
+        var cosFactor = Math.cos(time / this.movementDuration);
+
+        var focusProgress = 0.5 + 0.5 * Math.sin(time / this.focusDuration);
+        this._focalPoint = focusProgress;
+
+        Utilities.setElementPrefixedProperty(this._centerElement, "filter", "blur(" + this.getBlurValue(this.centerObjectDepth, true) + "px)");
+
+        for (var i = 0; i < this._offsetIndex; ++i)
+            this._testElements[i].animate(this, sinFactor, cosFactor);
+    },
+
+    getBlurValue: function(depth, isCenter)
+    {
+        if (isCenter)
+            return 1 + Math.abs(depth - this._focalPoint) * (this.maxCenterObjectBlurValue - 1);
+
+        return Utilities.lerp(Math.abs(depth - this._focalPoint), this.minBlurValue, this.maxBlurValue);
+    },
+
+    getOpacityValue: function(depth)
+    {
+        return Math.max(1, opacityMultiplier * (1 - Math.abs(depth - this._focalPoint)));
+    },
+});
+
+var FocusBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new FocusStage(), options);
+    }
+);
+
+window.benchmarkClass = FocusBenchmark;
+
+}());
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/resources/leaves.js b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/leaves.js
new file mode 100644
index 0000000..a0bb633
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/leaves.js
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015-2018 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.
+ */
+(function() {
+
+var SuperLeaf = window.Leaf;
+var SimpleLeaf = Utilities.createSubclass(SuperLeaf,
+    function(stage)
+    {
+        SuperLeaf.call(this, stage);
+    }, {
+
+    sizeMinimum: 25,
+    sizeRange: 0,
+    usesOpacity: false,
+
+    move: function()
+    {
+        this.element.style.transform = "translate(" + this._position.x + "px, " + this._position.y + "px)" + this.rotater.rotateZ();
+    }
+});
+
+var ScaleLeaf = Utilities.createSubclass(SuperLeaf,
+    function(stage)
+    {
+        SuperLeaf.call(this, stage);
+    }, {
+
+    sizeMinimum: 20,
+    sizeRange: 30,
+    usesOpacity: false,
+
+    move: function()
+    {
+        this.element.style.transform = "translate(" + this._position.x + "px, " + this._position.y + "px)" + this.rotater.rotateZ();
+    }
+});
+
+var OpacityLeaf = Utilities.createSubclass(SuperLeaf,
+    function(stage)
+    {
+        SuperLeaf.call(this, stage);
+    }, {
+
+    sizeMinimum: 25,
+    sizeRange: 0,
+    usesOpacity: true,
+
+    move: function()
+    {
+        this.element.style.transform = "translate(" + this._position.x + "px, " + this._position.y + "px)" + this.rotater.rotateZ();
+        this.element.style.opacity = this._opacity;
+    }
+});
+
+
+var LeavesBenchmark = window.benchmarkClass;
+var LeavesDerivedBenchmark = Utilities.createSubclass(LeavesBenchmark,
+    function(options)
+    {
+        switch (options["style"]) {
+        case "simple":
+            window.Leaf = SimpleLeaf;
+            break;
+        case "scale":
+            window.Leaf = ScaleLeaf;
+            break;
+        case "opacity":
+            window.Leaf = OpacityLeaf;
+            break;
+        }
+        LeavesBenchmark.call(this, options);
+    }
+);
+
+window.benchmarkClass = LeavesDerivedBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/dom/resources/multiply.js b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/multiply.js
new file mode 100644
index 0000000..322a3b4
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/dom/resources/multiply.js
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+(function() {
+
+var MultiplyBenchmark = window.benchmarkClass;
+var MultiplyDerivedBenchmark = Utilities.createSubclass(MultiplyBenchmark,
+    function(options)
+    {
+        switch (options["style"]) {
+        case "opacity":
+            options.visibleCSS = [["opacity", 0, 1]];
+            break;
+        case "display":
+            options.visibleCSS = [["display", "none", "block"]];
+            break;
+        case "visibility":
+            options.visibleCSS = [["visibility", "hidden", "visible"]];
+            break;
+        }
+        MultiplyBenchmark.call(this, options);
+    }
+);
+
+window.benchmarkClass = MultiplyDerivedBenchmark;
+
+})();
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/canvas-stage.html b/third_party/blink/perf_tests/MotionMark/tests/master/canvas-stage.html
new file mode 100644
index 0000000..9054192
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/canvas-stage.html
@@ -0,0 +1,41 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <canvas id="stage"></canvas>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/canvas-stage.js"></script>
+    <script src="resources/canvas-tests.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/design.html b/third_party/blink/perf_tests/MotionMark/tests/master/design.html
new file mode 100644
index 0000000..a8246a30
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/design.html
@@ -0,0 +1,106 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+
+        #stage {
+            font-family: Helvetica;
+            font-size: 52px;
+            background-color: #313534;
+        }
+        @media (max-width: 900px) {
+            #stage {
+                font-size: 40px;
+            }
+        }
+        @media (max-width: 568px) {
+            #stage {
+                font-size: 28px;
+            }
+        }
+
+        #stage div {
+            width: 80%;
+            height: 90%;
+            position: absolute;
+            text-align: center;
+        }
+        #template {
+            color: #FCFCFC;
+        }
+        table {
+            position: relative;
+            width: 100%;
+            height: 100%;
+        }
+        td {
+            width: 33%;
+        }
+        tr {
+            height: 20%;
+        }
+    </style>
+</head>
+<body>
+    <div id="stage">
+        <div id="template">
+            <table>
+                <tbody>
+                    <tr>
+                        <td>σχέδιο</td>
+                        <td>设计</td>
+                        <td>suunnittelu</td>
+                    </tr>
+                    <tr>
+                        <td>design</td>
+                        <td>дизайн</td>
+                        <td class="rtl">تصميم</td>
+                    </tr>
+                    <tr>
+                        <td>디자인</td>
+                        <td>conception</td>
+                        <td>デザイン</td>
+                    </tr>
+                    <tr>
+                        <td>konstruktion</td>
+                        <td class="rtl">עיצוב</td>
+                        <td>diseño</td>
+                    </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/design.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/focus.html b/third_party/blink/perf_tests/MotionMark/tests/master/focus.html
new file mode 100644
index 0000000..ab545b7
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/focus.html
@@ -0,0 +1,53 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+
+    #stage {
+        background-color: #201A1F;
+    }
+
+    #stage div {
+        position: absolute;
+        background-color: #DEDADD;
+        border-radius: 50%;
+        display: none;
+    }
+    </style>
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/focus.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/image-data.html b/third_party/blink/perf_tests/MotionMark/tests/master/image-data.html
new file mode 100644
index 0000000..ef2e429
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/image-data.html
@@ -0,0 +1,52 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+
+    #stage {
+        background-color: #000;
+    }
+
+    #stage canvas {
+        position: absolute;
+        transform: translateZ(0);
+    }
+
+    </style>
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/image-data.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/leaves.html b/third_party/blink/perf_tests/MotionMark/tests/master/leaves.html
new file mode 100644
index 0000000..7d9bd3f
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/leaves.html
@@ -0,0 +1,49 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style>
+        #stage {
+            background-color: #23282B;
+        }
+        #stage img {
+            position: absolute;
+        }
+    </style>
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/particles.js"></script>
+    <script src="resources/leaves.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/multiply.html b/third_party/blink/perf_tests/MotionMark/tests/master/multiply.html
new file mode 100644
index 0000000..4549951
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/multiply.html
@@ -0,0 +1,77 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+
+    #stage {
+        background-color: #000;
+    }
+
+    #stage div {
+        position: absolute;
+    }
+
+    #stage .div-0 {
+        border-top-right-radius: 100%;
+    }
+
+    #stage .div-1 {
+        border-top-left-radius: 100%;
+    }
+
+    #stage .div-2 {
+        border-bottom-left-radius: 100%;
+    }
+
+    #stage .div-3 {
+        border-bottom-right-radius: 100%;
+    }
+
+    #stage .div-4 {
+        border-bottom-left-radius: 100%;
+        border-top-right-radius: 100%;
+    }
+
+    #stage .div-5 {
+        border-bottom-right-radius: 100%;
+        border-top-left-radius: 100%;
+    }
+    </style>
+</head>
+<body>
+    <div id="stage">
+    </div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/multiply.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/canvas-stage.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/canvas-stage.js
new file mode 100644
index 0000000..57626bc
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/canvas-stage.js
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+SimpleCanvasStage = Utilities.createSubclass(Stage,
+    function(canvasObject)
+    {
+        Stage.call(this);
+        this._canvasObject = canvasObject;
+        this.objects = [];
+        this.offsetIndex = 0;
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+        this.context = this.element.getContext("2d");
+    },
+
+    tune: function(count)
+    {
+        if (count == 0)
+            return;
+
+        if (count < 0) {
+            this.offsetIndex = Math.min(this.offsetIndex - count, this.objects.length);
+            return;
+        }
+
+        var newIndex = this.offsetIndex - count;
+        if (newIndex < 0) {
+            this.offsetIndex = 0;
+            newIndex = -newIndex;
+            for (var i = 0; i < newIndex; ++i) {
+                if (this._canvasObject.constructor === Array)
+                    this.objects.push(new (Stage.randomElementInArray(this._canvasObject))(this));
+                else
+                    this.objects.push(new this._canvasObject(this));
+            }
+        } else
+            this.offsetIndex = newIndex;
+    },
+
+    animate: function()
+    {
+        var context = this.context;
+        context.clearRect(0, 0, this.size.x, this.size.y);
+        for (var i = this.offsetIndex, length = this.objects.length; i < length; ++i)
+            this.objects[i].draw(context);
+    },
+
+    complexity: function()
+    {
+        return this.objects.length - this.offsetIndex;
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/canvas-tests.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/canvas-tests.js
new file mode 100644
index 0000000..015cf8a
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/canvas-tests.js
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+// === PAINT OBJECTS ===
+
+CanvasLineSegment = Utilities.createClass(
+    function(stage)
+    {
+        var circle = Stage.randomInt(0, 3);
+        this._color = ["#e01040", "#10c030", "#744CBA", "#e05010"][circle];
+        this._lineWidth = Math.pow(Pseudo.random(), 12) * 20 + 3;
+        this._omega = Pseudo.random() * 3 + 0.2;
+        var theta = Stage.randomAngle();
+        this._cosTheta = Math.cos(theta);
+        this._sinTheta = Math.sin(theta);
+        this._startX = stage.circleRadius * this._cosTheta + stage.circleX[circle];
+        this._startY = stage.circleRadius * this._sinTheta + stage.circleY[circle];
+        this._length = Math.pow(Pseudo.random(), 8) * stage.lineLengthMaximum + stage.lineMinimum;
+        this._segmentDirection = Pseudo.random() > 0.5 ? -1 : 1;
+    }, {
+
+    draw: function(context)
+    {
+        context.strokeStyle = this._color;
+        context.lineWidth = this._lineWidth;
+
+        this._length += Math.sin(Stage.dateCounterValue(100) * this._omega);
+
+        context.beginPath();
+        context.moveTo(this._startX, this._startY);
+        context.lineTo(this._startX + this._segmentDirection * this._length * this._cosTheta,
+                       this._startY + this._segmentDirection * this._length * this._sinTheta);
+        context.stroke();
+    }
+});
+
+CanvasArc = Utilities.createClass(
+    function(stage)
+    {
+        var maxX = 6, maxY = 3;
+        var distanceX = stage.size.x / maxX;
+        var distanceY = stage.size.y / (maxY + 1);
+        var randY = Stage.randomInt(0, maxY);
+        var randX = Stage.randomInt(0, maxX - 1 * (randY % 2));
+
+        this._point = new Point(distanceX * (randX + (randY % 2) / 2), distanceY * (randY + .5));
+
+        this._radius = 20 + Math.pow(Pseudo.random(), 5) * (Math.min(distanceX, distanceY) / 1.8);
+        this._startAngle = Stage.randomAngle();
+        this._endAngle = Stage.randomAngle();
+        this._omega = (Pseudo.random() - 0.5) * 0.3;
+        this._counterclockwise = Stage.randomBool();
+        var colors = ["#101010", "#808080", "#c0c0c0"];
+        colors.push(["#e01040", "#10c030", "#e05010"][(randX + Math.ceil(randY / 2)) % 3]);
+        this._color = colors[Math.floor(Pseudo.random() * colors.length)];
+        this._lineWidth = 1 + Math.pow(Pseudo.random(), 5) * 30;
+        this._doStroke = Stage.randomInt(0, 3) != 0;
+    }, {
+
+    draw: function(context)
+    {
+        this._startAngle += this._omega;
+        this._endAngle += this._omega / 2;
+
+        if (this._doStroke) {
+            context.strokeStyle = this._color;
+            context.lineWidth = this._lineWidth;
+            context.beginPath();
+            context.arc(this._point.x, this._point.y, this._radius, this._startAngle, this._endAngle, this._counterclockwise);
+            context.stroke();
+        } else {
+            context.fillStyle = this._color;
+            context.beginPath();
+            context.lineTo(this._point.x, this._point.y);
+            context.arc(this._point.x, this._point.y, this._radius, this._startAngle, this._endAngle, this._counterclockwise);
+            context.lineTo(this._point.x, this._point.y);
+            context.fill();
+        }
+    }
+});
+
+// CanvasLinePoint contains no draw() method since it is either moveTo or
+// lineTo depending on its index.
+CanvasLinePoint = Utilities.createClass(
+    function(stage)
+    {
+        var colors = ["#101010", "#808080", "#c0c0c0", "#101010", "#808080", "#c0c0c0", "#e01040"];
+        this.color = Stage.randomElementInArray(colors);
+        this.width = Math.pow(Pseudo.random(), 5) * 20 + 1;
+        this.isSplit = Pseudo.random() > 0.95;
+
+        var nextPoint;
+        if (stage.objects.length)
+            nextPoint = this.randomPoint(stage, stage.objects[stage.objects.length - 1].coordinate);
+        else
+            nextPoint = this.randomPoint(stage, this.gridSize.center);
+        this.point = nextPoint.point;
+        this.coordinate = nextPoint.coordinate;
+    }, {
+
+    gridSize: new Point(80, 40),
+    offsets: [
+        new Point(-4, 0),
+        new Point(2, 0),
+        new Point(1, -2),
+        new Point(1, 2),
+    ],
+
+    randomPoint: function(stage, startCoordinate)
+    {
+        var coordinate = startCoordinate;
+        if (stage.objects.length) {
+            var offset = Stage.randomElementInArray(this.offsets);
+
+            coordinate = coordinate.add(offset);
+            if (coordinate.x < 0 || coordinate.x > this.gridSize.width)
+                coordinate.x -= offset.x * 2;
+            if (coordinate.y < 0 || coordinate.y > this.gridSize.height)
+                coordinate.y -= offset.y * 2;
+        }
+
+        var x = (coordinate.x + .5) * stage.size.x / (this.gridSize.width + 1);
+        var y = (coordinate.y + .5) * stage.size.y / (this.gridSize.height + 1);
+        return {
+            point: new Point(x, y),
+            coordinate: coordinate
+        };
+    },
+
+    draw: function(context)
+    {
+        context.lineTo(this.point.x, this.point.y);
+    }
+});
+
+CanvasQuadraticSegment = Utilities.createSubclass(CanvasLinePoint,
+    function(stage)
+    {
+        CanvasLinePoint.call(this, stage);
+        // The chosen point is instead the control point.
+        this._point2 = this.point;
+
+        // Get another random point for the actual end point of the segment.
+        var nextPoint = this.randomPoint(stage, this.coordinate);
+        this.point = nextPoint.point;
+        this.coordinate = nextPoint.coordinate;
+    }, {
+
+    draw: function(context)
+    {
+        context.quadraticCurveTo(this._point2.x, this._point2.y, this.point.x, this.point.y);
+    }
+});
+
+CanvasBezierSegment = Utilities.createSubclass(CanvasLinePoint,
+    function(stage)
+    {
+        CanvasLinePoint.call(this, stage);
+        // The chosen point is instead the first control point.
+        this._point2 = this.point;
+        var nextPoint = this.randomPoint(stage, this.coordinate);
+        this._point3 = nextPoint.point;
+
+        nextPoint = this.randomPoint(stage, nextPoint.coordinate);
+        this.point = nextPoint.point;
+        this.coordinate = nextPoint.coordinate;
+    }, {
+
+    draw: function(context, off)
+    {
+        context.bezierCurveTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y, this.point.x, this.point.y);
+    }
+});
+
+// === STAGES ===
+
+CanvasLineSegmentStage = Utilities.createSubclass(SimpleCanvasStage,
+    function()
+    {
+        SimpleCanvasStage.call(this, CanvasLineSegment);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        SimpleCanvasStage.prototype.initialize.call(this, benchmark, options);
+        this.context.lineCap = options["lineCap"] || "butt";
+        this.lineMinimum = 20;
+        this.lineLengthMaximum = 40;
+        this.circleRadius = this.size.x / 8 - .4 * (this.lineMinimum + this.lineLengthMaximum);
+        this.circleX = [
+            5.5 / 32 * this.size.x,
+            12.5 / 32 * this.size.x,
+            19.5 / 32 * this.size.x,
+            26.5 / 32 * this.size.x,
+        ];
+        this.circleY = [
+            2.1 / 3 * this.size.y,
+            0.9 / 3 * this.size.y,
+            2.1 / 3 * this.size.y,
+            0.9 / 3 * this.size.y
+        ];
+        this.halfSize = this.size.multiply(.5);
+        this.twoFifthsSizeX = this.size.x * .4;
+    },
+
+    animate: function()
+    {
+        var context = this.context;
+        context.clearRect(0, 0, this.size.x, this.size.y);
+
+        var angle = Stage.dateFractionalValue(3000) * Math.PI * 2;
+        var dx = this.twoFifthsSizeX * Math.cos(angle);
+        var dy = this.twoFifthsSizeX * Math.sin(angle);
+
+        var gradient = context.createLinearGradient(this.halfSize.x + dx, this.halfSize.y + dy, this.halfSize.x - dx, this.halfSize.y - dy);
+        var gradientStep = 0.5 + 0.5 * Math.sin(Stage.dateFractionalValue(5000) * Math.PI * 2);
+        var colorStopStep = Utilities.lerp(gradientStep, -.1, .1);
+        var brightnessStep = Math.round(Utilities.lerp(gradientStep, 32, 64));
+        var color1Step = "rgba(" + brightnessStep + "," + brightnessStep + "," + (brightnessStep << 1) + ",.4)";
+        var color2Step = "rgba(" + (brightnessStep << 1) + "," + (brightnessStep << 1) + "," + brightnessStep + ",.4)";
+        gradient.addColorStop(0, color1Step);
+        gradient.addColorStop(.2 + colorStopStep, color1Step);
+        gradient.addColorStop(.8 - colorStopStep, color2Step);
+        gradient.addColorStop(1, color2Step);
+
+        context.lineWidth = 15;
+        for(var i = 0; i < 4; i++) {
+            context.strokeStyle = ["#e01040", "#10c030", "#744CBA", "#e05010"][i];
+            context.fillStyle = ["#70051d", "#016112", "#2F0C6E", "#702701"][i];
+            context.beginPath();
+                context.arc(this.circleX[i], this.circleY[i], this.circleRadius, 0, Math.PI*2);
+                context.stroke();
+                context.fill();
+            context.fillStyle = gradient;
+                context.fill();
+        }
+
+        for (var i = this.offsetIndex, length = this.objects.length; i < length; ++i)
+            this.objects[i].draw(context);
+    }
+});
+
+CanvasLinePathStage = Utilities.createSubclass(SimpleCanvasStage,
+    function()
+    {
+        SimpleCanvasStage.call(this, [CanvasLinePoint, CanvasLinePoint, CanvasQuadraticSegment, CanvasBezierSegment]);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        SimpleCanvasStage.prototype.initialize.call(this, benchmark, options);
+        this.context.lineJoin = options["lineJoin"] || "bevel";
+        this.context.lineCap = options["lineCap"] || "butt";
+    },
+
+    animate: function() {
+        var context = this.context;
+
+        context.clearRect(0, 0, this.size.x, this.size.y);
+        context.beginPath();
+        for (var i = this.offsetIndex, length = this.objects.length; i < length; ++i) {
+            var object = this.objects[i];
+            if (i == this.offsetIndex) {
+                context.lineWidth = object.width;
+                context.strokeStyle = object.color;
+                context.beginPath();
+                context.moveTo(object.point.x, object.point.y);
+            } else {
+                object.draw(context);
+
+                if (object.isSplit) {
+                    context.stroke();
+
+                    context.lineWidth = object.width;
+                    context.strokeStyle = object.color;
+                    context.beginPath();
+                    context.moveTo(object.point.x, object.point.y);
+                }
+
+                if (Pseudo.random() > 0.995)
+                    object.isSplit = !object.isSplit;
+            }
+        }
+        context.stroke();
+    }
+});
+
+// === BENCHMARK ===
+
+CanvasPathBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        var stage;
+        switch (options["pathType"]) {
+        case "line":
+            stage = new CanvasLineSegmentStage();
+            break;
+        case "linePath":
+            stage = new CanvasLinePathStage();
+            break;
+        case "arcs":
+            stage = new SimpleCanvasStage(CanvasArc);
+            break;
+        }
+
+        Benchmark.call(this, stage, options);
+    }
+);
+
+window.benchmarkClass = CanvasPathBenchmark;
+
+})();
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/compass.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/compass.svg
new file mode 100644
index 0000000..3f94e7a
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/compass.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 24 45.7600002 L 24 45.7600002 C 36.0177159 45.7600002 45.7599999 36.0177161 45.7599999 24.0000001 C 45.7599999 11.9822838 36.0177159 2.24000001 24 2.24000001 C 11.9822838 2.24000001 2.23999999 11.9822838 2.23999999 24.0000001 C 2.23999999 36.0177161 11.9822838 45.7600002 24 45.7600002 L 24 45.7600002 L 24 45.7600002 L 24 45.7600002 Z M 24 48 L 24 48 C 10.745166 48 8.52651283e-14 37.254834 8.52651283e-14 24.0000001 C 8.52651283e-14 10.745166 10.745166 0 24 0 C 37.254834 0 48 10.745166 48 24.0000001 C 48 37.254834 37.254834 48 24 48 L 24 48 L 24 48 L 24 48 Z" fill="rgb(142, 142, 147)"/>
+    <path fill="white" d="M 19.2141787 30.7527044 C 20.0566026 31.3582067 21.0164459 31.8087988 22.052466 32.0629879 L 24.0150243 38.3621108 L 25.9644157 32.0671275 C 28.9532689 31.3397602 31.304042 28.97474 32.0270276 25.9677724 L 38.2840894 24.0065666 L 32.38318 22.1457238 L 30.1049072 24.2136546 C 29.9995478 27.5073249 27.2907334 30.1510903 24.0134391 30.1359337 C 23.1661809 30.1431339 22.3840431 29.959524 21.6645278 29.6641888 L 19.2141787 30.7527044 L 19.2141787 30.7527044 L 19.2141787 30.7527044 Z M 28.8019182 17.2563866 C 27.4120183 16.2548466 25.9438825 15.9331447 25.9438825 15.9331447 L 23.9849759 9.63788916 L 22.0355845 15.9328727 C 19.0467312 16.6602398 16.695958 19.0252601 15.9729726 22.0322277 L 9.71591065 23.9934336 C 9.71591065 23.9934336 13.7573684 25.2679011 15.7780972 25.9051349 L 17.8923556 23.9486543 C 17.9116726 20.5783691 20.6200789 17.8803136 23.9912031 17.8674375 C 24.8266313 17.8130168 26.1806153 18.2277657 26.3381938 18.3358993 C 26.3381937 18.3358993 28.8019182 17.2563866 28.8019182 17.2563866 L 28.8019182 17.2563866 L 28.8019182 17.2563866 Z"/>
+    <path fill="white" d="M 22.4528571 21.5612813 L 10.1267612 32.8610634 L 25.4820204 26.3285511 L 37.8732388 15.1389366 L 22.4528571 21.5612813 L 22.4528571 21.5612813 L 22.4528571 21.5612813 Z"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/compass100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/compass100.png
new file mode 100644
index 0000000..e513ce11
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/compass100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/console.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/console.svg
new file mode 100644
index 0000000..e3c7611
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/console.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <rect stroke="rgb(0, 136, 204)" stroke-width="2.5" x="5.03735352" y="5.03735352" width="37.925293" height="37.925293" rx="4" fill="none"/>
+    <path d="M 13.164202 13.164202 L 24 24 L 13.164202 34.835798 M 24 14 L 35 14 M 29.5 24 L 34.9999999 24 M 24 34 L 35 34" stroke="white" stroke-width="2.5"  fill="none" />
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/console100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/console100.png
new file mode 100644
index 0000000..81f9c16
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/console100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/contribute.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/contribute.svg
new file mode 100644
index 0000000..68860efa
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/contribute.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path fill="rgb(203, 170, 68)" d="M 24 45.76 L 24 45.76 C 36.0177161 45.76 45.76 36.0177162 45.76 24 C 45.76 11.9822838 36.0177161 2.24 24 2.24 C 11.9822838 2.24 2.24 11.9822838 2.24 24 C 2.24 36.0177162 11.9822838 45.76 24 45.76 L 24 45.76 L 24 45.76 L 24 45.76 Z M 24 48 L 24 48 C 10.745166 48 -1.77635684e-14 37.254834 -1.77635684e-14 24 C -1.77635684e-14 10.745166 10.745166 2.84217094e-14 24 2.84217094e-14 C 37.254834 2.84217094e-14 48 10.745166 48 24 C 48 37.254834 37.254834 48 24 48 L 24 48 L 24 48 L 24 48 Z"/>
+    <path d="M 29.4897098 23.3065925 L 26.2706917 20.9393745 L 26.6482584 24.3031351 L 28.4802897 29.4247528 L 29.4897098 33.8205977 L 30.4989581 29.4247528 L 32.3309894 24.3031351 L 32.7087278 20.9393745 L 29.4897098 23.3065925 Z M 18.8503641 23.3065925 L 15.631346 20.9393745 L 16.0090845 24.3031351 L 17.8411157 29.4247528 L 18.8503641 33.8205977 L 19.8597841 29.4247528 L 21.6916437 24.3031351 L 22.0693821 20.9393745 L 18.8503641 23.3065925 Z M 37.2876041 24.3031351 L 39.1196354 29.4247528 L 40.3400738 34.740219 L 38.3454433 35 L 36.6368638 29.562799 C 36.6368638 29.562799 34.8092967 25.6310573 34.8092967 25.4866582 C 34.8092967 25.6310573 32.9819013 29.562799 32.9819013 29.562799 L 31.2733218 35 L 29.4897098 34.7676909 L 27.7060977 35 L 25.9975182 29.562799 C 25.9975182 29.562799 24.1701228 25.6310573 24.1701228 25.4866582 C 24.1701228 25.6310573 22.3425557 29.562799 22.3425557 29.562799 L 20.6339762 35 L 18.8503641 34.7676909 L 17.066752 35 L 15.3581725 29.562799 C 15.3581725 29.562799 13.5307771 25.6310573 13.5307771 25.4866582 C 13.5307771 25.6310573 11.7033817 29.562799 11.7033817 29.562799 L 9.9946305 35 L 8 34.740219 L 9.22043846 29.4247528 L 11.0524697 24.3031351 L 11.4302081 20.9393745 L 8.21101841 23.3065925 L 8.21101841 21.228001 L 11.6719607 18.326455 L 12.3810787 18.2218901 L 12.3810787 17.9233051 C 11.4619725 17.51054 10.825655 16.6183906 10.825655 15.5839024 C 10.825655 14.156738 12.0368217 13 13.5307771 13 C 15.0247325 13 16.2358992 14.156738 16.2358992 15.5839024 C 16.2358992 16.6183906 15.5995817 17.51054 14.6804755 17.9233051 L 14.6804755 18.2218901 L 15.3895935 18.326455 L 18.8503641 21.228001 L 22.3113064 18.326455 L 23.0204244 18.2218901 L 23.0204244 17.9233051 C 22.1013182 17.51054 21.4650007 16.6183906 21.4650007 15.5839024 C 21.4650007 14.156738 22.6761674 13 24.1701228 13 C 25.6640782 13 26.8750732 14.156738 26.8750732 15.5839024 C 26.8750732 16.6183906 26.2387556 17.51054 25.3198211 17.9233051 L 25.3198211 18.2218901 L 26.0289391 18.326455 L 29.4897098 21.228001 L 32.9504804 18.326455 L 33.6595984 18.2218901 L 33.6595984 17.9233051 C 32.7406639 17.51054 32.1043463 16.6183906 32.1043463 15.5839024 C 32.1043463 14.156738 33.3153413 13 34.8092967 13 C 36.3034238 13 37.5142471 14.156738 37.5144188 15.5839024 C 37.5144188 16.6183906 36.8781013 17.51054 35.9591668 17.9233051 L 35.9591668 18.2218901 L 36.6682848 18.326455 L 40.1290554 21.228001 L 40.1290554 23.3065925 L 36.9100374 20.9393745 L 37.2876041 24.3031351 Z" fill="white"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/contribute100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/contribute100.png
new file mode 100644
index 0000000..790e3dc
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/contribute100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/debugger.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/debugger.svg
new file mode 100644
index 0000000..646ddf4
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/debugger.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 24.1320008 44.328125 C 32.1512251 44.328125 38.6520901 35.226914 38.6520901 24 C 38.6520901 12.773086 32.1512251 3.671875 24.1320008 3.671875 C 16.1127765 3.671875 9.61191153 12.773086 9.61191153 24 C 9.61191153 35.226914 16.1127765 44.328125 24.1320008 44.328125 Z M 13.7861328 10.5 L 34.4768075 10.5 L 13.7861328 10.5 Z M 24.25 11 L 24.25 44.328125 M 34.1640625 37.0680804 L 39.9720982 42.8761161 M 38.5200893 22.25 L 44.328125 22.25 M 9.47991071 22.25 L 3.671875 22.25 M 13.8359375 10.9319196 L 8.02790179 5.12388393 M 34.1640625 10.9319196 L 39.9720982 5.12388393 M 13.972 37.068 L 8.164 42.876" fill="none" stroke="rgb(0, 136, 204)" stroke-width="2.5"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/debugger100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/debugger100.png
new file mode 100644
index 0000000..e2652096
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/debugger100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/design.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/design.js
new file mode 100644
index 0000000..91c6968
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/design.js
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+var TextStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+
+        this.testElements = [];
+        this._offsetIndex = 0;
+    }, {
+
+    shadowFalloff: new UnitBezier(new Point(0.015, 0.750), new Point(0.755, 0.235)),
+    shimmerAverage: 0,
+    shimmerMax: 0.5,
+    millisecondsPerRotation: 1000 / (.26 * Math.PI * 2),
+    particleDistanceX: 1.5,
+    particleDistanceY: .5,
+    lightnessMin: 13,
+    lightnessMax: 94,
+    gradients: [
+        [10, 176, 176, 209, 148, 140],
+        [171, 120, 154, 245, 196, 154],
+        [224, 99, 99, 71, 134, 148],
+        [101, 100, 117, 80, 230, 175],
+        [232, 165, 30, 69, 186, 172]
+    ],
+
+    initialize: function(benchmark)
+    {
+        Stage.prototype.initialize.call(this, benchmark);
+
+        this._template = document.getElementById("template");
+        this._offset = this.size.subtract(Point.elementClientSize(this._template)).multiply(.5);
+        this._template.style.left = this._offset.width + "px";
+        this._template.style.top = this._offset.height + "px";
+
+        this._stepProgress = 0;
+    },
+
+    tune: function(count)
+    {
+        if (count == 0)
+            return;
+
+        if (count < 0) {
+            this._offsetIndex = Math.max(this._offsetIndex + count, 0);
+            for (var i = this._offsetIndex; i < this.testElements.length; ++i)
+                this.testElements[i].style.visibility = "hidden";
+
+            this._stepProgress = 1 / this._offsetIndex;
+            return;
+        }
+
+        this._offsetIndex = this._offsetIndex + count;
+        this._stepProgress = 1 / this._offsetIndex;
+
+        var index = Math.min(this._offsetIndex, this.testElements.length);
+        for (var i = 0; i < index; ++i)
+            this.testElements[i].style.visibility = "visible";
+
+        if (this._offsetIndex <= this.testElements.length)
+            return;
+
+        for (var i = this.testElements.length; i < this._offsetIndex; ++i) {
+            var clone = this._template.cloneNode(true);
+            this.testElements.push(clone);
+            this.element.insertBefore(clone, this.element.firstChild);
+        }
+    },
+
+    animate: function(timeDelta) {
+        var angle = Stage.dateCounterValue(this.millisecondsPerRotation);
+
+        var progress = 0;
+        var stepX = Math.sin(angle) * this.particleDistanceX;
+        var stepY = Math.cos(angle) * this.particleDistanceY;
+        var x = -stepX * 3;
+        var y = -stepY * 3;
+        var gradient = this.gradients[Math.floor(angle/(Math.PI * 2)) % this.gradients.length];
+        var offset = Stage.dateCounterValue(200);
+        this._template.style.transform = "translate(" + Math.floor(x) + "px," + Math.floor(y) + "px)";
+        for (var i = 0; i < this._offsetIndex; ++i) {
+            var element = this.testElements[i];
+
+            var colorProgress = this.shadowFalloff.solve(progress);
+            var shimmer = Math.sin(offset - colorProgress);
+            colorProgress = Math.max(Math.min(colorProgress + Utilities.lerp(shimmer, this.shimmerAverage, this.shimmerMax), 1), 0);
+            var r = Math.round(Utilities.lerp(colorProgress, gradient[0], gradient[3]));
+            var g = Math.round(Utilities.lerp(colorProgress, gradient[1], gradient[4]));
+            var b = Math.round(Utilities.lerp(colorProgress, gradient[2], gradient[5]));
+            element.style.color = "rgb(" + r + "," + g + "," + b + ")";
+
+            x += stepX;
+            y += stepY;
+            element.style.transform = "translate(" + Math.floor(x) + "px," + Math.floor(y) + "px)";
+
+            progress += this._stepProgress;
+        }
+    },
+
+    complexity: function()
+    {
+        return 1 + this._offsetIndex;
+    }
+});
+
+var TextBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new TextStage(), options);
+    }
+);
+
+window.benchmarkClass = TextBenchmark;
+
+}());
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/focus.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/focus.js
new file mode 100644
index 0000000..ae51e5d8
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/focus.js
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+var minimumDiameter = 30;
+var sizeVariance = 20;
+var travelDistance = 50;
+
+var minBlurValue = 1;
+var maxBlurValue = 10;
+
+var opacityMultiplier = 30;
+var focusDuration = 1000;
+var movementDuration = 2500;
+
+var FocusElement = Utilities.createClass(
+    function(stage)
+    {
+        var size = minimumDiameter + sizeVariance;
+
+        // Size and blurring are a function of depth.
+        this._depth = Pseudo.random();
+        var distance = Utilities.lerp(this._depth, 0, sizeVariance);
+        size -= distance;
+
+        var top = Stage.random(0, stage.size.height - size);
+        var left = Stage.random(0, stage.size.width - size);
+
+        this.particle = document.createElement("div");
+        this.particle.style.width = size + "px";
+        this.particle.style.height = size + "px";
+        this.particle.style.top = top + "px";
+        this.particle.style.left = left + "px";
+        this.particle.style.zIndex = Math.round((1 - this._depth) * 10);
+
+        var depthMultiplier = Utilities.lerp(1 - this._depth, 0.8, 1);
+        this._sinMultiplier = Pseudo.random() * Stage.randomSign() * depthMultiplier * travelDistance;
+        this._cosMultiplier = Pseudo.random() * Stage.randomSign() * depthMultiplier * travelDistance;
+
+        this.animate(stage, 0, 0);
+    }, {
+
+    hide: function()
+    {
+        this.particle.style.display = "none";
+    },
+
+    show: function()
+    {
+        this.particle.style.display = "block";
+    },
+
+    animate: function(stage, sinFactor, cosFactor)
+    {
+        var top = sinFactor * this._sinMultiplier;
+        var left = cosFactor * this._cosMultiplier;
+        var distance = Math.abs(this._depth - stage.focalPoint);
+        var blur = Utilities.lerp(distance, minBlurValue, maxBlurValue);
+        var opacity = Math.max(5, opacityMultiplier * (1 - distance));
+
+        Utilities.setElementPrefixedProperty(this.particle, "filter", "blur(" + blur + "px) opacity(" + opacity + "%)");
+        this.particle.style.transform = "translate3d(" + left + "%, " + top + "%, 0)";
+    }
+});
+
+var FocusStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+
+        this._testElements = [];
+        this._offsetIndex = 0;
+        this.focalPoint = 0.5;
+    },
+
+    complexity: function()
+    {
+        return this._offsetIndex;
+    },
+
+    tune: function(count)
+    {
+        if (count == 0)
+            return;
+
+        if (count < 0) {
+            this._offsetIndex = Math.max(0, this._offsetIndex + count);
+            for (var i = this._offsetIndex; i < this._testElements.length; ++i)
+                this._testElements[i].hide();
+            return;
+        }
+
+        var newIndex = this._offsetIndex + count;
+        for (var i = this._testElements.length; i < newIndex; ++i) {
+            var obj = new FocusElement(this);
+            this._testElements.push(obj);
+            this.element.appendChild(obj.particle);
+        }
+        for (var i = this._offsetIndex; i < newIndex; ++i)
+            this._testElements[i].show();
+        this._offsetIndex = newIndex;
+    },
+
+    animate: function()
+    {
+        var time = this._benchmark.timestamp;
+        var sinFactor = Math.sin(time / movementDuration);
+        var cosFactor = Math.cos(time / movementDuration);
+
+        this.focalPoint = 0.5 + 0.5 * Math.sin(time / focusDuration);
+
+        for (var i = 0; i < this._offsetIndex; ++i)
+            this._testElements[i].animate(this, sinFactor, cosFactor);
+    }
+});
+
+var FocusBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new FocusStage(), options);
+    }
+);
+
+window.benchmarkClass = FocusBenchmark;
+
+}());
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/image-data.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/image-data.js
new file mode 100644
index 0000000..1940c3a7
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/image-data.js
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+var ImageDataStage = Utilities.createSubclass(Stage,
+    function() {
+        Stage.call(this);
+
+        this.testElements = [];
+        this._offsetIndex = 0;
+    }, {
+
+    imageWidth: 50,
+    imageHeight: 50,
+    pixelStride: 4,
+    rowStride: 200,
+    weightNegativeThreshold: 0.04,
+    weightPositiveThreshold: 0.96,
+    imageSrcs: [
+        "compass",
+        "console",
+        "contribute",
+        "debugger",
+        "inspector",
+        "layout",
+        "performance",
+        "script",
+        "shortcuts",
+        "standards",
+        "storage",
+        "styles",
+        "timeline"
+    ],
+    images: [],
+
+    initialize: function(benchmark)
+    {
+        Stage.prototype.initialize.call(this, benchmark);
+
+        var lastPromise;
+        var images = this.images;
+        this.imageSrcs.forEach(function(imageSrc) {
+            var promise = this._loadImage("resources/" + imageSrc + ".svg");
+            if (!lastPromise)
+                lastPromise = promise;
+            else {
+                lastPromise = lastPromise.then(function(img) {
+                    images.push(img);
+                    return promise;
+                });
+            }
+        }, this);
+
+        lastPromise.then(function(img) {
+            images.push(img);
+            benchmark.readyPromise.resolve();
+        }.bind(this));
+    },
+
+    _loadImage: function(src) {
+        var img = new Image;
+        var promise = new SimplePromise;
+
+        img.addEventListener('load', function onImageLoad(e) {
+            img.removeEventListener('load', onImageLoad);
+            promise.resolve(img);
+        });
+
+        img.src = src;
+        return promise;
+    },
+
+    tune: function(count)
+    {
+        if (count == 0)
+            return;
+
+        if (count < 0) {
+            this._offsetIndex = Math.max(this._offsetIndex + count, 0);
+            for (var i = this._offsetIndex; i < this.testElements.length; ++i)
+                this.testElements[i].style.display = "none";
+            return;
+        }
+
+        this._offsetIndex = this._offsetIndex + count;
+        var index = Math.min(this._offsetIndex, this.testElements.length);
+        for (var i = 0; i < index; ++i) {
+            this.testElements[i].style.display = "block";
+            this._refreshElement(this.testElements[i]);
+        }
+        if (this._offsetIndex <= this.testElements.length)
+            return;
+
+        index = this._offsetIndex - this.testElements.length;
+        for (var i = 0; i < index; ++i) {
+            var element = this._createTestElement();
+            this.testElements.push(element);
+            this.element.appendChild(element);
+        }
+    },
+
+    _createTestElement: function() {
+        var element = document.createElement('canvas');
+        element.width = this.imageWidth;
+        element.height = this.imageHeight;
+        element.style.width = this.imageWidth + 'px';
+        element.style.height = this.imageHeight + 'px';
+
+        this._refreshElement(element);
+        return element;
+    },
+
+    _refreshElement: function(element) {
+        var top = Stage.randomInt(0, Math.floor((this.size.height - this.imageHeight) / this.imageHeight)) * this.imageHeight;
+        var left = Stage.randomInt(0, Math.floor((this.size.width - this.imageWidth) / this.imageWidth)) * this.imageWidth;
+
+        element.style.top = top + 'px';
+        element.style.left = left + 'px';
+    },
+
+    animate: function(timeDelta) {
+        for (var i = 0; i < this._offsetIndex; ++i) {
+            var element = this.testElements[i];
+            var context = element.getContext("2d");
+
+            // Get image data
+            var imageData = context.getImageData(0, 0, this.imageWidth, this.imageHeight);
+
+            var didDraw = false,
+                neighborPixelIndex,
+                dataLen = imageData.data.length;
+            for (var j = 0; j < dataLen; j += this.pixelStride) {
+                if (imageData.data[j + 3] === 0)
+                    continue;
+
+                // get random neighboring pixel color
+                neighborPixelIndex = this._getRandomNeighboringPixelIndex(j, dataLen);
+
+                // Update the RGB data
+                imageData.data[j] = imageData.data[neighborPixelIndex];
+                imageData.data[j + 1] = imageData.data[neighborPixelIndex + 1];
+                imageData.data[j + 2] = imageData.data[neighborPixelIndex + 2];
+                imageData.data[j + 3] = imageData.data[neighborPixelIndex + 3];
+                didDraw = true;
+            }
+
+            if (didDraw)
+                context.putImageData(imageData, 0, 0);
+            else {
+                this._refreshElement(element);
+                element.getContext("2d").drawImage(Stage.randomElementInArray(this.images), 0, 0, this.imageWidth, this.imageHeight);
+            }
+        }
+    },
+
+    _getRandomNeighboringPixelIndex: function(pixelIdx, pixelArrayLength)
+    {
+        var xOffset = Math.floor((Pseudo.random() - this.weightNegativeThreshold) / (this.weightPositiveThreshold - this.weightNegativeThreshold));
+        var yOffset = Math.floor((Pseudo.random() - this.weightNegativeThreshold) / (this.weightPositiveThreshold - this.weightNegativeThreshold));
+        return (pixelIdx + this.pixelStride * xOffset + this.rowStride * yOffset) % pixelArrayLength;
+    },
+
+    complexity: function()
+    {
+        return this._offsetIndex;
+    }
+});
+
+var ImageDataBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new ImageDataStage(), options);
+    }, {
+
+    waitUntilReady: function() {
+        this.readyPromise = new SimplePromise;
+        return this.readyPromise;
+    }
+});
+
+window.benchmarkClass = ImageDataBenchmark;
+
+}());
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/inspector.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/inspector.svg
new file mode 100644
index 0000000..68cc4130
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/inspector.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <circle fill="none" stroke="rgb(0, 136, 204)" stroke-width="2.5" cx="24" cy="24" r="18"/>
+    <path d="M 28.5 25.5 L 48 25.5 L 48 23 L 28.5 23 L 28.5 25.5 M 23 28.5 L 23 48 L 25.5 48 L 25.5 28.5 L 23 28.5 M 0 25.5 L 19.5 25.5 L 19.5 23 L 5.99520433e-15 23 L 0 25.5 M 23 0 L 23 19.5 L 25.5 19.5 L 25.5 0 L 23 0" fill="white"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/inspector100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/inspector100.png
new file mode 100644
index 0000000..26d1a7d59
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/inspector100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/layout.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/layout.svg
new file mode 100644
index 0000000..73db97e
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/layout.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 44.5086986 24.2230775 L 24.1090229 24.2230775 L 24.1090229 4.50363839 L 24.1090229 4.50363839" fill="none" stroke="white" stroke-width="2.5"/>
+    <rect x="3.71000004" y="4.50363839" width="40.7993514" height="39.4388783" fill="none" stroke="rgb(191, 109, 113)" stroke-width="2.5"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/layout100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/layout100.png
new file mode 100644
index 0000000..5b1ec28
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/layout100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/leaves.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/leaves.js
new file mode 100644
index 0000000..dc2cf71a
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/leaves.js
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2015-2018 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.
+ */
+(function() {
+
+window.Leaf = Utilities.createSubclass(Particle,
+    function(stage)
+    {
+        this.element = document.createElement("img");
+        this.element.setAttribute("src", Stage.randomElementInArray(stage.images).src);
+        stage.element.appendChild(this.element);
+
+        Particle.call(this, stage);
+    }, {
+
+    sizeMinimum: 20,
+    sizeRange: 30,
+    usesOpacity: true,
+
+    reset: function()
+    {
+        Particle.prototype.reset.call(this);
+        this.element.style.width = this.size.x + "px";
+        this.element.style.height = this.size.y + "px";
+
+        if (this.usesOpacity) {
+            this._opacity = .01;
+            this._opacityRate = 0.02 * Stage.random(1, 6);
+        } else
+            this._life = Stage.randomInt(20, 100);
+
+        this._position = new Point(Stage.random(0, this.maxPosition.x), Stage.random(-this.size.height, this.maxPosition.y));
+        this._velocity = new Point(Stage.random(-6, -2), .1 * this.size.y + Stage.random(-1, 1));
+    },
+
+    animate: function(timeDelta)
+    {
+        this.rotater.next(timeDelta);
+
+        this._position.x += this._velocity.x + 8 * this.stage.focusX;
+        this._position.y += this._velocity.y;
+
+        if (this.usesOpacity) {
+            this._opacity += this._opacityRate;
+            if (this._opacity > 1) {
+                this._opacity = 1;
+                this._opacityRate *= -1;
+            } else if (this._opacity < 0 || this._position.y > this.stage.size.height)
+                this.reset();
+        } else {
+            this._life--;
+            if (!this._life || this._position.y > this.stage.size.height)
+                this.reset();
+        }
+
+        if (this._position.x < -this.size.width || this._position.x > this.stage.size.width)
+            this._position.x = this._position.x - Math.sign(this._position.x) * (this.size.width + this.stage.size.width);
+        this.move();
+    },
+
+    move: function()
+    {
+        this.element.style.transform = "translate(" + this._position.x + "px, " + this._position.y + "px)" + this.rotater.rotateZ();
+        this.element.style.opacity = this._opacity;
+    }
+});
+
+Utilities.extendObject(ParticlesStage.prototype, {
+
+    imageSrcs: [
+        "compass",
+        "console",
+        "contribute",
+        "debugger",
+        "inspector",
+        "layout",
+        "performance",
+        "script",
+        "shortcuts",
+        "standards",
+        "storage",
+        "styles",
+        "timeline"
+    ],
+    images: [],
+
+    initialize: function(benchmark)
+    {
+        Stage.prototype.initialize.call(this, benchmark);
+
+        var lastPromise;
+        var images = this.images;
+        this.imageSrcs.forEach(function(imageSrc) {
+            var promise = this._loadImage("../master/resources/" + imageSrc + "100.png"); // nocheck
+            if (!lastPromise)
+                lastPromise = promise;
+            else {
+                lastPromise = lastPromise.then(function(img) {
+                    images.push(img);
+                    return promise;
+                });
+            }
+        }, this);
+
+        lastPromise.then(function(img) {
+            images.push(img);
+            benchmark.readyPromise.resolve();
+        });
+    },
+
+    _loadImage: function(src) {
+        var img = new Image;
+        var promise = new SimplePromise;
+
+        img.onload = function(e) {
+            promise.resolve(e.target);
+        };
+
+        img.src = src;
+        return promise;
+    },
+
+    animate: function(timeDelta)
+    {
+        this.focusX = 0.5 + 0.5 * Math.sin(Stage.dateFractionalValue(10000) * Math.PI * 2);
+        timeDelta /= 4;
+        this.particles.forEach(function(particle) {
+            particle.animate(timeDelta);
+        });
+    },
+
+    createParticle: function()
+    {
+        return new Leaf(this);
+    },
+
+    willRemoveParticle: function(particle)
+    {
+        particle.element.remove();
+    }
+});
+
+var LeavesBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new ParticlesStage(), options);
+    }, {
+
+    waitUntilReady: function() {
+        this.readyPromise = new SimplePromise;
+        return this.readyPromise;
+    }
+
+});
+
+window.benchmarkClass = LeavesBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/multiply.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/multiply.js
new file mode 100644
index 0000000..67dab33
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/multiply.js
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+var MultiplyStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+        this.tiles = [];
+        this._offsetIndex = 0;
+    }, {
+
+    visibleCSS: [
+        ["visibility", "hidden", "visible"],
+        ["opacity", 0, 1],
+        ["display", "none", "block"]
+    ],
+    totalRows: 55,
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+        var tileSize = Math.round(this.size.height / this.totalRows);
+        if (options.visibleCSS)
+            this.visibleCSS = options.visibleCSS;
+
+        // Fill the scene with elements
+        var x = Math.round((this.size.width - tileSize) / 2);
+        var y = Math.round((this.size.height - tileSize) / 2);
+        var tileStride = tileSize;
+        var direction = 0;
+        var spiralCounter = 2;
+        var nextIndex = 1;
+        var maxSide = Math.floor(y / tileStride) * 2 + 1;
+        this._centerSpiralCount = maxSide * maxSide;
+        for (var i = 0; i < this._centerSpiralCount; ++i) {
+            this._addTile(x, y, tileSize, Stage.randomInt(0, 359));
+
+            if (i == nextIndex) {
+                direction = (direction + 1) % 4;
+                spiralCounter++;
+                nextIndex += spiralCounter >> 1;
+            }
+            if (direction == 0)
+                x += tileStride;
+            else if (direction == 1)
+                y -= tileStride;
+            else if (direction == 2)
+                x -= tileStride;
+            else
+                y += tileStride;
+        }
+
+        this._sidePanelCount = maxSide * Math.floor((this.size.width - x) / tileStride) * 2;
+        for (var i = 0; i < this._sidePanelCount; ++i) {
+            var sideX = x + Math.floor(Math.floor(i / maxSide) / 2) * tileStride;
+            var sideY = y - tileStride * (i % maxSide);
+
+            if (Math.floor(i / maxSide) % 2 == 1)
+                sideX = this.size.width - sideX - tileSize + 1;
+            this._addTile(sideX, sideY, tileSize, Stage.randomInt(0, 359));
+        }
+    },
+
+    _addTile: function(x, y, tileSize, rotateDeg)
+    {
+        var tile = Utilities.createElement("div", { class: "div-" + Stage.randomInt(0,6) }, this.element);
+        var halfTileSize = tileSize / 2;
+        tile.style.left = x + 'px';
+        tile.style.top = y + 'px';
+        tile.style.width = tileSize + 'px';
+        tile.style.height = tileSize + 'px';
+        var visibleCSS = this.visibleCSS[this.tiles.length % this.visibleCSS.length];
+        tile.style[visibleCSS[0]] = visibleCSS[1];
+
+        var distance = 1 / tileSize * this.size.multiply(0.5).subtract(new Point(x + halfTileSize, y + halfTileSize)).length();
+        this.tiles.push({
+            element: tile,
+            rotate: rotateDeg,
+            step: Math.max(3, distance / 1.5),
+            distance: distance,
+            active: false,
+            visibleCSS: visibleCSS,
+        });
+    },
+
+    complexity: function()
+    {
+        return this._offsetIndex;
+    },
+
+    tune: function(count)
+    {
+        this._offsetIndex = Math.max(0, Math.min(this._offsetIndex + count, this.tiles.length));
+        this._distanceFactor = 1.5 * (1 - 0.5 * Math.max(this._offsetIndex - this._centerSpiralCount, 0) / this._sidePanelCount) / Math.sqrt(this._offsetIndex);
+    },
+
+    animate: function()
+    {
+        var progress = this._benchmark.timestamp % 10000 / 10000;
+        var bounceProgress = Math.sin(2 * Math.abs( 0.5 - progress));
+        var l = Utilities.lerp(bounceProgress, 20, 50);
+        var hslPrefix = "hsla(" + Utilities.lerp(progress, 0, 360) + ",100%,";
+
+        for (var i = 0; i < this._offsetIndex; ++i) {
+            var tile = this.tiles[i];
+            tile.active = true;
+            tile.element.style[tile.visibleCSS[0]] = tile.visibleCSS[2];
+            tile.rotate += tile.step;
+            tile.element.style.transform = "rotate(" + tile.rotate + "deg)";
+
+            var influence = Math.max(.01, 1 - (tile.distance * this._distanceFactor));
+            tile.element.style.backgroundColor = hslPrefix + l * Math.tan(influence / 1.25) + "%," + influence + ")";
+        }
+
+        for (var i = this._offsetIndex; i < this.tiles.length && this.tiles[i].active; ++i) {
+            var tile = this.tiles[i];
+            tile.active = false;
+            tile.element.style[tile.visibleCSS[0]] = tile.visibleCSS[1];
+        }
+    }
+});
+
+var MultiplyBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new MultiplyStage(), options);
+    }
+);
+
+window.benchmarkClass = MultiplyBenchmark;
+
+}());
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/particles.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/particles.js
new file mode 100644
index 0000000..e918e1e
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/particles.js
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+function Particle(stage)
+{
+    this.stage = stage;
+    this.rotater = Stage.randomRotater();
+    this.reset();
+    this.move();
+}
+
+Particle.prototype =
+{
+    sizeMinimum: 40,
+    sizeRange: 10,
+
+    reset: function()
+    {
+        var randSize = Math.round(Math.pow(Pseudo.random(), 4) * this.sizeRange + this.sizeMinimum);
+        this.size = new Point(randSize, randSize);
+        this.minPosition = this.size.center;
+        this.maxPosition = this.stage.size.subtract(this.minPosition);
+    },
+
+    animate: function(timeDelta)
+    {
+        this.rotater.next(timeDelta);
+
+        this.position = this.position.add(this.velocity.multiply(timeDelta));
+        this.velocity.y += 0.03;
+
+        // If particle is going to move off right side
+        if (this.position.x > this.maxPosition.x) {
+            if (this.velocity.x > 0)
+                this.velocity.x *= -1;
+            this.position.x = this.maxPosition.x;
+        } else if (this.position.x < this.minPosition.x) {
+            // If particle is going to move off left side
+            if (this.velocity.x < 0)
+                this.velocity.x *= -1;
+            this.position.x = this.minPosition.x;
+        }
+
+        // If particle is going to move off bottom side
+        if (this.position.y > this.maxPosition.y) {
+            // Adjust direction but maintain magnitude
+            var magnitude = this.velocity.length();
+            this.velocity.x *= 1.5 + .005 * this.size.x;
+            this.velocity = this.velocity.normalize().multiply(magnitude);
+            if (Math.abs(this.velocity.y) < 0.7)
+                this.reset();
+            else {
+                if (this.velocity.y > 0)
+                    this.velocity.y *= -0.999;
+                this.position.y = this.maxPosition.y;
+            }
+        } else if (this.position.y < this.minPosition.y) {
+            // If particle is going to move off top side
+            var magnitude = this.velocity.length();
+            this.velocity.x *= 1.5 + .005 * this.size.x;
+            this.velocity = this.velocity.normalize().multiply(magnitude);
+            if (this.velocity.y < 0)
+                this.velocity.y *= -0.998;
+            this.position.y = this.minPosition.y;
+        }
+
+        this.move();
+    },
+
+    move: function()
+    {
+    }
+}
+
+ParticlesStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+        this.particles = [];
+    }, {
+
+    animate: function(timeDelta)
+    {
+        timeDelta /= 4;
+        this.particles.forEach(function(particle) {
+            particle.animate(timeDelta);
+        });
+    },
+
+    tune: function(count)
+    {
+        if (count == 0)
+            return;
+
+        if (count > 0) {
+            for (var i = 0; i < count; ++i)
+                this.particles.push(this.createParticle());
+            return;
+        }
+
+        count = Math.min(-count, this.particles.length);
+
+        if (typeof(this.willRemoveParticle) == "function") {
+            for (var i = 0; i < count; ++i)
+                this.willRemoveParticle(this.particles[i]);
+        }
+
+        this.particles.splice(0, count);
+    },
+
+    complexity: function()
+    {
+        return this.particles.length;
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/performance.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/performance.svg
new file mode 100644
index 0000000..37c4e95
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/performance.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 24 45.76 L 24 45.76 C 36.0177161 45.76 45.76 36.0177162 45.76 24 C 45.76 11.9822838 36.0177161 2.24 24 2.24 C 11.9822838 2.24 2.24 11.9822838 2.24 24 C 2.24 36.0177162 11.9822838 45.76 24 45.76 L 24 45.76 L 24 45.76 L 24 45.76 Z M 24 48 L 24 48 C 10.745166 48 -1.77635684e-14 37.254834 -1.77635684e-14 24 C -1.77635684e-14 10.745166 10.745166 2.84217094e-14 24 2.84217094e-14 C 37.254834 2.84217094e-14 48 10.745166 48 24 C 48 37.254834 37.254834 48 24 48 L 24 48 L 24 48 L 24 48 Z" fill="rgb(152, 188, 77)"/>
+    <path d="M 25.4586474 22.9633529 L 36.6273818 12.9367924 L 19.3784717 20.0882179 L 22.54035 25.0378408 L 11.3720064 35.0646845 L 28.6179627 27.9103051 L 25.4586474 22.9633529 L 25.4586474 22.9633529 Z" fill="white"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/performance100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/performance100.png
new file mode 100644
index 0000000..3f8a187
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/performance100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/script.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/script.svg
new file mode 100644
index 0000000..5e3f9c1b
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/script.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 9.4057939 17.7395629 C 10.1528885 17.0482595 11.14598 16.6062505 12.2562501 16.6062505 C 14.6587038 16.6062505 16.5125003 18.7103026 16.5125003 20.8625007 C 16.5125003 20.8625007 18.178953 19.2008056 19.0121793 18.369958 C 21.6138782 15.7756868 26.817276 10.5871443 26.817276 10.5871443 C 26.817276 10.5871443 37.1931445 21.9632427 37.5748423 22.4630973 C 38.0895548 23.1371422 39.2154452 24.3686768 39.2154452 26.5456407 C 39.2154452 27.6292862 38.7691081 28.6850409 38.0240604 29.4729943 C 37.2725506 30.267782 21.5041804 45.9478026 22.256517 45.2395774 C 23.0871144 44.4575043 23.6062505 43.3509701 23.6062505 42.1437514 C 23.6062505 39.8308355 22.4995839 38.7247751 21.9516194 38.0693479 C 21.9377433 38.0527505 21.4369464 37.5002693 20.6469581 36.6292772 L 15.0937502 42.1437514 C 15.0937502 44.4944134 16.9993383 46.4000015 19.3500004 46.4000015 C 20.4737422 46.4000015 21.4957691 45.9558816 22.256517 45.2395774 L 22.256517 45.2395773 C 22.2567055 45.2393999 22.256895 45.2392214 22.2570855 45.2390419 C 23.0873513 44.4569993 23.6062505 43.3506946 23.6062505 42.1437514 C 23.6062505 39.8308355 22.4995839 38.7247751 21.9516194 38.0693479 C 21.4036549 37.4139207 10.6902909 25.670612 9.9591809 24.8251984 C 9.2280709 23.9797848 8 23.049163 8 20.8625007 C 8 19.6863826 8.5362909 18.5441335 9.4057939 17.7395629 C 8.5362926 18.5441317 24.254167 2.7911567 25.2247918 1.98986582 C 25.9645636 1.37915353 26.8917931 1 27.8625007 1 C 30.1068344 1 32.1634331 3.09747093 32.1634331 5.25625015 L 16.5125003 20.8625007 C 16.5125003 18.7103026 14.6587038 16.6062505 12.2562501 16.6062505 C 11.1459801 16.6062505 10.1528886 17.0482595 9.405794 17.7395627 L 9.4057939 17.7395629 Z" fill="none" stroke="rgb(153, 127, 166)" stroke-width="2.5"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/script100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/script100.png
new file mode 100644
index 0000000..c2ea55ea
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/script100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/shortcuts.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/shortcuts.svg
new file mode 100644
index 0000000..edaa8496
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/shortcuts.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 5 35.8242187 C 5 39.7527757 8.1847243 42.9375 12.1132812 42.9375 C 16.0418382 42.9375 19.2265625 39.7527757 19.2265625 35.8242187 L 19.2265625 11.9442883 C 19.2265625 8.1847243 16.0418382 5 12.1132812 5 C 8.1847243 5 5 8.1847243 5 12.1132812 C 5 16.0418382 8.1847243 19.2265625 12.1132812 19.2265625 L 35.8928161 19.2265625 C 39.7527757 19.2265625 42.9375 16.0418382 42.9375 12.1132812 C 42.9375 8.1847243 39.7527757 5 35.8242188 5 C 31.8956618 5 28.7109375 8.1847243 28.7109375 12.1132812 L 28.7109375 35.8190088 C 28.7109375 39.7527757 31.8956618 42.9375 35.8242187 42.9375 C 39.7527757 42.9375 42.9375 39.7527757 42.9375 35.8242188 C 42.9375 31.8956618 39.7527757 28.7109375 35.8242187 28.7109375 L 12.1184912 28.7109375 C 8.1847243 28.7109375 5 31.8956618 5 35.8242187 Z" fill="none" stroke="rgb(0, 136, 204)" stroke-width="2.5"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/shortcuts100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/shortcuts100.png
new file mode 100644
index 0000000..aeb23e0
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/shortcuts100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/standards.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/standards.svg
new file mode 100644
index 0000000..ac1e6934
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/standards.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 42.0710239 24.0177617 C 39.1538386 16.9070258 32.1617573 11.8990479 24 11.8990479 C 16.3635634 11.8990479 9.75107907 16.2831086 6.54212676 22.6716502 M 30.9761247 44.4830419 C 32.2260967 41.0462637 32.9749756 36.6675422 32.9749756 31.8990479 C 32.9749756 20.8533529 28.9567421 11.8990479 24 11.8990479 C 19.0432579 11.8990479 15.0250244 20.8533529 15.0250244 31.8990479 C 15.0250244 36.5317055 15.7318455 40.7964804 16.9182797 44.1870585 L 16.9182797 44.1870585 M 6.58618164 23.392334 C 6.58618164 25.4881886 14.5338788 27.1872144 24.3378601 27.1872144 C 34.1418414 27.1872144 42.0895386 25.4881886 42.0895386 23.392334 M 7.57792629 35.5492537 C 10.9596878 37.443268 17.049483 38.7070228 24 38.7070228 C 31.5250917 38.7070228 38.041274 37.2256916 41.204187 35.0669761 M 24.25 12.9990234 L 24.25 45" fill="none" stroke="white" stroke-width="2.5"/>
+    <path d="M 8.20156221 41.7446204 L 4.60455725 1.39999998 L 44.1294427 1.39999998 L 40.5286241 41.7383005 L 24.34281 46.2255399 L 8.20156221 41.7446204 Z" fill="none" stroke="#BF7600" stroke-width="2.5"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/standards100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/standards100.png
new file mode 100644
index 0000000..ff386ff
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/standards100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/storage.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/storage.svg
new file mode 100644
index 0000000..c34a9ed
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/storage.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 39.9236499 31.5126111 C 41.869091 32.6498521 43 34.0625041 43 35.6923077 C 43 40.1632127 34.4896382 43 24 43 C 13.5103618 43 5 40.1632127 5 35.6923077 C 5 34.0625041 6.130909 32.6498521 8.07635005 31.5126111 C 9.14708175 31.9858647 10.3798534 32.4104194 11.7445378 32.7755154 C 9.22593316 33.7562269 7.92307692 34.9214488 7.92307692 35.6923077 C 7.92307692 36.4947878 9.3350136 37.7246485 12.0606138 38.728817 C 15.168606 39.8738668 19.433505 40.5384615 24 40.5384615 C 28.566495 40.5384615 32.831394 39.8738668 35.9393862 38.728817 C 38.6649864 37.7246485 40.0769231 36.4947878 40.0769231 35.6923077 C 40.0769231 34.9214488 38.7740668 33.7562269 36.2554622 32.7755154 C 37.6201466 32.4104194 38.8529182 31.9858647 39.9236499 31.5126111 Z M 39.9236499 19.8203034 C 41.869091 20.9575444 43 22.3701964 43 24 C 43 28.470905 34.4896382 31.3076923 24 31.3076923 C 13.5103618 31.3076923 5 28.470905 5 24 C 5 22.3701964 6.130909 20.9575444 8.07635005 19.8203034 C 9.06881359 20.2589632 10.2004933 20.6557834 11.4473978 21.0021956 C 9.12353139 22.0250817 7.92307692 23.2072017 7.92307692 24 C 7.92307692 24.8598001 9.3350136 26.177508 12.0606138 27.2534028 C 15.168606 28.4802419 19.433505 29.1923077 24 29.1923077 C 28.566495 29.1923077 32.831394 28.4802419 35.9393862 27.2534028 C 38.6649864 26.177508 40.0769231 24.8598001 40.0769231 24 C 40.0769231 23.2072017 38.8764686 22.0250817 36.5526022 21.0021956 C 37.7995067 20.6557834 38.9311864 20.2589632 39.9236499 19.8203034 Z M 43 12.3076923 C 43 7.83678727 34.4896382 5 24 5 C 13.5103618 5 5 7.83678727 5 12.3076923 C 5 16.7785973 13.5103618 19.6153846 24 19.6153846 C 34.4896382 19.6153846 43 16.7785973 43 12.3076923 Z M 12.0606138 15.3442016 C 9.3350136 14.3400331 7.92307692 13.1101724 7.92307692 12.3076923 C 7.92307692 11.5052122 9.3350136 10.2753515 12.0606138 9.27118298 C 15.168606 8.12613322 19.433505 7.46153846 24 7.46153846 C 28.566495 7.46153846 32.831394 8.12613322 35.9393862 9.27118298 C 38.6649864 10.2753515 40.0769231 11.5052122 40.0769231 12.3076923 C 40.0769231 13.1101724 38.6649864 14.3400331 35.9393862 15.3442016 C 32.831394 16.4892514 28.566495 17.1538462 24 17.1538462 C 19.433505 17.1538462 15.168606 16.4892514 12.0606138 15.3442016 Z" fill="rgb(153, 127, 166)"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/storage100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/storage100.png
new file mode 100644
index 0000000..bc59d92
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/storage100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/styles.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/styles.svg
new file mode 100644
index 0000000..f50cff7
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/styles.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 32.2807541 19.800573 C 30.8515632 18.9532817 29.6775632 16.9314716 29.6582461 15.2582558 L 29.5886562 9.2305008 C 29.5694759 7.56913954 30.7023175 6.90315961 32.1417063 7.75649663 L 37.3271003 10.8306408 C 38.7562912 11.677932 39.9302912 13.6997422 39.9496083 15.3729579 L 40.0191983 21.400713 C 40.0383785 23.0620742 38.905537 23.7280542 37.4661481 22.8747171 L 32.2807541 19.800573 L 32.2807541 19.800573 L 32.2807541 19.800573 Z M 22.7106927 25.0325153 C 21.2837011 24.186528 20.1113895 22.1575845 20.0922204 20.4971883 L 19.9529996 8.43813667 C 19.9338489 6.77933205 21.0737602 6.11960178 22.5021209 6.96640082 L 32.8759556 13.1164953 C 34.3029471 13.9624827 35.4752587 15.9914262 35.4944279 17.6518224 L 35.6336486 29.710874 C 35.6527994 31.3696786 34.512888 32.0294089 33.0845273 31.1826098 L 22.7106927 25.0325153 L 22.7106927 25.0325153 L 22.7106927 25.0325153 Z M 11.6578029 32.7104298 C 9.75514746 31.5824467 8.19206532 28.8771886 8.16650648 26.6633271 L 7.98087883 10.5845916 C 7.95534449 8.37285211 9.47522625 7.49321175 11.3797072 8.62227714 L 25.2114868 16.8224031 C 27.1141422 17.9503863 28.6772243 20.6556443 28.7027831 22.8695059 L 28.8884108 38.9482414 C 28.9139451 41.1599809 27.3940634 42.0396212 25.4895824 40.9105558 L 11.6578029 32.7104298 L 11.6578029 32.7104298 L 11.6578029 32.7104298 Z" fill="none" stroke="rgb(191, 109, 113)" stroke-width="2.5"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/styles100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/styles100.png
new file mode 100644
index 0000000..7bc9fff
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/styles100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/suits.js b/third_party/blink/perf_tests/MotionMark/tests/master/resources/suits.js
new file mode 100644
index 0000000..526f879
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/suits.js
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2015-2018 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.
+ */
+(function() {
+
+window.SuitsParticle = Utilities.createSubclass(Particle,
+    function(stage)
+    {
+        this.isClipPath = stage.particleCounter % 2;
+        this.initialize(stage);
+    }, {
+
+    sizeMinimum: 30,
+    sizeRange: 40,
+    hasGradient: true,
+
+    initialize: function(stage)
+    {
+        var shapeId = "#shape-" + Stage.randomInt(1, stage.particleTypeCount);
+        if (this.isClipPath) {
+            this.element = Utilities.createSVGElement("rect", {
+                x: 0,
+                y: 0,
+                "clip-path": "url(" + shapeId + ")"
+            }, {}, stage.element);
+        } else {
+            var shapePath = document.querySelector(shapeId + " path");
+            this.element = shapePath.cloneNode();
+            stage.element.appendChild(this.element);
+        }
+
+        if (this.hasGradient) {
+            this.gradient = document.getElementById("default-gradient").cloneNode(true);
+            this.gradient.id = "gradient-" + stage.gradientsCounter++;
+            stage.gradientsDefs.appendChild(this.gradient);
+            this.element.setAttribute("fill", "url(#" + this.gradient.id + ")");
+        }
+        Particle.call(this, stage);
+    },
+
+    reset: function()
+    {
+        Particle.prototype.reset.call(this);
+
+        this.position = Stage.randomElementInArray(this.stage.emitLocation);
+
+        var velocityMagnitude = Stage.random(.5, 2.5);
+        var angle = Stage.randomInt(0, this.stage.emitSteps) / this.stage.emitSteps * Math.PI * 2 + Stage.dateCounterValue(1000) * this.stage.emissionSpin + velocityMagnitude;
+        this.velocity = new Point(Math.sin(angle), Math.cos(angle))
+            .multiply(velocityMagnitude);
+
+        if (this.isClipPath) {
+            this.element.setAttribute("width", this.size.x);
+            this.element.setAttribute("height", this.size.y);
+            this.transformSuffix = " translate(-" + this.size.center.x + ",-" + this.size.center.y + ")";
+        } else
+            this.transformSuffix = " scale(" + this.size.x + ") translate(-.5,-.5)";
+
+        this.stage.colorOffset = (this.stage.colorOffset + .5) % 360;
+
+        if (this.hasGradient) {
+            var transform = this.stage.element.createSVGTransform();
+            transform.setRotate(Stage.randomInt(0, 359), 0, 0);
+            this.gradient.gradientTransform.baseVal.initialize(transform);
+
+            var stops = this.gradient.querySelectorAll("stop");
+            stops[0].setAttribute("stop-color", "hsl(" + this.stage.colorOffset + ", 70%, 45%)");
+            stops[1].setAttribute("stop-color", "hsl(" + ((this.stage.colorOffset + Stage.randomInt(50,100)) % 360) + ", 70%, 65%)");
+        } else
+            this.element.setAttribute("fill", "hsl(" + this.stage.colorOffset + ", 70%, 65%)");
+    },
+
+    move: function()
+    {
+        this.element.setAttribute("transform", "translate(" + this.position.x + "," + this.position.y + ") " + this.rotater.rotate(Point.zero) + this.transformSuffix);
+    }
+});
+
+var SuitsStage = Utilities.createSubclass(ParticlesStage,
+    function()
+    {
+        ParticlesStage.call(this);
+    }, {
+
+    initialize: function(benchmark)
+    {
+        ParticlesStage.prototype.initialize.call(this, benchmark);
+        this.emissionSpin = Stage.random(0, 3);
+        this.emitSteps = Stage.randomInt(4, 6);
+        this.emitLocation = [
+            new Point(this.size.x * .25, this.size.y * .333),
+            new Point(this.size.x * .5, this.size.y * .25),
+            new Point(this.size.x * .75, this.size.y * .333)
+        ];
+        this.colorOffset = Stage.randomInt(0, 359);
+
+        this.particleTypeCount = document.querySelectorAll(".shape").length;
+        this.gradientsDefs = document.getElementById("gradients");
+        this.gradientsCounter = 0;
+        this.particleCounter = 0;
+    },
+
+    createParticle: function()
+    {
+        this.particleCounter++;
+        return new SuitsParticle(this);
+    },
+
+    willRemoveParticle: function(particle)
+    {
+        particle.element.remove();
+        if (particle.gradient)
+            particle.gradient.remove();
+    }
+});
+
+var SuitsBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new SuitsStage(), options);
+    }
+);
+
+window.benchmarkClass = SuitsBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/timeline.svg b/third_party/blink/perf_tests/MotionMark/tests/master/resources/timeline.svg
new file mode 100644
index 0000000..cd1e8a4
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/timeline.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M 24 45.76 L 24 45.76 C 36.0177161 45.76 45.76 36.0177162 45.76 24 C 45.76 11.9822838 36.0177161 2.24 24 2.24 C 11.9822838 2.24 2.24 11.9822838 2.24 24 C 2.24 36.0177162 11.9822838 45.76 24 45.76 L 24 45.76 L 24 45.76 L 24 45.76 Z M 24 48 L 24 48 C 10.745166 48 0 37.254834 0 24 C 0 10.745166 10.745166 0 24 0 C 37.254834 0 48 10.745166 48 24 C 48 37.254834 37.254834 48 24 48 L 24 48 L 24 48 L 24 48 Z" fill="rgb(0, 136, 204)"/>
+    <path d="M 24.625 7.57617187 L 24.625 24.5833333 L 15 24.5833333" fill="none" stroke="white" stroke-width="2.5"/>
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/resources/timeline100.png b/third_party/blink/perf_tests/MotionMark/tests/master/resources/timeline100.png
new file mode 100644
index 0000000..b9839f8
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/resources/timeline100.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/master/suits.html b/third_party/blink/perf_tests/MotionMark/tests/master/suits.html
new file mode 100644
index 0000000..72d0872f
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/master/suits.html
@@ -0,0 +1,62 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <svg id="stage">
+        <defs id="gradients">
+            <linearGradient id="default-gradient">
+                <stop offset="0%"/>
+                <stop offset="100%"/>
+            </linearGradient>
+        </defs>
+        <defs id="shapes">
+            <clipPath id="shape-1" class="shape heart" clipPathUnits="objectBoundingBox">
+                <path d="M0.5,0.214 C0.466,0.164 0.369,0.09 0.267,0.092 C0.137,0.093 -0,0.186 -0,0.345 C-0,0.659 0.395,0.655 0.5,0.938 C0.605,0.655 1,0.659 1,0.345 C1,0.186 0.863,0.093 0.733,0.092 C0.631,0.09 0.534,0.164 0.5,0.214 z"/>
+            </clipPath>
+            <clipPath id="shape-2" class="shape club" clipPathUnits="objectBoundingBox">
+                <path d="M0.5,0.018 C0.62,0.018 0.718,0.115 0.718,0.235 C0.718,0.31 0.679,0.377 0.618,0.418 C0.657,0.393 0.703,0.382 0.749,0.381 C0.869,0.381 0.967,0.468 0.967,0.588 C0.967,0.709 0.869,0.806 0.749,0.806 C0.664,0.805 0.578,0.756 0.542,0.677 C0.538,0.799 0.605,0.918 0.708,0.982 C0.593,0.941 0.407,0.941 0.292,0.982 C0.397,0.917 0.461,0.799 0.459,0.676 C0.422,0.756 0.337,0.804 0.251,0.806 C0.131,0.806 0.033,0.709 0.033,0.588 C0.033,0.468 0.131,0.381 0.251,0.381 C0.298,0.38 0.342,0.395 0.382,0.418 C0.319,0.378 0.284,0.309 0.282,0.235 C0.282,0.115 0.38,0.018 0.5,0.018 z"/>
+            </clipPath>
+            <clipPath id="shape-3" class="shape spade" clipPathUnits="objectBoundingBox">
+                <path d="M0.301,0.982 C0.374,0.941 0.469,0.804 0.469,0.72 C0.374,0.857 0.039,0.825 0.049,0.563 C0.059,0.28 0.406,0.269 0.5,0.018 C0.594,0.269 0.941,0.28 0.951,0.563 C0.961,0.825 0.626,0.857 0.531,0.72 C0.531,0.804 0.626,0.941 0.699,0.982 C0.584,0.941 0.416,0.941 0.301,0.982"/>
+            </clipPath>
+            <clipPath id="shape-4" class="shape diamond" clipPathUnits="objectBoundingBox">
+                <path d="M0.495,0 C0.424,0.153 0.199,0.439 0.128,0.5 C0.199,0.561 0.424,0.847 0.495,1 C0.566,0.847 0.791,0.561 0.862,0.5 C0.791,0.439 0.566,0.153 0.495,0 z"/>
+            </clipPath>
+        </defs>
+    </svg>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/particles.js"></script>
+    <script src="resources/suits.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/resources/main.js b/third_party/blink/perf_tests/MotionMark/tests/resources/main.js
new file mode 100644
index 0000000..c96f02d
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/resources/main.js
@@ -0,0 +1,954 @@
+/*
+ * Copyright (C) 2015-2021 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.
+ */
+Sampler = Utilities.createClass(
+    function(seriesCount, expectedSampleCount, processor)
+    {
+        this._processor = processor;
+
+        this.samples = [];
+        for (var i = 0; i < seriesCount; ++i) {
+            var array = new Array(expectedSampleCount);
+            array.fill(0);
+            this.samples[i] = array;
+        }
+        this.sampleCount = 0;
+    }, {
+
+    record: function() {
+        // Assume that arguments.length == this.samples.length
+        for (var i = 0; i < arguments.length; i++) {
+            this.samples[i][this.sampleCount] = arguments[i];
+        }
+        ++this.sampleCount;
+    },
+
+    processSamples: function()
+    {
+        var results = {};
+
+        // Remove unused capacity
+        this.samples = this.samples.map(function(array) {
+            return array.slice(0, this.sampleCount);
+        }, this);
+
+        this._processor.processSamples(results);
+
+        return results;
+    }
+});
+
+Controller = Utilities.createClass(
+    function(benchmark, options)
+    {
+        // Initialize timestamps relative to the start of the benchmark
+        // In start() the timestamps are offset by the start timestamp
+        this._startTimestamp = 0;
+        this._endTimestamp = options["test-interval"];
+        this._targetFrameRate = options["frame-rate"] || 60;
+        // Default data series: timestamp, complexity, estimatedFrameLength
+        var sampleSize = options["sample-capacity"] || (this._targetFrameRate * options["test-interval"] / 1000);
+        this._sampler = new Sampler(options["series-count"] || 3, sampleSize, this);
+        this._marks = {};
+
+        this._frameLengthEstimator = new SimpleKalmanEstimator(options["kalman-process-error"], options["kalman-measurement-error"]);
+        this._isFrameLengthEstimatorEnabled = true;
+
+        // Length of subsequent intervals; a value of 0 means use no intervals
+        this.intervalSamplingLength = 100;
+
+        this.initialComplexity = 1;
+    }, {
+
+    set isFrameLengthEstimatorEnabled(enabled) {
+        this._isFrameLengthEstimatorEnabled = enabled;
+    },
+
+    start: function(startTimestamp, stage)
+    {
+        this._startTimestamp = startTimestamp;
+        this._endTimestamp += startTimestamp;
+        this._previousTimestamp = startTimestamp;
+        this._measureAndResetInterval(startTimestamp);
+        this.recordFirstSample(startTimestamp, stage);
+    },
+
+    recordFirstSample: function(startTimestamp, stage)
+    {
+        this._sampler.record(startTimestamp, stage.complexity(), -1);
+        this.mark(Strings.json.samplingStartTimeOffset, startTimestamp);
+    },
+
+    mark: function(comment, timestamp, data) {
+        data = data || {};
+        data.time = timestamp;
+        data.index = this._sampler.sampleCount;
+        this._marks[comment] = data;
+    },
+
+    containsMark: function(comment) {
+        return comment in this._marks;
+    },
+
+    filterOutOutliers: function(array)
+    {
+        if (array.length == 0)
+            return [];
+
+        array.sort((a, b) => a - b);
+        var q1 = array[Math.min(Math.round(array.length * 1 / 4), array.length - 1)];
+        var q3 = array[Math.min(Math.round(array.length * 3 / 4), array.length - 1)];
+        var interquartileRange = q3 - q1;
+        var minimum = q1 - interquartileRange * 1.5;
+        var maximum = q3 + interquartileRange * 1.5;
+        return array.filter(x => x >= minimum && x <= maximum);
+    },
+
+    _measureAndResetInterval: function(currentTimestamp)
+    {
+        var sampleCount = this._sampler.sampleCount;
+        var averageFrameLength = 0;
+
+        if (this._intervalEndTimestamp) {
+            var durations = [];
+            for (var i = Math.max(this._intervalStartIndex, 1); i < sampleCount; ++i) {
+                durations.push(this._sampler.samples[0][i] - this._sampler.samples[0][i - 1]);
+            }
+            var filteredDurations = this.filterOutOutliers(durations);
+            if (filteredDurations.length > 0)
+                averageFrameLength = filteredDurations.reduce((a, b) => a + b, 0) / filteredDurations.length;
+        }
+
+        this._intervalStartIndex = sampleCount;
+        this._intervalEndTimestamp = currentTimestamp + this.intervalSamplingLength;
+
+        return averageFrameLength;
+    },
+
+    update: function(timestamp, stage)
+    {
+        var lastFrameLength = timestamp - this._previousTimestamp;
+        this._previousTimestamp = timestamp;
+
+        var frameLengthEstimate = -1, intervalAverageFrameLength = -1;
+        var didFinishInterval = false;
+        if (!this.intervalSamplingLength) {
+            if (this._isFrameLengthEstimatorEnabled) {
+                this._frameLengthEstimator.sample(lastFrameLength);
+                frameLengthEstimate = this._frameLengthEstimator.estimate;
+            }
+        } else {
+            this.registerFrameTime(lastFrameLength);
+            if (this.intervalHasConcluded(timestamp)) {
+                var intervalStartTimestamp = this._sampler.samples[0][this._intervalStartIndex];
+                intervalAverageFrameLength = this._measureAndResetInterval(timestamp);
+                if (this._isFrameLengthEstimatorEnabled) {
+                    this._frameLengthEstimator.sample(intervalAverageFrameLength);
+                    frameLengthEstimate = this._frameLengthEstimator.estimate;
+                }
+                didFinishInterval = true;
+                this.didFinishInterval(timestamp, stage, intervalAverageFrameLength);
+                this._frameLengthEstimator.reset();
+            }
+        }
+
+        this._sampler.record(timestamp, stage.complexity(), frameLengthEstimate);
+        this.tune(timestamp, stage, lastFrameLength, didFinishInterval, intervalAverageFrameLength);
+    },
+
+    registerFrameTime: function(lastFrameLength)
+    {
+    },
+
+    intervalHasConcluded: function(timestamp)
+    {
+        return timestamp >= this._intervalEndTimestamp;
+    },
+
+    didFinishInterval: function(timestamp, stage, intervalAverageFrameLength)
+    {
+    },
+
+    tune: function(timestamp, stage, lastFrameLength, didFinishInterval, intervalAverageFrameLength)
+    {
+    },
+
+    shouldStop: function(timestamp)
+    {
+        return timestamp > this._endTimestamp;
+    },
+
+    results: function()
+    {
+        return this._sampler.processSamples();
+    },
+
+    _processComplexitySamples: function(complexitySamples)
+    {
+        complexitySamples.sort(function(a, b) {
+            return complexitySamples.getFieldInDatum(a, Strings.json.complexity) - complexitySamples.getFieldInDatum(b, Strings.json.complexity);
+        });
+    },
+
+    _processMarks: function()
+    {
+        for (var markName in this._marks)
+            this._marks[markName].time -= this._startTimestamp;
+        return this._marks;
+    },
+    _processControllerSamples: function()
+    {
+        var controllerSamples = new SampleData;
+        controllerSamples.addField(Strings.json.time, 0);
+        controllerSamples.addField(Strings.json.complexity, 1);
+        controllerSamples.addField(Strings.json.frameLength, 2);
+        controllerSamples.addField(Strings.json.smoothedFrameLength, 3);
+
+        var samples = this._sampler.samples;
+        samples[0].forEach(function(timestamp, i) {
+            var sample = controllerSamples.createDatum();
+            controllerSamples.push(sample);
+
+            // Represent time in milliseconds
+            controllerSamples.setFieldInDatum(sample, Strings.json.time, timestamp - this._startTimestamp);
+            controllerSamples.setFieldInDatum(sample, Strings.json.complexity, samples[1][i]);
+
+            if (i == 0)
+                controllerSamples.setFieldInDatum(sample, Strings.json.frameLength, 1000/this._targetFrameRate);
+            else
+                controllerSamples.setFieldInDatum(sample, Strings.json.frameLength, timestamp - samples[0][i - 1]);
+
+            if (samples[2][i] != -1)
+                controllerSamples.setFieldInDatum(sample, Strings.json.smoothedFrameLength, samples[2][i]);
+        }, this);
+
+        return controllerSamples;
+    },
+
+    processSamples: function(results)
+    {
+        results[Strings.json.marks] = this._processMarks();
+
+        var controllerSamples = this._processControllerSamples();
+        var complexitySamples = new SampleData(controllerSamples.fieldMap);
+
+        results[Strings.json.samples] = {};
+        results[Strings.json.samples][Strings.json.controller] = controllerSamples;
+        results[Strings.json.samples][Strings.json.complexity] = complexitySamples;
+        controllerSamples.forEach(function (sample) {
+            complexitySamples.push(sample);
+        });
+        this._processComplexitySamples(complexitySamples);
+    }
+});
+
+FixedController = Utilities.createSubclass(Controller,
+    function(benchmark, options)
+    {
+        Controller.call(this, benchmark, options);
+        this.initialComplexity = options["complexity"];
+        this.intervalSamplingLength = 0;
+    }
+);
+
+AdaptiveController = Utilities.createSubclass(Controller,
+    function(benchmark, options)
+    {
+        // Data series: timestamp, complexity, estimatedIntervalFrameLength
+        Controller.call(this, benchmark, options);
+
+        // All tests start at 0, so we expect to see the target fps quickly.
+        this._samplingTimestamp = options["test-interval"] / 2;
+        this._startedSampling = false;
+        this._targetFrameRate = options["frame-rate"];
+        this._pid = new PIDController(this._targetFrameRate);
+
+        this._intervalFrameCount = 0;
+        this._numberOfFramesToMeasurePerInterval = 4;
+    }, {
+
+    start: function(startTimestamp, stage)
+    {
+        Controller.prototype.start.call(this, startTimestamp, stage);
+
+        this._samplingTimestamp += startTimestamp;
+        this._intervalTimestamp = startTimestamp;
+    },
+
+    recordFirstSample: function(startTimestamp, stage)
+    {
+        this._sampler.record(startTimestamp, stage.complexity(), -1);
+    },
+
+    update: function(timestamp, stage)
+    {
+        if (!this._startedSampling && timestamp >= this._samplingTimestamp) {
+            this._startedSampling = true;
+            this.mark(Strings.json.samplingStartTimeOffset, this._samplingTimestamp);
+        }
+
+        // Start the work for the next frame.
+        ++this._intervalFrameCount;
+
+        if (this._intervalFrameCount < this._numberOfFramesToMeasurePerInterval) {
+            this._sampler.record(timestamp, stage.complexity(), -1);
+            return;
+        }
+
+        // Adjust the test to reach the desired FPS.
+        var intervalLength = timestamp - this._intervalTimestamp;
+        this._frameLengthEstimator.sample(intervalLength / this._numberOfFramesToMeasurePerInterval);
+        var intervalEstimatedFrameRate = 1000 / this._frameLengthEstimator.estimate;
+        var tuneValue = -this._pid.tune(timestamp - this._startTimestamp, intervalLength, intervalEstimatedFrameRate);
+        tuneValue = tuneValue > 0 ? Math.floor(tuneValue) : Math.ceil(tuneValue);
+        stage.tune(tuneValue);
+
+        this._sampler.record(timestamp, stage.complexity(), this._frameLengthEstimator.estimate);
+
+        // Start the next interval.
+        this._intervalFrameCount = 0;
+        this._intervalTimestamp = timestamp;
+    }
+});
+
+RampController = Utilities.createSubclass(Controller,
+    function(benchmark, options)
+    {
+        this.targetFPS = options["frame-rate"] || 60;
+
+        // The tier warm-up takes at most 5 seconds
+        options["sample-capacity"] = (options["test-interval"] / 1000 + 5) * this.targetFPS;
+        Controller.call(this, benchmark, options);
+
+        // Initially start with a tier test to find the bounds
+        // The number of objects in a tier test is 10^|_tier|
+        this._tier = -.5;
+        // The timestamp is first set after the first interval completes
+        this._tierStartTimestamp = 0;
+        this._minimumComplexity = 1;
+        this._maximumComplexity = 1;
+
+        this._testLength = options["test-interval"];
+
+        // After the tier range is determined, figure out the number of ramp iterations
+        var minimumRampLength = 3000;
+        var totalRampIterations = Math.max(1, Math.floor(this._endTimestamp / minimumRampLength));
+        // Give a little extra room to run since the ramps won't be exactly this length
+        this._rampLength = Math.floor((this._endTimestamp - totalRampIterations * this.intervalSamplingLength) / totalRampIterations);
+        this._rampDidWarmup = false;
+        this._rampRegressions = [];
+
+        this._finishedTierSampling = false;
+        this._changePointEstimator = new Experiment;
+        this._minimumComplexityEstimator = new Experiment;
+        // Estimates all frames within an interval
+        this._intervalFrameLengthEstimator = new Experiment;
+
+        // Used for regression calculations in the ramps
+        this.frameLengthDesired = 1000/this.targetFPS;
+        // Add some tolerance; frame lengths shorter than this are considered to be @ the desired frame length
+        this.frameLengthDesiredThreshold = 1000/(this.targetFPS - 2);
+        // During tier sampling get at least this slow to find the right complexity range
+        this.frameLengthTierThreshold = 1000/(this.targetFPS * 0.5);
+        // Try to make each ramp get this slow so that we can cross the break point
+        this.frameLengthRampLowerThreshold = 1000/(this.targetFPS * 0.75);
+        // Do not let the regression calculation at the maximum complexity of a ramp get slower than this threshold
+        this.frameLengthRampUpperThreshold = 1000/(this.targetFPS / 3);
+    }, {
+
+    // If the engine can handle the tier's complexity at the desired frame rate, test for a short
+    // period, then move on to the next tier
+    tierFastTestLength: 250,
+    // If the engine is under stress, let the test run a little longer to let the measurement settle
+    tierSlowTestLength: 750,
+    // Tier intervals must have this number of non-outlier frames in order to end.
+    numberOfFramesRequiredInInterval: 9,
+
+    rampWarmupLength: 200,
+
+    start: function(startTimestamp, stage)
+    {
+        Controller.prototype.start.call(this, startTimestamp, stage);
+        this._rampStartTimestamp = 0;
+        this.intervalSamplingLength = 100;
+        this._frameTimeHistory = [];
+    },
+
+    registerFrameTime: function(lastFrameLength)
+    {
+        this._frameTimeHistory.push(lastFrameLength);
+    },
+
+    intervalHasConcluded: function(timestamp)
+    {
+        if (!Controller.prototype.intervalHasConcluded.call(this, timestamp))
+            return false;
+
+        return this._finishedTierSampling || this.filterOutOutliers(this._frameTimeHistory).length > this.numberOfFramesRequiredInInterval;
+    },
+
+    didFinishInterval: function(timestamp, stage, intervalAverageFrameLength)
+    {
+        this._frameTimeHistory = [];
+        if (!this._finishedTierSampling) {
+            if (this._tierStartTimestamp > 0 && timestamp < this._tierStartTimestamp + this.tierFastTestLength)
+                return;
+
+            var currentComplexity = stage.complexity();
+            var currentFrameLength = this._frameLengthEstimator.estimate;
+            if (currentFrameLength < this.frameLengthTierThreshold) {
+                var isAnimatingAtTargetFPS = currentFrameLength < this.frameLengthDesiredThreshold;
+                var hasFinishedSlowTierTest = timestamp > this._tierStartTimestamp + this.tierSlowTestLength;
+
+                if (!isAnimatingAtTargetFPS && !hasFinishedSlowTierTest)
+                    return;
+
+                // We're measuring at the target fps, so quickly move on to the next tier, or
+                // we're slower than the target fps, but we've let this tier run long enough to
+                // get an estimate
+                this._lastTierComplexity = currentComplexity;
+                this._lastTierFrameLength = currentFrameLength;
+
+                if (currentComplexity <= 50)
+                    this._tier += 1/2;
+                else if (currentComplexity <= 10000)
+                    this._tier += 1/4;
+                else
+                    this._tier += 1/8;
+                this._endTimestamp = timestamp + this._testLength;
+                var nextTierComplexity = Math.max(Math.round(Math.pow(10, this._tier)), currentComplexity + 1);
+                stage.tune(nextTierComplexity - currentComplexity);
+
+                // Some tests may be unable to go beyond a certain capacity. If so, don't keep moving up tiers
+                if (stage.complexity() - currentComplexity > 0 || nextTierComplexity == 1) {
+                    this._tierStartTimestamp = timestamp;
+                    this.mark("Complexity: " + nextTierComplexity, timestamp);
+                    return;
+                }
+            } else if (timestamp < this._tierStartTimestamp + this.tierSlowTestLength)
+                return;
+
+            this._finishedTierSampling = true;
+            this.isFrameLengthEstimatorEnabled = false;
+            this.intervalSamplingLength = 120;
+
+            // Extend the test length so that the full test length is made of the ramps
+            this._endTimestamp = timestamp + this._testLength;
+            this.mark(Strings.json.samplingStartTimeOffset, timestamp);
+
+            this._minimumComplexity = 1;
+            this._possibleMinimumComplexity = this._minimumComplexity;
+            this._minimumComplexityEstimator.sample(this._minimumComplexity);
+
+            // Sometimes this last tier will drop the frame length well below the threshold.
+            // Avoid going down that far since it means fewer measurements are taken in the target fps area.
+            // Interpolate a maximum complexity that gets us around the lowest threshold.
+            // Avoid doing this calculation if we never get out of the first tier (where this._lastTierComplexity is undefined).
+            if (this._lastTierComplexity && this._lastTierComplexity != currentComplexity)
+                this._maximumComplexity = Math.floor(Utilities.lerp(Utilities.progressValue(this.frameLengthTierThreshold, this._lastTierFrameLength, currentFrameLength), this._lastTierComplexity, currentComplexity));
+            else {
+                // If the browser is capable of handling the most complex version of the test, use that
+                this._maximumComplexity = currentComplexity;
+            }
+            this._possibleMaximumComplexity = this._maximumComplexity;
+
+            // If we get ourselves onto a ramp where the maximum complexity does not yield slow enough FPS,
+            // We'll use this as a boundary to find a higher maximum complexity for the next ramp
+            this._lastTierComplexity = currentComplexity;
+            this._lastTierFrameLength = currentFrameLength;
+
+            // First ramp
+            stage.tune(this._maximumComplexity - currentComplexity);
+            this._rampDidWarmup = false;
+            // Start timestamp represents start of ramp iteration and warm up
+            this._rampStartTimestamp = timestamp;
+            return;
+        }
+
+        if ((timestamp - this._rampStartTimestamp) < this.rampWarmupLength)
+            return;
+
+        if (this._rampDidWarmup)
+            return;
+
+        this._rampDidWarmup = true;
+        this._currentRampLength = this._rampStartTimestamp + this._rampLength - timestamp;
+        // Start timestamp represents start of ramp down, after warm up
+        this._rampStartTimestamp = timestamp;
+        this._rampStartIndex = this._sampler.sampleCount;
+    },
+
+    tune: function(timestamp, stage, lastFrameLength, didFinishInterval, intervalAverageFrameLength)
+    {
+        if (!this._rampDidWarmup)
+            return;
+
+        this._intervalFrameLengthEstimator.sample(lastFrameLength);
+        if (!didFinishInterval)
+            return;
+
+        var currentComplexity = stage.complexity();
+        var intervalFrameLengthMean = this._intervalFrameLengthEstimator.mean();
+        var intervalFrameLengthStandardDeviation = this._intervalFrameLengthEstimator.standardDeviation();
+
+        if (intervalFrameLengthMean < this.frameLengthDesiredThreshold && this._intervalFrameLengthEstimator.cdf(this.frameLengthDesiredThreshold) > .9) {
+            this._possibleMinimumComplexity = Math.max(this._possibleMinimumComplexity, currentComplexity);
+        } else if (intervalFrameLengthStandardDeviation > 2) {
+            // In the case where we might have found a previous interval where the target fps was reached. We hit a significant blip,
+            // so we should resample this area in the next ramp.
+            this._possibleMinimumComplexity = 1;
+        }
+        if (intervalFrameLengthMean - intervalFrameLengthStandardDeviation > this.frameLengthRampLowerThreshold)
+            this._possibleMaximumComplexity = Math.min(this._possibleMaximumComplexity, currentComplexity);
+        this._intervalFrameLengthEstimator.reset();
+
+        var progress = (timestamp - this._rampStartTimestamp) / this._currentRampLength;
+
+        if (progress < 1) {
+            // Reframe progress percentage so that the last interval of the ramp can sample at minimum complexity
+            progress = (timestamp - this._rampStartTimestamp) / (this._currentRampLength - this.intervalSamplingLength);
+            stage.tune(Math.max(this._minimumComplexity, Math.floor(Utilities.lerp(progress, this._maximumComplexity, this._minimumComplexity))) - currentComplexity);
+            return;
+        }
+
+        var regression = new Regression(this._sampler.samples, this._getComplexity, this._getFrameLength,
+            this._sampler.sampleCount - 1, this._rampStartIndex, { desiredFrameLength: this.frameLengthDesired });
+        this._rampRegressions.push(regression);
+
+        var frameLengthAtMaxComplexity = regression.valueAt(this._maximumComplexity);
+        if (frameLengthAtMaxComplexity < this.frameLengthRampLowerThreshold)
+            this._possibleMaximumComplexity = Math.floor(Utilities.lerp(Utilities.progressValue(this.frameLengthRampLowerThreshold, frameLengthAtMaxComplexity, this._lastTierFrameLength), this._maximumComplexity, this._lastTierComplexity));
+        // If the regression doesn't fit the first segment at all, keep the minimum bound at 1
+        if ((timestamp - this._sampler.samples[0][this._sampler.sampleCount - regression.n1]) / this._currentRampLength < .25)
+            this._possibleMinimumComplexity = 1;
+
+        this._minimumComplexityEstimator.sample(this._possibleMinimumComplexity);
+        this._minimumComplexity = Math.round(this._minimumComplexityEstimator.mean());
+
+        if (frameLengthAtMaxComplexity < this.frameLengthRampUpperThreshold) {
+            this._changePointEstimator.sample(regression.complexity);
+            // Ideally we'll target the change point in the middle of the ramp. If the range of the ramp is too small, there isn't enough
+            // range along the complexity (x) axis for a good regression calculation to be made, so force at least a range of 5
+            // particles. Make it possible to increase the maximum complexity in case unexpected noise caps the regression too low.
+            this._maximumComplexity = Math.round(this._minimumComplexity +
+                Math.max(5,
+                    this._possibleMaximumComplexity - this._minimumComplexity,
+                    (this._changePointEstimator.mean() - this._minimumComplexity) * 2));
+        } else {
+            // The slowest samples weighed the regression too heavily
+            this._maximumComplexity = Math.max(Math.round(.8 * this._maximumComplexity), this._minimumComplexity + 5);
+        }
+
+        // Next ramp
+        stage.tune(this._maximumComplexity - stage.complexity());
+        this._rampDidWarmup = false;
+        // Start timestamp represents start of ramp iteration and warm up
+        this._rampStartTimestamp = timestamp;
+        this._possibleMinimumComplexity = 1;
+        this._possibleMaximumComplexity = this._maximumComplexity;
+    },
+
+    _getComplexity: function(samples, i) {
+        return samples[1][i];
+    },
+
+    _getFrameLength: function(samples, i) {
+        return samples[0][i] - samples[0][i - 1];
+    },
+
+    processSamples: function(results)
+    {
+        results[Strings.json.marks] = this._processMarks();
+        // Have samplingTimeOffset represent time 0
+        var startTimestamp = this._marks[Strings.json.samplingStartTimeOffset].time;
+        for (var markName in results[Strings.json.marks]) {
+            results[Strings.json.marks][markName].time -= startTimestamp;
+        }
+
+        results[Strings.json.samples] = {};
+
+        var controllerSamples = this._processControllerSamples();
+        results[Strings.json.samples][Strings.json.controller] = controllerSamples;
+        controllerSamples.forEach(function(timeSample) {
+            controllerSamples.setFieldInDatum(timeSample, Strings.json.time, controllerSamples.getFieldInDatum(timeSample, Strings.json.time) - startTimestamp);
+        });
+
+        // Aggregate all of the ramps into one big complexity-frameLength dataset
+        var complexitySamples = new SampleData(controllerSamples.fieldMap);
+        results[Strings.json.samples][Strings.json.complexity] = complexitySamples;
+
+        results[Strings.json.controller] = [];
+        this._rampRegressions.forEach(function(ramp) {
+            var startIndex = ramp.startIndex, endIndex = ramp.endIndex;
+            var startTime = controllerSamples.getFieldInDatum(startIndex, Strings.json.time);
+            var endTime = controllerSamples.getFieldInDatum(endIndex, Strings.json.time);
+            var startComplexity = controllerSamples.getFieldInDatum(startIndex, Strings.json.complexity);
+            var endComplexity = controllerSamples.getFieldInDatum(endIndex, Strings.json.complexity);
+
+            var regression = {};
+            results[Strings.json.controller].push(regression);
+
+            var percentage = (ramp.complexity - startComplexity) / (endComplexity - startComplexity);
+            var inflectionTime = startTime + percentage * (endTime - startTime);
+
+            regression[Strings.json.regressions.segment1] = [
+                [startTime, ramp.s2 + ramp.t2 * startComplexity],
+                [inflectionTime, ramp.s2 + ramp.t2 * ramp.complexity]
+            ];
+            regression[Strings.json.regressions.segment2] = [
+                [inflectionTime, ramp.s1 + ramp.t1 * ramp.complexity],
+                [endTime, ramp.s1 + ramp.t1 * endComplexity]
+            ];
+            regression[Strings.json.complexity] = ramp.complexity;
+            regression[Strings.json.regressions.startIndex] = startIndex;
+            regression[Strings.json.regressions.endIndex] = endIndex;
+            regression[Strings.json.regressions.profile] = ramp.profile;
+
+            for (var j = startIndex; j <= endIndex; ++j)
+                complexitySamples.push(controllerSamples.at(j));
+        });
+
+        this._processComplexitySamples(complexitySamples);
+    }
+});
+
+Stage = Utilities.createClass(
+    function()
+    {
+    }, {
+
+    initialize: function(benchmark)
+    {
+        this._benchmark = benchmark;
+        this._element = document.getElementById("stage");
+        this._element.setAttribute("width", document.body.offsetWidth);
+        this._element.setAttribute("height", document.body.offsetHeight);
+        this._size = Point.elementClientSize(this._element).subtract(Insets.elementPadding(this._element).size);
+    },
+
+    get element()
+    {
+        return this._element;
+    },
+
+    get size()
+    {
+        return this._size;
+    },
+
+    complexity: function()
+    {
+        return 0;
+    },
+
+    tune: function()
+    {
+        throw "Not implemented";
+    },
+
+    animate: function()
+    {
+        throw "Not implemented";
+    },
+
+    clear: function()
+    {
+        return this.tune(-this.tune(0));
+    }
+});
+
+Utilities.extendObject(Stage, {
+    random: function(min, max)
+    {
+        return (Pseudo.random() * (max - min)) + min;
+    },
+
+    randomBool: function()
+    {
+        return !!Math.round(Pseudo.random());
+    },
+
+    randomSign: function()
+    {
+        return Pseudo.random() >= .5 ? 1 : -1;
+    },
+
+    randomInt: function(min, max)
+    {
+        return Math.floor(this.random(min, max + 1));
+    },
+
+    randomPosition: function(maxPosition)
+    {
+        return new Point(this.randomInt(0, maxPosition.x), this.randomInt(0, maxPosition.y));
+    },
+
+    randomSquareSize: function(min, max)
+    {
+        var side = this.random(min, max);
+        return new Point(side, side);
+    },
+
+    randomVelocity: function(maxVelocity)
+    {
+        return this.random(maxVelocity / 8, maxVelocity);
+    },
+
+    randomAngle: function()
+    {
+        return this.random(0, Math.PI * 2);
+    },
+
+    randomColor: function()
+    {
+        var min = 32;
+        var max = 256 - 32;
+        return "#"
+            + this.randomInt(min, max).toString(16)
+            + this.randomInt(min, max).toString(16)
+            + this.randomInt(min, max).toString(16);
+    },
+
+    randomStyleMixBlendMode: function()
+    {
+        var mixBlendModeList = [
+          'normal',
+          'multiply',
+          'screen',
+          'overlay',
+          'darken',
+          'lighten',
+          'color-dodge',
+          'color-burn',
+          'hard-light',
+          'soft-light',
+          'difference',
+          'exclusion',
+          'hue',
+          'saturation',
+          'color',
+          'luminosity'
+        ];
+
+        return mixBlendModeList[this.randomInt(0, mixBlendModeList.length)];
+    },
+
+    randomStyleFilter: function()
+    {
+        var filterList = [
+            'grayscale(50%)',
+            'sepia(50%)',
+            'saturate(50%)',
+            'hue-rotate(180)',
+            'invert(50%)',
+            'opacity(50%)',
+            'brightness(50%)',
+            'contrast(50%)',
+            'blur(10px)',
+            'drop-shadow(10px 10px 10px gray)'
+        ];
+
+        return filterList[this.randomInt(0, filterList.length)];
+    },
+
+    randomElementInArray: function(array)
+    {
+        return array[Stage.randomInt(0, array.length - 1)];
+    },
+
+    rotatingColor: function(cycleLengthMs, saturation, lightness)
+    {
+        return "hsl("
+            + Stage.dateFractionalValue(cycleLengthMs) * 360 + ", "
+            + ((saturation || .8) * 100).toFixed(0) + "%, "
+            + ((lightness || .35) * 100).toFixed(0) + "%)";
+    },
+
+    // Returns a fractional value that wraps around within [0,1]
+    dateFractionalValue: function(cycleLengthMs)
+    {
+        return (Date.now() / (cycleLengthMs || 2000)) % 1;
+    },
+
+    // Returns an increasing value slowed down by factor
+    dateCounterValue: function(factor)
+    {
+        return Date.now() / factor;
+    },
+
+    randomRotater: function()
+    {
+        return new Rotater(this.random(1000, 10000));
+    }
+});
+
+Rotater = Utilities.createClass(
+    function(rotateInterval)
+    {
+        this._timeDelta = 0;
+        this._rotateInterval = rotateInterval;
+        this._isSampling = false;
+    }, {
+
+    get interval()
+    {
+        return this._rotateInterval;
+    },
+
+    next: function(timeDelta)
+    {
+        this._timeDelta = (this._timeDelta + timeDelta) % this._rotateInterval;
+    },
+
+    degree: function()
+    {
+        return (360 * this._timeDelta) / this._rotateInterval;
+    },
+
+    rotateZ: function()
+    {
+        return "rotateZ(" + Math.floor(this.degree()) + "deg)";
+    },
+
+    rotate: function(center)
+    {
+        return "rotate(" + Math.floor(this.degree()) + ", " + center.x + "," + center.y + ")";
+    }
+});
+
+Benchmark = Utilities.createClass(
+    function(stage, options)
+    {
+        this._animateLoop = this._animateLoop.bind(this);
+        this._warmupLength = options["warmup-length"];
+        this._frameCount = 0;
+        this._warmupFrameCount = options["warmup-frame-count"];
+        this._firstFrameMinimumLength = options["first-frame-minimum-length"];
+
+        this._stage = stage;
+        this._stage.initialize(this, options);
+
+        switch (options["time-measurement"])
+        {
+        case "performance":
+            if (window.performance && window.performance.now)
+                this._getTimestamp = performance.now.bind(performance);
+            else
+                this._getTimestamp = null;
+            break;
+        case "raf":
+            this._getTimestamp = null;
+            break;
+        case "date":
+            this._getTimestamp = Date.now;
+            break;
+        }
+
+        options["test-interval"] *= 1000;
+        switch (options["controller"])
+        {
+        case "fixed":
+            this._controller = new FixedController(this, options);
+            break;
+        case "adaptive":
+            this._controller = new AdaptiveController(this, options);
+            break;
+        case "ramp":
+            this._controller = new RampController(this, options);
+            break;
+        }
+    }, {
+
+    get stage()
+    {
+        return this._stage;
+    },
+
+    get timestamp()
+    {
+        return this._currentTimestamp - this._benchmarkStartTimestamp;
+    },
+
+    backgroundColor: function()
+    {
+        var stage = window.getComputedStyle(document.getElementById("stage"));
+        return stage["background-color"];
+    },
+
+    run: function()
+    {
+        return this.waitUntilReady().then(function() {
+            this._finishPromise = new SimplePromise;
+            this._previousTimestamp = undefined;
+            this._didWarmUp = false;
+            this._stage.tune(this._controller.initialComplexity - this._stage.complexity());
+            this._animateLoop();
+            return this._finishPromise;
+        }.bind(this));
+    },
+
+    // Subclasses should override this if they have setup to do prior to commencing.
+    waitUntilReady: function()
+    {
+        var promise = new SimplePromise;
+        promise.resolve();
+        return promise;
+    },
+
+    _animateLoop: function(timestamp)
+    {
+        timestamp = (this._getTimestamp && this._getTimestamp()) || timestamp;
+        this._currentTimestamp = timestamp;
+
+        if (this._controller.shouldStop(timestamp)) {
+            this._finishPromise.resolve(this._controller.results());
+            return;
+        }
+
+        if (!this._didWarmUp) {
+            if (!this._previousTimestamp) {
+                this._previousTimestamp = timestamp;
+                this._benchmarkStartTimestamp = timestamp;
+            } else if (timestamp - this._previousTimestamp >= this._warmupLength && this._frameCount >= this._warmupFrameCount) {
+                this._didWarmUp = true;
+                this._benchmarkStartTimestamp = timestamp;
+                this._controller.start(timestamp, this._stage);
+                this._previousTimestamp = timestamp;
+
+                while (this._getTimestamp && this._getTimestamp() - timestamp < this._firstFrameMinimumLength) {
+                }
+            }
+
+            this._stage.animate(0);
+            ++this._frameCount;
+            requestAnimationFrame(this._animateLoop);
+            return;
+        }
+
+        this._controller.update(timestamp, this._stage);
+        this._stage.animate(timestamp - this._previousTimestamp);
+        this._previousTimestamp = timestamp;
+        requestAnimationFrame(this._animateLoop);
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/tests/resources/math.js b/third_party/blink/perf_tests/MotionMark/tests/resources/math.js
new file mode 100644
index 0000000..4080493
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/resources/math.js
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+SimpleKalmanEstimator = Utilities.createSubclass(Experiment,
+    function(processError, measurementError) {
+        Experiment.call(this, false);
+        var error = .5 * (Math.sqrt(processError * processError + 4 * processError * measurementError) - processError);
+        this._gain = error / (error + measurementError);
+    }, {
+
+    sample: function(newMeasurement)
+    {
+        if (!this._initialized) {
+            this._initialized = true;
+            this.estimate = newMeasurement;
+            return;
+        }
+
+        this.estimate = this.estimate + this._gain * (newMeasurement - this.estimate);
+    },
+
+    reset: function()
+    {
+        Experiment.prototype.reset.call(this);
+        this._initialized = false;
+        this.estimate = 0;
+    }
+});
+
+PIDController = Utilities.createClass(
+    function(ysp)
+    {
+        this._ysp = ysp;
+        this._out = 0;
+
+        this._Kp = 0;
+        this._stage = PIDController.stages.WARMING;
+
+        this._eold = 0;
+        this._I = 0;
+    }, {
+
+    // Determines whether the current y is
+    //  before ysp => (below ysp if ysp > y0) || (above ysp if ysp < y0)
+    //  after ysp => (above ysp if ysp > y0) || (below ysp if ysp < y0)
+    _yPosition: function(y)
+    {
+        return (y < this._ysp) == (this._y0 < this._ysp)
+            ? PIDController.yPositions.BEFORE_SETPOINT
+            : PIDController.yPositions.AFTER_SETPOINT;
+    },
+
+    // Calculate the ultimate distance from y0 after time t. We want to move very
+    // slowly at the beginning to see how adding few items to the test can affect
+    // its output. The complexity of a single item might be big enough to keep the
+    // proportional gain very small but achieves the desired progress. But if y does
+    // not change significantly after adding few items, that means we need a much
+    // bigger gain. So we need to move over a cubic curve which increases very
+    // slowly with small t values but moves very fast with larger t values.
+    // The basic formula is: y = t^3
+    // Change the formula to reach y=1 after 1000 ms: y = (t/1000)^3
+    // Change the formula to reach y=(ysp - y0) after 1000 ms: y = (ysp - y0) * (t/1000)^3
+    _distanceUltimate: function(t)
+    {
+        return (this._ysp - this._y0) * Math.pow(t / 1000, 3);
+    },
+
+    // Calculates the distance of y relative to y0. It also ensures we do not return
+    // zero by returning a epsilon value in the same direction as ultimate distance.
+    _distance: function(y, du)
+    {
+        const epsilon = 0.0001;
+        var d  = y - this._y0;
+        return du < 0 ? Math.min(d, -epsilon) : Math.max(d, epsilon);
+    },
+
+    // Decides how much the proportional gain should be increased during the manual
+    // gain stage. We choose to use the ratio of the ultimate distance to the current
+    // distance as an indication of how much the system is responsive. We want
+    // to keep the increment under control so it does not cause the system instability
+    // So we choose to take the natural logarithm of this ratio.
+    _gainIncrement: function(t, y, e)
+    {
+        var du = this._distanceUltimate(t);
+        var d = this._distance(y, du);
+        return Math.log(du / d) * 0.1;
+    },
+
+    // Update the stage of the controller based on its current stage and the system output
+    _updateStage: function(y)
+    {
+        var yPosition = this._yPosition(y);
+
+        switch (this._stage) {
+        case PIDController.stages.WARMING:
+            if (yPosition == PIDController.yPositions.AFTER_SETPOINT)
+                this._stage = PIDController.stages.OVERSHOOT;
+            break;
+
+        case PIDController.stages.OVERSHOOT:
+            if (yPosition == PIDController.yPositions.BEFORE_SETPOINT)
+                this._stage = PIDController.stages.UNDERSHOOT;
+            break;
+
+        case PIDController.stages.UNDERSHOOT:
+            if (yPosition == PIDController.yPositions.AFTER_SETPOINT)
+                this._stage = PIDController.stages.SATURATE;
+            break;
+        }
+    },
+
+    // Manual tuning is used before calculating the PID controller gains.
+    _tuneP: function(e)
+    {
+        // The output is the proportional term only.
+        return this._Kp * e;
+    },
+
+    // PID tuning function. Kp, Ti and Td were already calculated
+    _tunePID: function(h, y, e)
+    {
+        // Proportional term.
+        var P = this._Kp * e;
+
+        // Integral term is the area under the curve starting from the beginning
+        // till the current time.
+        this._I += (this._Kp / this._Ti) * ((e + this._eold) / 2) * h;
+
+        // Derivative term is the slope of the curve at the current time.
+        var D = (this._Kp * this._Td) * (e - this._eold) / h;
+
+        // The output is a PID function.
+       return P + this._I + D;
+    },
+
+    // Apply different strategies for the tuning based on the stage of the controller.
+    _tune: function(t, h, y, e)
+    {
+        switch (this._stage) {
+        case PIDController.stages.WARMING:
+            // This is the first stage of the Zieglerâ€Nichols method. It increments
+            // the proportional gain till the system output passes the set-point value.
+            if (typeof this._y0 == "undefined") {
+                // This is the first time a tuning value is required. We want the test
+                // to add only one item. So we need to return -1 which forces us to
+                // choose the initial value of Kp to be = -1 / e
+                this._y0 = y;
+                this._Kp = -1 / e;
+            } else {
+                // Keep incrementing the Kp as long as we have not reached the
+                // set-point yet
+                this._Kp += this._gainIncrement(t, y, e);
+            }
+
+            return this._tuneP(e);
+
+        case PIDController.stages.OVERSHOOT:
+            // This is the second stage of the Zieglerâ€Nichols method. It measures the
+            // oscillation period.
+            if (typeof this._t0 == "undefined") {
+                // t is the time of the beginning of the first overshot
+                this._t0 = t;
+                this._Kp /= 2;
+            }
+
+            return this._tuneP(e);
+
+        case PIDController.stages.UNDERSHOOT:
+            // This is the end of the Zieglerâ€Nichols method. We need to calculate the
+            // integral and derivative periods.
+            if (typeof this._Ti == "undefined") {
+                // t is the time of the end of the first overshot
+                var Tu = t - this._t0;
+
+                // Calculate the system parameters from Kp and Tu assuming
+                // a "some overshoot" control type. See:
+                // https://en.wikipedia.org/wiki/Ziegler%E2%80%93Nichols_method
+                this._Ti = Tu / 2;
+                this._Td = Tu / 3;
+                this._Kp = 0.33 * this._Kp;
+
+                // Calculate the tracking time.
+                this._Tt = Math.sqrt(this._Ti * this._Td);
+            }
+
+            return this._tunePID(h, y, e);
+
+        case PIDController.stages.SATURATE:
+            return this._tunePID(h, y, e);
+        }
+
+        return 0;
+    },
+
+    // Ensures the system does not fluctuates.
+    _saturate: function(v, e)
+    {
+        var u = v;
+
+        switch (this._stage) {
+        case PIDController.stages.OVERSHOOT:
+        case PIDController.stages.UNDERSHOOT:
+            // Calculate the min-max values of the saturation actuator.
+            if (typeof this._min == "undefined")
+                this._min = this._max = this._out;
+            else {
+                this._min = Math.min(this._min, this._out);
+                this._max = Math.max(this._max, this._out);
+            }
+            break;
+
+        case PIDController.stages.SATURATE:
+            const limitPercentage = 0.90;
+            var min = this._min > 0 ? Math.min(this._min, this._max * limitPercentage) : this._min;
+            var max = this._max < 0 ? Math.max(this._max, this._min * limitPercentage) : this._max;
+            var out = this._out + u;
+
+            // Clip the controller output to the min-max values
+            out = Math.max(Math.min(max, out), min);
+            u = out - this._out;
+
+            // Apply the back-calculation and tracking
+            if (u != v)
+                u += (this._Kp * this._Tt / this._Ti) * e;
+            break;
+        }
+
+        this._out += u;
+        return u;
+    },
+
+    // Called from the benchmark to tune its test. It uses Ziegler-Nichols method
+    // to calculate the controller parameters. It then returns a PID tuning value.
+    tune: function(t, h, y)
+    {
+        this._updateStage(y);
+
+        // Current error.
+        var e = this._ysp - y;
+        var v = this._tune(t, h, y, e);
+
+        // Save e for the next call.
+        this._eold = e;
+
+        // Apply back-calculation and tracking to avoid integrator windup
+        return this._saturate(v, e);
+    }
+});
+
+Utilities.extendObject(PIDController, {
+    // This enum will be used to tell whether the system output (or the controller input)
+    // is moving towards the set-point or away from it.
+    yPositions: {
+        BEFORE_SETPOINT: 0,
+        AFTER_SETPOINT: 1
+    },
+
+    // The Ziegler-Nichols method for is used tuning the PID controller. The workflow of
+    // the tuning is split into four stages. The first two stages determine the values
+    // of the PID controller gains. During these two stages we return the proportional
+    // term only. The third stage is used to determine the min-max values of the
+    // saturation actuator. In the last stage back-calculation and tracking are applied
+    // to avoid integrator windup. During the last two stages, we return a PID control
+    // value.
+    stages: {
+        WARMING: 0,         // Increase the value of the Kp until the system output reaches ysp.
+        OVERSHOOT: 1,       // Measure the oscillation period and the overshoot value
+        UNDERSHOOT: 2,      // Return PID value and measure the undershoot value
+        SATURATE: 3         // Return PID value and apply back-calculation and tracking.
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/tests/resources/stage.css b/third_party/blink/perf_tests/MotionMark/tests/resources/stage.css
new file mode 100644
index 0000000..c96d041
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/resources/stage.css
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+html {
+    height: 100%;
+}
+body {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    background-color: rgb(241, 241, 241);
+    font-family: "Helvetica Neue", Helvetica, Verdana, sans-serif;
+}
+
+#stage {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    background-color: rgb(241, 241, 241);
+    overflow: hidden;
+}
+
+#center-text {
+    position: absolute;
+    z-index: 3;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+}
diff --git a/third_party/blink/perf_tests/MotionMark/tests/resources/star.svg b/third_party/blink/perf_tests/MotionMark/tests/resources/star.svg
new file mode 100644
index 0000000..3c46ae0
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/resources/star.svg
@@ -0,0 +1,8 @@
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1 1">
+    <defs>
+        <mask id="star-mask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
+            <path fill="white" d="M.50,0L.38,.38L0,.38L.30,.60L.18,1L.50,.75L.82,1L.70,.60L1,.38L.62,.38z" />
+        </mask>
+    </defs>
+    <path d="M.50,0L.38,.38L0,.38L.30,.60L.18,1L.50,.75L.82,1L.70,.60L1,.38L.62,.38z" fill="white" />
+</svg>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/resources/yin-yang.png b/third_party/blink/perf_tests/MotionMark/tests/resources/yin-yang.png
new file mode 100644
index 0000000..3162f6e
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/resources/yin-yang.png
Binary files differ
diff --git a/third_party/blink/perf_tests/MotionMark/tests/resources/yin-yang.svg b/third_party/blink/perf_tests/MotionMark/tests/resources/yin-yang.svg
new file mode 100644
index 0000000..4412626
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/resources/yin-yang.svg
@@ -0,0 +1,17 @@
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">

+    <defs>

+        <clipPath id="left-half">

+            <rect width="100" height="200"/>

+        </clipPath>

+        <clipPath id="right-half">

+            <rect x="100" width="100" height="200"/>

+        </clipPath>

+    </defs>

+    <circle cx="100" cy="100" r="98" fill="none" stroke="green" stroke-width="2"/>

+    <circle cx="100" cy="100" r="98" fill="white" clip-path="url(#left-half)"/>

+    <circle cx="100" cy="100" r="98" fill="green" clip-path="url(#right-half)"/>

+    <circle cx="100" cy="50"  r="49" fill="green"/>

+    <circle cx="100" cy="148" r="49" fill="white"/>

+    <circle cx="100" cy="50"  r="10" fill="white"/>    

+    <circle cx="100" cy="148" r="10" fill="green"/>

+</svg>

diff --git a/third_party/blink/perf_tests/MotionMark/tests/simple/resources/simple-canvas-paths.js b/third_party/blink/perf_tests/MotionMark/tests/simple/resources/simple-canvas-paths.js
new file mode 100644
index 0000000..b7a31e2
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/simple/resources/simple-canvas-paths.js
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+// === PAINT OBJECTS ===
+
+CanvasLineSegment = Utilities.createClass(
+    function(stage) {
+        var radius = Stage.randomInt(10, 100);
+        var center = Stage.randomPosition(stage.size);
+        var delta = Point.pointOnCircle(Stage.randomAngle(), radius/2);
+
+        this._point1 = center.add(delta);
+        this._point2 = center.subtract(delta);
+        this._color = Stage.randomColor();
+        this._lineWidth = Stage.randomInt(1, 100);
+    }, {
+
+    draw: function(context) {
+        context.strokeStyle = this._color;
+        context.lineWidth = this._lineWidth;
+        context.beginPath();
+        context.moveTo(this._point1.x, this._point1.y);
+        context.lineTo(this._point2.x, this._point2.y);
+        context.stroke();
+    }
+});
+
+CanvasLinePoint = Utilities.createClass(
+    function(stage, coordinateMaximumFactor) {
+        var pointMaximum = new Point(Math.min(stage.size.x, coordinateMaximumFactor * stage.size.x), Math.min(stage.size.y, coordinateMaximumFactor * stage.size.y));
+        this._point = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2));
+    }, {
+
+    draw: function(context) {
+        context.lineTo(this._point.x, this._point.y);
+    }
+})
+
+CanvasQuadraticSegment = Utilities.createClass(
+    function(stage) {
+        var maxSize = Stage.randomInt(20, 200);
+        var toCenter = Stage.randomPosition(stage.size).subtract(new Point(maxSize/2, maxSize/2));
+
+        this._point1 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._point2 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._point3 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._color = Stage.randomColor();
+        this._lineWidth = Stage.randomInt(1, 50);
+    }, {
+
+    draw: function(context) {
+        context.strokeStyle = this._color;
+        context.lineWidth = this._lineWidth;
+        context.beginPath();
+        context.moveTo(this._point1.x, this._point1.y);
+        context.quadraticCurveTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y);
+        context.stroke();
+    }
+});
+
+CanvasQuadraticPoint = Utilities.createClass(
+    function(stage, coordinateMaximumFactor) {
+        var pointMaximum = Stage.randomPosition(new Point(Math.min(stage.size.x, coordinateMaximumFactor * stage.size.x), Math.min(stage.size.y, coordinateMaximumFactor * stage.size.y)));
+        this._point1 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2));
+        this._point2 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2));
+    }, {
+
+    draw: function(context) {
+        context.quadraticCurveTo(this._point1.x, this._point1.y, this._point2.x, this._point2.y);
+    }
+});
+
+CanvasBezierSegment = Utilities.createClass(
+    function(stage) {
+        var maxSize = Stage.randomInt(20, 200);
+        var toCenter = Stage.randomPosition(stage.size).subtract(new Point(maxSize/2, maxSize/2));
+
+        this._point1 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._point2 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._point3 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._point4 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._color = Stage.randomColor();
+        this._lineWidth = Stage.randomInt(1, 50);
+    }, {
+
+    draw: function(context) {
+        context.strokeStyle = this._color;
+        context.lineWidth = this._lineWidth;
+        context.beginPath();
+        context.moveTo(this._point1.x, this._point1.y);
+        context.bezierCurveTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y, this._point4.x, this._point4.y);
+        context.stroke();
+    }
+});
+
+CanvasBezierPoint = Utilities.createClass(
+    function(stage, coordinateMaximumFactor) {
+        var pointMaximum = Stage.randomPosition(new Point(Math.min(stage.size.x, coordinateMaximumFactor * stage.size.x), Math.min(stage.size.y, coordinateMaximumFactor * stage.size.y)));
+        this._point1 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2));
+        this._point2 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2));
+        this._point3 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2));
+    }, {
+
+    draw: function(context) {
+        context.bezierCurveTo(this._point1.x, this._point1.y, this._point2.x, this._point2.y, this._point3.x, this._point3.y);
+    }
+});
+
+CanvasArcToSegment = Utilities.createClass(
+    function(stage) {
+        var maxSize = Stage.randomInt(20, 200);
+        var toCenter = Stage.randomPosition(stage.size).subtract(new Point(maxSize/2, maxSize/2));
+
+        this._point1 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._point2 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._point3 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._radius = Stage.randomInt(20, 200);
+        this._color = Stage.randomColor();
+        this._lineWidth = Stage.randomInt(1, 50);
+    }, {
+
+    draw: function(context) {
+        context.strokeStyle = this._color;
+        context.lineWidth = this._lineWidth;
+        context.beginPath();
+        context.moveTo(this._point1.x, this._point1.y);
+        context.arcTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y, this._radius);
+        context.stroke();
+    }
+});
+
+CanvasArcToSegmentFill = Utilities.createClass(
+    function(stage) {
+        CanvasArcToSegment.call(this, stage);
+    }, {
+
+    draw: function(context) {
+        context.fillStyle = this._color;
+        context.beginPath();
+        context.moveTo(this._point1.x, this._point1.y);
+        context.arcTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y, this._radius);
+        context.fill();
+    }
+});
+
+CanvasArcSegment = Utilities.createClass(
+    function(stage) {
+        var maxSize = Stage.randomInt(20, 200);
+        var toCenter = Stage.randomPosition(stage.size).subtract(new Point(maxSize/2, maxSize/2));
+
+        this._point = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter);
+        this._radius = Stage.randomInt(20, 200);
+        this._startAngle = Stage.randomAngle();
+        this._endAngle = Stage.randomAngle();
+        this._counterclockwise = Stage.randomBool();
+        this._color = Stage.randomColor();
+        this._lineWidth = Stage.randomInt(1, 50);
+    }, {
+
+    draw: function(context) {
+        context.strokeStyle = this._color;
+        context.lineWidth = this._lineWidth;
+        context.beginPath();
+        context.arc(this._point.x, this._point.y, this._radius, this._startAngle, this._endAngle, this._counterclockwise);
+        context.stroke();
+    }
+});
+
+CanvasArcSegmentFill = Utilities.createClass(
+    function(stage) {
+        CanvasArcSegment.call(this, stage);
+    }, {
+
+    draw: function(context) {
+        context.fillStyle = this._color;
+        context.beginPath();
+        context.arc(this._point.x, this._point.y, this._radius, this._startAngle, this._endAngle, this._counterclockwise);
+        context.fill();
+    }
+});
+
+CanvasRect = Utilities.createClass(
+    function(stage) {
+        this._width = Stage.randomInt(20, 200);
+        this._height = Stage.randomInt(20, 200);
+        this._point = Stage.randomPosition(stage.size).subtract(new Point(this._width/2, this._height/2));
+        this._color = Stage.randomColor();
+        this._lineWidth = Stage.randomInt(1, 20);
+    }, {
+
+    draw: function(context) {
+        context.strokeStyle = this._color;
+        context.lineWidth = this._lineWidth;
+        context.beginPath();
+        context.rect(this._point.x, this._point.y, this._width, this._height);
+        context.stroke();
+    }
+});
+
+CanvasRectFill = Utilities.createClass(
+    function(stage) {
+        CanvasRect.call(this, stage);
+    }, {
+
+    draw: function(context) {
+        context.fillStyle = this._color;
+        context.beginPath();
+        context.rect(this._point.x, this._point.y, this._width, this._height);
+        context.fill();
+    }
+});
+
+CanvasEllipse = Utilities.createClass(
+    function(stage) {
+        this._radius = new Point(Stage.randomInt(20, 200), Stage.randomInt(20, 200));
+        var toCenter = Stage.randomPosition(stage.size).subtract(this._radius.multiply(.5));
+
+        this._center = Stage.randomPosition(this._radius).add(toCenter);
+        this._rotation = Stage.randomAngle();
+        this._startAngle = Stage.randomAngle();
+        this._endAngle = Stage.randomAngle();
+        this._anticlockwise = Stage.randomBool();
+        this._color = Stage.randomColor();
+        this._lineWidth = Stage.randomInt(1, 20);
+    }, {
+
+    draw: function(context) {
+        context.strokeStyle = this._color;
+        context.lineWidth = this._lineWidth;
+        context.beginPath();
+        context.ellipse(this._center.x, this._center.y, this._radius.width, this._radius.height, this._rotation, this._startAngle, this._endAngle, this._anticlockwise);
+        context.stroke();
+    }
+});
+
+CanvasEllipseFill = Utilities.createClass(
+    function(stage) {
+        CanvasEllipse.call(this, stage);
+    }, {
+
+    draw: function(context) {
+        context.fillStyle = this._color;
+        context.beginPath();
+        context.ellipse(this._center.x, this._center.y, this._radius.width, this._radius.height, this._rotation, this._startAngle, this._endAngle, this._anticlockwise);
+        context.fill();
+    }
+});
+
+CanvasSpreadSheets = Utilities.createClass(
+    function(stage) {
+        // Some good dark color for writing text in spreadsheet.
+        var dark_colors = ['#000000', '#404040', '#00008B', '#442D16', '#7E0000'];
+        // Some good light color for filling cells in spreadsheet.
+        var light_colors = ['#ADFF2F', '#ADD8E6', '#FFC0CB', '#E3C8C8', '#EBEEAF'];
+        // Possible text alignment in spreadsheet.
+        var align = ['left', 'right', 'center', 'start' , 'end']
+        this._text_color = dark_colors[Stage.randomInt(0, 5)];
+        this._fill_color = light_colors[Stage.randomInt(0, 5)];
+        this._text_align = align[Stage.randomInt(0, 5)];
+        this._start = Stage.randomPosition(stage.size)
+        this._color = Stage.randomColor();
+        this._cell_width = Stage.randomInt(90, 150);
+        this._cell_height = Stage.randomInt(20, 30);
+        this._font = Stage.randomInt(10, 40) + 'px Arial';
+        this._border_style_index = Stage.randomInt(0, 3);
+        this._color = Stage.randomColor();
+    }, {
+    draw: function(context) {
+        context.save();
+        rectPath = new Path2D();
+        rectPath.rect(this._start.x, this._start.y, this._cell_width, this._cell_height);
+        context.clip(rectPath);
+        context.beginPath();
+        context.globalAlpha = 0.5;
+        context.fillStyle = this._fill_color;
+        context.fill(rectPath);
+        context.globalAlpha = 1;
+        context.font = this._font;
+        context.fillStyle = this._text_color;
+        context.textAlign = this._text_align;
+        context.fillText("hello world", (this._start.x + this._start.x + this._cell_width)/2, this._start.y + this._cell_height);
+        if (this._border_style_index === 0) {
+            context.setLineDash([5, 5]);
+        } else if (this._border_style_index === 1) {
+            context.globalAlpha = 0.5;
+        } else {
+            context.strokeStyle = "#000000";
+        }
+        context.stroke(rectPath);
+        context.restore();
+    }
+});
+
+CanvasStroke = Utilities.createClass(
+    function (stage) {
+        this._object = new (Stage.randomElementInArray(this.objectTypes))(stage);
+    }, {
+
+    objectTypes: [
+        CanvasQuadraticSegment,
+        CanvasBezierSegment,
+        CanvasArcToSegment,
+        CanvasArcSegment,
+        CanvasRect,
+        CanvasEllipse
+    ],
+
+    draw: function(context) {
+        this._object.draw(context);
+    }
+});
+
+CanvasFill = Utilities.createClass(
+    function (stage) {
+        this._object = new (Stage.randomElementInArray(this.objectTypes))(stage);
+    }, {
+
+    objectTypes: [
+        CanvasArcToSegmentFill,
+        CanvasArcSegmentFill,
+        CanvasRectFill,
+        CanvasEllipseFill
+    ],
+
+    draw: function(context) {
+        this._object.draw(context);
+    }
+});
+
+// === STAGES ===
+
+SimpleCanvasPathStrokeStage = Utilities.createSubclass(SimpleCanvasStage,
+    function(canvasObject) {
+        SimpleCanvasStage.call(this, canvasObject);
+    }, {
+
+    animate: function()
+    {
+        var context = this.context;
+        context.clearRect(0, 0, this.size.x, this.size.y);
+        context.lineWidth = Stage.randomInt(1, 20);
+        context.strokeStyle = Stage.rotatingColor();
+        context.beginPath();
+        context.moveTo(this.size.x / 2, this.size.y / 2);
+        for (var i = 0, length = this.offsetIndex; i < length; ++i)
+            this.objects[i].draw(context);
+        context.stroke();
+    }
+});
+
+SimpleCanvasPathFillStage = Utilities.createSubclass(SimpleCanvasStage,
+    function(canvasObject) {
+        SimpleCanvasStage.call(this, canvasObject);
+    }, {
+
+    animate: function()
+    {
+        var context = this.context;
+        context.clearRect(0, 0, this.size.x, this.size.y);
+        context.fillStyle = Stage.rotatingColor();
+        context.beginPath();
+        context.moveTo(this.size.x / 2, this.size.y / 2);
+        for (var i = 0, length = this.offsetIndex; i < length; ++i)
+            this.objects[i].draw(context);
+        context.fill();
+    }
+});
+
+CanvasLineSegmentStage = Utilities.createSubclass(SimpleCanvasStage,
+    function()
+    {
+        SimpleCanvasStage.call(this, CanvasLineSegment);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        SimpleCanvasStage.prototype.initialize.call(this, benchmark, options);
+        this.context.lineCap = options["lineCap"] || "butt";
+    }
+});
+
+CanvasLinePathStage = Utilities.createSubclass(SimpleCanvasPathStrokeStage,
+    function()
+    {
+        SimpleCanvasPathStrokeStage.call(this, CanvasLinePoint);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        SimpleCanvasPathStrokeStage.prototype.initialize.call(this, benchmark, options);
+        this.context.lineJoin = options["lineJoin"] || "bevel";
+    }
+});
+
+CanvasLineDashStage = Utilities.createSubclass(SimpleCanvasStage,
+    function()
+    {
+        SimpleCanvasStage.call(this, CanvasLinePoint);
+        this._step = 0;
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        SimpleCanvasStage.prototype.initialize.call(this, benchmark, options);
+        this.context.setLineDash([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+        this.context.lineWidth = 1;
+        this.context.strokeStyle = "#000";
+    },
+
+    animate: function()
+    {
+        var context = this.context;
+        context.clearRect(0, 0, this.size.x, this.size.y);
+        context.lineDashOffset = this._step++;
+        context.beginPath();
+        context.moveTo(this.size.x / 2, this.size.y / 2);
+        for (var i = 0, length = this.offsetIndex; i < length; ++i)
+            this.objects[i].draw(context);
+        context.stroke();
+    }
+});
+
+// === BENCHMARK ===
+
+CanvasPathBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        var stage;
+        switch (options["pathType"]) {
+        case "line":
+            stage = new CanvasLineSegmentStage();
+            break;
+        case "linePath": {
+            if ("lineJoin" in options)
+                stage = new CanvasLinePathStage();
+            if ("lineDash" in options)
+                stage = new CanvasLineDashStage();
+            break;
+        }
+        case "quadratic":
+            stage = new SimpleCanvasStage(CanvasQuadraticSegment);
+            break;
+        case "quadraticPath":
+            stage = new SimpleCanvasPathStrokeStage(CanvasQuadraticPoint);
+            break;
+        case "bezier":
+            stage = new SimpleCanvasStage(CanvasBezierSegment);
+            break;
+        case "bezierPath":
+            stage = new SimpleCanvasPathStrokeStage(CanvasBezierPoint);
+            break;
+        case "arcTo":
+            stage = new SimpleCanvasStage(CanvasArcToSegment);
+            break;
+        case "arc":
+            stage = new SimpleCanvasStage(CanvasArcSegment);
+            break;
+        case "rect":
+            stage = new SimpleCanvasStage(CanvasRect);
+            break;
+        case "ellipse":
+            stage = new SimpleCanvasStage(CanvasEllipse);
+            break;
+        case "lineFill":
+            stage = new SimpleCanvasPathFillStage(CanvasLinePoint);
+            break;
+        case "quadraticFill":
+            stage = new SimpleCanvasPathFillStage(CanvasQuadraticPoint);
+            break;
+        case "bezierFill":
+            stage = new SimpleCanvasPathFillStage(CanvasBezierPoint);
+            break;
+        case "arcToFill":
+            stage = new SimpleCanvasStage(CanvasArcToSegmentFill);
+            break;
+        case "arcFill":
+            stage = new SimpleCanvasStage(CanvasArcSegmentFill);
+            break;
+        case "rectFill":
+            stage = new SimpleCanvasStage(CanvasRectFill);
+            break;
+        case "ellipseFill":
+            stage = new SimpleCanvasStage(CanvasEllipseFill);
+            break;
+        case "spreadSheets":
+            stage = new SimpleCanvasStage(CanvasSpreadSheets);
+            break;
+        case "strokes":
+            stage = new SimpleCanvasStage(CanvasStroke);
+            break;
+        case "fills":
+            stage = new SimpleCanvasStage(CanvasFill);
+            break;
+        }
+
+        Benchmark.call(this, stage, options);
+    }
+);
+
+window.benchmarkClass = CanvasPathBenchmark;
+
+})();
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/MotionMark/tests/simple/resources/simple-canvas.js b/third_party/blink/perf_tests/MotionMark/tests/simple/resources/simple-canvas.js
new file mode 100644
index 0000000..b3810e1
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/simple/resources/simple-canvas.js
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+Utilities.extendObject(SimpleCanvasStage.prototype, {
+    tune: function(count)
+    {
+        if (count == 0)
+            return;
+
+        if (count < 0) {
+            this.offsetIndex = Math.max(this.offsetIndex + count, 0);
+            return;
+        }
+
+        this.offsetIndex = this.offsetIndex + count;
+        if (this.offsetIndex > this.objects.length) {
+            // For some tests, it may be easier to see how well the test is going
+            // by limiting the range of coordinates in which new objects can reside
+            var coordinateMaximumFactor = Math.min(this.objects.length, Math.min(this.size.x, this.size.y)) / Math.min(this.size.x, this.size.y);
+            var newIndex = this.offsetIndex - this.objects.length;
+            for (var i = 0; i < newIndex; ++i)
+                this.objects.push(new this._canvasObject(this, coordinateMaximumFactor));
+        }
+    },
+
+    animate: function()
+    {
+        var context = this.context;
+        context.clearRect(0, 0, this.size.x, this.size.y);
+        for (var i = 0, length = this.offsetIndex; i < length; ++i)
+            this.objects[i].draw(context);
+    },
+
+    complexity: function()
+    {
+        return this.offsetIndex;
+    }
+});
diff --git a/third_party/blink/perf_tests/MotionMark/tests/simple/resources/tiled-canvas-image.js b/third_party/blink/perf_tests/MotionMark/tests/simple/resources/tiled-canvas-image.js
new file mode 100644
index 0000000..3f0700c
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/simple/resources/tiled-canvas-image.js
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+CanvasImageTile = Utilities.createClass(
+    function(stage, source)
+    {
+        this._context = stage.context;
+        this._size = stage.tileSize;
+        this.source = source;
+    }, {
+
+    getImageData: function()
+    {
+        this._imagedata = this._context.getImageData(this.source.x, this.source.y, this._size.width, this._size.height);
+    },
+
+    putImageData: function(destination)
+    {
+        this._context.putImageData(this._imagedata, destination.x, destination.y);
+    }
+});
+
+TiledCanvasImageStage = Utilities.createSubclass(Stage,
+    function(element, options)
+    {
+        Stage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+        this.context = this.element.getContext("2d");
+        this._setupTiles();
+    },
+
+    _setupTiles: function()
+    {
+        const maxTilesPerRow = 50;
+        const maxTilesPerCol = 50;
+
+        this.tileSize = this.size.multiply(new Point(1 / maxTilesPerRow, 1 / maxTilesPerCol));
+
+        this._tiles = new Array(maxTilesPerRow * maxTilesPerCol);
+
+        var source = Point.zero;
+        for (var index = 0; index < this._tiles.length; ++index) {
+            this._tiles[index] = new CanvasImageTile(this, source);
+            source = this._nextTilePosition(source);
+        }
+
+        this._ctiles = 0;
+    },
+
+    _nextTilePosition: function(destination)
+    {
+        var next = destination.add(this.tileSize);
+
+        if (next.x >= this._size.width)
+            return new Point(0, next.y >= this._size.height ? 0 : next.y);
+
+        return new Point(next.x, destination.y);
+    },
+
+    tune: function(count)
+    {
+        this._ctiles += count;
+
+        this._ctiles = Math.max(this._ctiles, 0);
+        this._ctiles = Math.min(this._ctiles, this._tiles.length);
+    },
+
+    _drawBackground: function()
+    {
+        var size = this._benchmark._stage.size;
+        var gradient = this.context.createLinearGradient(0, 0, size.width, 0);
+        gradient.addColorStop(0, "red");
+        gradient.addColorStop(1, "white");
+        this.context.save();
+            this.context.fillStyle = gradient;
+            this.context.fillRect(0, 0, size.width, size.height);
+        this.context.restore();
+    },
+
+    animate: function(timeDelta)
+    {
+        this._drawBackground();
+
+        if (!this._ctiles)
+            return;
+
+        this._tiles.shuffle();
+
+        var destinations = new Array(this._ctiles);
+        for (var index = 0; index < this._ctiles; ++index) {
+            this._tiles[index].getImageData();
+            destinations[index] = this._tiles[index].source;
+        }
+
+        destinations.shuffle();
+
+        for (var index = 0; index < this._ctiles; ++index)
+            this._tiles[index].putImageData(destinations[index]);
+    },
+
+    complexity: function()
+    {
+        return this._ctiles;
+    }
+});
+
+TiledCanvasImageBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new TiledCanvasImageStage(), options);
+    }
+);
+
+window.benchmarkClass = TiledCanvasImageBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/simple/simple-canvas-paths.html b/third_party/blink/perf_tests/MotionMark/tests/simple/simple-canvas-paths.html
new file mode 100644
index 0000000..910ef3cc
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/simple/simple-canvas-paths.html
@@ -0,0 +1,42 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <canvas id="stage"></canvas>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="../master/resources/canvas-stage.js"></script> <!-- nocheck -->
+    <script src="resources/simple-canvas.js"></script>
+    <script src="resources/simple-canvas-paths.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/simple/tiled-canvas-image.html b/third_party/blink/perf_tests/MotionMark/tests/simple/tiled-canvas-image.html
new file mode 100644
index 0000000..237aeac
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/simple/tiled-canvas-image.html
@@ -0,0 +1,40 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <canvas id="stage"></canvas>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/tiled-canvas-image.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/svg/suits.html b/third_party/blink/perf_tests/MotionMark/tests/svg/suits.html
new file mode 100644
index 0000000..1ea139947
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/svg/suits.html
@@ -0,0 +1,68 @@
+<!--
+  Copyright (C) 2018 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+        #stage {
+            background-color: #fdd;
+        }
+    </style>
+</head>
+<body>
+    <svg id="stage">
+        <defs id="gradients">
+            <linearGradient id="default-gradient">
+                <stop offset="0%"/>
+                <stop offset="100%"/>
+            </linearGradient>
+        </defs>
+        <defs id="shapes">
+            <clipPath id="shape-1" class="shape heart" clipPathUnits="objectBoundingBox">
+                <path d="M0.5,0.214 C0.466,0.164 0.369,0.09 0.267,0.092 C0.137,0.093 -0,0.186 -0,0.345 C-0,0.659 0.395,0.655 0.5,0.938 C0.605,0.655 1,0.659 1,0.345 C1,0.186 0.863,0.093 0.733,0.092 C0.631,0.09 0.534,0.164 0.5,0.214 z"/>
+            </clipPath>
+            <clipPath id="shape-2" class="shape club" clipPathUnits="objectBoundingBox">
+                <path d="M0.5,0.018 C0.62,0.018 0.718,0.115 0.718,0.235 C0.718,0.31 0.679,0.377 0.618,0.418 C0.657,0.393 0.703,0.382 0.749,0.381 C0.869,0.381 0.967,0.468 0.967,0.588 C0.967,0.709 0.869,0.806 0.749,0.806 C0.664,0.805 0.578,0.756 0.542,0.677 C0.538,0.799 0.605,0.918 0.708,0.982 C0.593,0.941 0.407,0.941 0.292,0.982 C0.397,0.917 0.461,0.799 0.459,0.676 C0.422,0.756 0.337,0.804 0.251,0.806 C0.131,0.806 0.033,0.709 0.033,0.588 C0.033,0.468 0.131,0.381 0.251,0.381 C0.298,0.38 0.342,0.395 0.382,0.418 C0.319,0.378 0.284,0.309 0.282,0.235 C0.282,0.115 0.38,0.018 0.5,0.018 z"/>
+            </clipPath>
+            <clipPath id="shape-3" class="shape spade" clipPathUnits="objectBoundingBox">
+                <path d="M0.301,0.982 C0.374,0.941 0.469,0.804 0.469,0.72 C0.374,0.857 0.039,0.825 0.049,0.563 C0.059,0.28 0.406,0.269 0.5,0.018 C0.594,0.269 0.941,0.28 0.951,0.563 C0.961,0.825 0.626,0.857 0.531,0.72 C0.531,0.804 0.626,0.941 0.699,0.982 C0.584,0.941 0.416,0.941 0.301,0.982"/>
+            </clipPath>
+            <clipPath id="shape-4" class="shape diamond" clipPathUnits="objectBoundingBox">
+                <path d="M0.495,0 C0.424,0.153 0.199,0.439 0.128,0.5 C0.199,0.561 0.424,0.847 0.495,1 C0.566,0.847 0.791,0.561 0.862,0.5 C0.791,0.439 0.566,0.153 0.495,0 z"/>
+            </clipPath>
+        </defs>
+    </svg>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="../master/resources/particles.js"></script> <!-- nocheck -->
+    <script src="../master/resources/suits.js"></script> <!-- nocheck -->
+    <script src="suits.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/svg/suits.js b/third_party/blink/perf_tests/MotionMark/tests/svg/suits.js
new file mode 100644
index 0000000..9916755
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/svg/suits.js
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+(function() {
+
+var SuperSuitsParticle = window.SuitsParticle;
+ClipSuit = Utilities.createSubclass(SuperSuitsParticle,
+    function(stage)
+    {
+        this.initialize(stage);
+    }, {
+
+    isClipPath: true,
+    hasGradient: false,
+    move: function()
+    {
+        this.element.setAttribute("transform", "translate(" + (this.position.x - this.size.center.x) + "," + (this.position.y - this.size.center.x) + ")");
+    }
+});
+
+ShapeSuit = Utilities.createSubclass(SuperSuitsParticle,
+    function(stage)
+    {
+        this.initialize(stage);
+    }, {
+
+    isClipPath: false,
+    hasGradient: false,
+    move: function()
+    {
+        this.element.setAttribute("transform", "translate(" + this.position.x + "," + this.position.y + ") " + this.transformSuffix);
+    }
+});
+
+RotationSuit = Utilities.createSubclass(SuperSuitsParticle,
+    function(stage)
+    {
+        this.isClipPath = stage.particleCounter % 2;
+        this.initialize(stage);
+    }, {
+
+    hasGradient: false,
+});
+
+GradientSuit = Utilities.createSubclass(SuperSuitsParticle,
+    function(stage)
+    {
+        this.isClipPath = stage.particleCounter % 2;
+        this.initialize(stage);
+    }, {
+
+    hasGradient: true,
+    move: function()
+    {
+        this.element.setAttribute("transform", "translate(" + this.position.x + "," + this.position.y + ") " + this.transformSuffix);
+    }
+});
+
+StaticSuit = Utilities.createSubclass(SuperSuitsParticle,
+    function(stage)
+    {
+        this.isClipPath = stage.particleCounter % 2;
+        this.initialize(stage);
+    }, {
+
+    hasGradient: true,
+    reset: function()
+    {
+        SuperSuitsParticle.prototype.reset.call(this);
+        this.originalPosition = Stage.randomPosition(this.stage.size);
+        this.transformSuffix = " rotate(" + Math.floor(Stage.randomAngle() * 180 / Math.PI) + ",0,0)" + this.transformSuffix;
+    },
+
+    move: function()
+    {
+        this.element.setAttribute("transform", "translate(" + this.originalPosition.x + "," + this.originalPosition.y + ") " + this.transformSuffix);
+    }
+});
+
+var SuitsBenchmark = window.benchmarkClass;
+var SuitsDerivedBenchmark = Utilities.createSubclass(SuitsBenchmark,
+    function(options)
+    {
+        switch (options["style"]) {
+        case "clip":
+            window.SuitsParticle = ClipSuit;
+            break;
+        case "shape":
+            window.SuitsParticle = ShapeSuit;
+            break;
+        case "rotation":
+            window.SuitsParticle = RotationSuit;
+            break;
+        case "gradient":
+            window.SuitsParticle = GradientSuit;
+            break;
+        case "static":
+            window.SuitsParticle = StaticSuit;
+            break;
+        }
+        SuitsBenchmark.call(this, options);
+    }
+);
+
+window.benchmarkClass = SuitsDerivedBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-canvas.js b/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-canvas.js
new file mode 100644
index 0000000..9a0c7272
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-canvas.js
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+function TemplateCanvasObject(stage)
+{
+    // For the canvas stage, most likely you will need to create your
+    // animated object since it's only draw time thing.
+
+    // Fill in your object data.
+}
+
+TemplateCanvasObject.prototype = {
+    _draw: function()
+    {
+        // Draw your object.
+    },
+
+    animate: function(timeDelta)
+    {
+        // Redraw the animated object. The last time this animated
+        // item was drawn before 'timeDelta'.
+
+        // Move your object.
+
+        // Redraw your object.
+        this._draw();
+    }
+};
+
+TemplateCanvasStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+        this.context = this.element.getContext("2d");
+
+        // Define a collection for your objects.
+    },
+
+    tune: function(count)
+    {
+        // If count is -ve, -count elements need to be removed form the
+        // stage. If count is +ve, +count elements need to be added to
+        // the stage.
+
+        // Change objects in the stage.
+    },
+
+    animate: function(timeDelta)
+    {
+        // Animate the elements such that all of them are redrawn. Most
+        // likely you will need to call TemplateCanvasObject.animate()
+        // for all your animated objects here.
+
+        // Most likely you will need to clear the canvas with every redraw.
+        this.context.clearRect(0, 0, this.size.x, this.size.y);
+
+        // Loop through all your objects and ask them to animate.
+    }
+});
+
+TemplateCanvasBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new TemplateCanvasStage(), options);
+    }, {
+
+    // Override this function if the benchmark needs to wait for resources to be
+    // loaded.
+    //
+    // Default implementation returns a resolved promise, so that the benchmark
+    // benchmark starts right away. Here's an example where we're waiting 5
+    // seconds before starting the benchmark.
+    waitUntilReady: function()
+    {
+        var promise = new SimplePromise;
+        window.setTimeout(function() {
+            promise.resolve();
+        }, 5000);
+        return promise;
+    }
+});
+
+window.benchmarkClass = TemplateCanvasBenchmark;
+
+})();
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-css.js b/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-css.js
new file mode 100644
index 0000000..d7e1e6e
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-css.js
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+TemplateCssStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+
+        // Do initialization here.
+    },
+
+    tune: function(count)
+    {
+        // If count is -ve, -count elements need to be removed form the
+        // stage. If count is +ve, +count elements need to be added to
+        // the stage.
+
+        // Change objects in the stage.
+    },
+
+    animate: function(timeDelta)
+    {
+        // Animate the elements such that all of them are redrawn. You
+        // may need to define your object so it keeps its animation data.
+        // This object should encapsulate a corrosponding HTMLElement.
+        // You may also define a method called animate() in this object
+        // and just call this function here for all the elements.
+
+        // Loop through all your objects and ask them to animate.
+    }
+});
+
+TemplateCssBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new TemplateCssStage(), options);
+    }
+);
+
+window.benchmarkClass = TemplateCssBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-svg.js b/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-svg.js
new file mode 100644
index 0000000..9e1a87b
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/template/resources/template-svg.js
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015-2017 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.
+ */
+(function() {
+
+TemplateSvgStage = Utilities.createSubclass(Stage,
+    function()
+    {
+        Stage.call(this);
+    }, {
+
+    initialize: function(benchmark, options)
+    {
+        Stage.prototype.initialize.call(this, benchmark, options);
+
+        // Do initialization here.
+    },
+
+    tune: function(count)
+    {
+        // If count is -ve, -count elements need to be removed form the
+        // stage. If count is +ve, +count elements need to be added to
+        // the stage.
+
+        // TODO: Change objects in the stage.
+    },
+
+    animate: function(timeDelta)
+    {
+        // Animate the elements such that all of them are redrawn. You
+        // may need to define your object so it keeps its animation data.
+        // This object should encapsulate a corrosponding SVGElement.
+        // You may also define a method called animate() in this object
+        // and just call this function here for all the elements.
+
+        // TODO: Loop through all your objects and ask them to animate.
+    }
+});
+
+TemplateSvgBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new TemplateSvgStage(), options);
+    }
+);
+
+window.benchmarkClass = TemplateSvgBenchmark;
+
+})();
diff --git a/third_party/blink/perf_tests/MotionMark/tests/template/template-canvas.html b/third_party/blink/perf_tests/MotionMark/tests/template/template-canvas.html
new file mode 100644
index 0000000..bdcab6f
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/template/template-canvas.html
@@ -0,0 +1,40 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <canvas id="stage"></canvas>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/template-canvas.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/template/template-css.html b/third_party/blink/perf_tests/MotionMark/tests/template/template-css.html
new file mode 100644
index 0000000..ed6b6ca
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/template/template-css.html
@@ -0,0 +1,40 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <div id="stage"></div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/template-css.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/template/template-svg.html b/third_party/blink/perf_tests/MotionMark/tests/template/template-svg.html
new file mode 100644
index 0000000..eb7a034
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/template/template-svg.html
@@ -0,0 +1,40 @@
+<!--
+  Copyright (C) 2015-2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <svg id="stage"></svg>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/template-svg.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/text/design-6.html b/third_party/blink/perf_tests/MotionMark/tests/text/design-6.html
new file mode 100644
index 0000000..9ce2b360
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/text/design-6.html
@@ -0,0 +1,117 @@
+<!--
+  Copyright (C) 2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+
+        #stage {
+            font-family: Helvetica;
+            font-size: 52px;
+            background-color: #422E2C;
+        }
+        @media (max-width: 900px) {
+            #stage {
+                font-size: 40px;
+            }
+        }
+        @media (max-width: 568px) {
+            #stage {
+                font-size: 28px;
+            }
+        }
+
+        #stage div {
+            width: 80%;
+            height: 90%;
+            position: absolute;
+            text-align: center;
+        }
+        #template {
+            color: #FCFCFC;
+        }
+        table {
+            position: relative;
+            width: 100%;
+            height: 100%;
+        }
+        td {
+            width: 25%;
+        }
+        tr {
+            height: 20%;
+        }
+    </style>
+</head>
+<body>
+    <div id="stage">
+        <div id="template">
+            <table>
+                <tbody>
+                    <tr>
+                        <td></td>
+                        <td></td>
+                        <td></td>
+                        <td></td>
+                    </tr>
+                    <tr>
+                        <td></td>
+                        <td id="cell0"></td>
+                        <td id="cell1"></td>
+                        <td></td>
+                    </tr>
+                    <tr>
+                        <td></td>
+                        <td id="cell2"></td>
+                        <td id="cell3"></td>
+                        <td></td>
+                    </tr>
+                    <tr>
+                        <td></td>
+                        <td id="cell4"></td>
+                        <td id="cell5"></td>
+                        <td></td>
+                    </tr>
+                    <tr>
+                        <td></td>
+                        <td></td>
+                        <td></td>
+                        <td></td>
+                    </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="../master/resources/design.js"></script> <!-- nocheck -->
+    <script src="design-6.js" charset="utf-8"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/text/design-6.js b/third_party/blink/perf_tests/MotionMark/tests/text/design-6.js
new file mode 100644
index 0000000..9401657
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/text/design-6.js
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+(function() {
+
+// The MotionMark-based TextBenchmark should already be set to |window.benchmarkClass|
+var TextBenchmark = window.benchmarkClass;
+var TextTemplateBenchmark = Utilities.createSubclass(TextBenchmark,
+    function(options)
+    {
+        var dataset;
+        switch (options["corpus"]) {
+        case "latin":
+            dataset = [
+                "σχέδιο",
+                "umění",
+                "design",
+                "искусство",
+                "conception",
+                "diseño"
+            ];
+            break;
+        case "cjk":
+            dataset = [
+                "设计",
+                "디자인",
+                "デザイン",
+                "예술",
+                "使吃惊",
+                "がいねん",
+            ];
+            break;
+        case "arabic":
+            dataset = [
+                {text: "تصميم", direction: "rtl"},
+                "வடிவமைப்பு",
+                "योजना",
+                {text: "לְעַצֵב", direction: "rtl"},
+                {text: "خلاق", direction: "rtl"},
+                "ศิลปะ",
+            ];
+            break;
+        }
+
+        dataset.forEach(function(entry, i) {
+            var td = document.getElementById("cell" + i);
+            if (typeof entry === 'string') {
+                td.innerText = entry;
+            } else {
+                td.innerText = entry.text;
+                td.classList.add("rtl");
+            }
+        })
+
+        TextBenchmark.call(this, options);
+    }
+);
+
+window.benchmarkClass = TextTemplateBenchmark;
+
+})();
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/MotionMark/tests/text/design.html b/third_party/blink/perf_tests/MotionMark/tests/text/design.html
new file mode 100644
index 0000000..900c9aa
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/text/design.html
@@ -0,0 +1,107 @@
+<!--
+  Copyright (C) 2017 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+    <style type="text/css">
+
+        #stage {
+            font-family: Helvetica;
+            font-size: 52px;
+            background-color: #422E2C;
+        }
+        @media (max-width: 900px) {
+            #stage {
+                font-size: 40px;
+            }
+        }
+        @media (max-width: 568px) {
+            #stage {
+                font-size: 28px;
+            }
+        }
+
+        #stage div {
+            width: 80%;
+            height: 90%;
+            position: absolute;
+            text-align: center;
+        }
+        #template {
+            color: #FCFCFC;
+        }
+        table {
+            position: relative;
+            width: 100%;
+            height: 100%;
+        }
+        td {
+            width: 33%;
+        }
+        tr {
+            height: 20%;
+        }
+    </style>
+</head>
+<body>
+    <div id="stage">
+        <div id="template">
+            <table>
+                <tbody>
+                    <tr>
+                        <td id="cell0"></td>
+                        <td id="cell1"></td>
+                        <td id="cell2"></td>
+                    </tr>
+                    <tr>
+                        <td id="cell3"></td>
+                        <td id="cell4"></td>
+                        <td id="cell5"></td>
+                    </tr>
+                    <tr>
+                        <td id="cell6"></td>
+                        <td id="cell7"></td>
+                        <td id="cell8"></td>
+                    </tr>
+                    <tr>
+                        <td id="cell9"></td>
+                        <td id="cell10"></td>
+                        <td id="cell11"></td>
+                    </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../../resources/statistics.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="../master/resources/design.js"></script> <!-- nocheck -->
+    <script src="design.js" charset="utf-8"></script>
+</body>
+</html>
diff --git a/third_party/blink/perf_tests/MotionMark/tests/text/design.js b/third_party/blink/perf_tests/MotionMark/tests/text/design.js
new file mode 100644
index 0000000..9ec8a80
--- /dev/null
+++ b/third_party/blink/perf_tests/MotionMark/tests/text/design.js
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+(function() {
+
+// The MotionMark-based TextBenchmark should already be set to |window.benchmarkClass|
+var TextBenchmark = window.benchmarkClass;
+var TextTemplateBenchmark = Utilities.createSubclass(TextBenchmark,
+    function(options)
+    {
+        var dataset;
+        switch (options["corpus"]) {
+        case "latin":
+            dataset = [
+                "σχέδιο",
+                "umění",
+                "suunnittelu",
+                "design",
+                "deseń",
+                "искусство",
+                "дизайн",
+                "conception",
+                "kunst",
+                "konstruktion",
+                "τέχνη",
+                "diseño"
+            ];
+            break;
+        case "cjk":
+            dataset = [
+                "设计",
+                "디자인",
+                "デザイン",
+                "がいねん",
+                "藝術",
+                "养殖",
+                "예술",
+                "展開する",
+                "발달",
+                "技術",
+                "驚き",
+                "使吃惊",
+            ];
+            break;
+        case "arabic":
+            dataset = [
+                {text: "تصميم", direction: "rtl"},
+                "வடிவமைப்பு",
+                "योजना",
+                {text: "לְעַצֵב", direction: "rtl"},
+                {text: "خلاق", direction: "rtl"},
+                "ศิลปะ",
+                "कौशल",
+                {text: "אָמָנוּת", direction: "rtl"},
+                "கலை",
+                "ดีไซน์",
+                "পরিকল্পনা",
+                {text: "ډیزاین", direction: "rtl"},
+            ];
+            break;
+        }
+
+        dataset.forEach(function(entry, i) {
+            var td = document.getElementById("cell" + i);
+            if (typeof entry === 'string') {
+                td.innerText = entry;
+            } else {
+                td.innerText = entry.text;
+                td.classList.add("rtl");
+            }
+        })
+
+        TextBenchmark.call(this, options);
+    }
+);
+
+window.benchmarkClass = TextTemplateBenchmark;
+
+})();
\ No newline at end of file
diff --git a/third_party/blink/perf_tests/speedometer/InteractiveRunner.html b/third_party/blink/perf_tests/speedometer20/InteractiveRunner.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/InteractiveRunner.html
rename to third_party/blink/perf_tests/speedometer20/InteractiveRunner.html
diff --git a/third_party/blink/perf_tests/speedometer/README.md b/third_party/blink/perf_tests/speedometer20/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/README.md
rename to third_party/blink/perf_tests/speedometer20/README.md
diff --git a/third_party/blink/perf_tests/speedometer/index.html b/third_party/blink/perf_tests/speedometer20/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/index.html
rename to third_party/blink/perf_tests/speedometer20/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/benchmark-report.js b/third_party/blink/perf_tests/speedometer20/resources/benchmark-report.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/benchmark-report.js
rename to third_party/blink/perf_tests/speedometer20/resources/benchmark-report.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/benchmark-runner.js b/third_party/blink/perf_tests/speedometer20/resources/benchmark-runner.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/benchmark-runner.js
rename to third_party/blink/perf_tests/speedometer20/resources/benchmark-runner.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/LICENSE.md b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/LICENSE.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/LICENSE.md
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/LICENSE.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/README.md b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/boot/page.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/boot/page.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/boot/page.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/boot/page.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_data/compose_box.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_data/compose_box.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_data/compose_box.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_data/compose_box.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_data/mail_items.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_data/mail_items.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_data/mail_items.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_data/mail_items.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_data/move_to.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_data/move_to.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_data/move_to.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_data/move_to.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/compose_box.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/compose_box.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/compose_box.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/compose_box.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/folders.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/folders.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/folders.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/folders.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/mail_controls.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/mail_controls.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/mail_controls.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/mail_controls.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/mail_items.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/mail_items.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/mail_items.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/mail_items.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/move_to_selector.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/move_to_selector.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/move_to_selector.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/move_to_selector.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/with_select.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/with_select.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/component_ui/with_select.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/component_ui/with_select.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/css/custom.css b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/css/custom.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/css/custom.css
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/css/custom.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/data.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/data.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/data.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/data.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/templates.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/templates.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/app/templates.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/app/templates.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/css/bootstrap-responsive.css b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/css/bootstrap-responsive.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/css/bootstrap-responsive.css
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/css/bootstrap-responsive.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/css/bootstrap-responsive.min.css b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/css/bootstrap-responsive.min.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/css/bootstrap-responsive.min.css
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/css/bootstrap-responsive.min.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/css/bootstrap.css b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/css/bootstrap.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/css/bootstrap.css
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/css/bootstrap.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/css/bootstrap.min.css b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/css/bootstrap.min.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/css/bootstrap.min.css
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/css/bootstrap.min.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/img/glyphicons-halflings-white.png b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/img/glyphicons-halflings-white.png
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/img/glyphicons-halflings-white.png
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/img/glyphicons-halflings-white.png
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/img/glyphicons-halflings.png b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/img/glyphicons-halflings.png
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/img/glyphicons-halflings.png
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/img/glyphicons-halflings.png
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/js/bootstrap.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/js/bootstrap.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/js/bootstrap.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/js/bootstrap.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/js/bootstrap.min.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/js/bootstrap.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/bootstrap/js/bootstrap.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/bootstrap/js/bootstrap.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/.gitignore b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/.gitignore
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/.gitignore
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/.gitignore
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/CHANGES b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/CHANGES
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/CHANGES
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/CHANGES
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/CONTRIBUTORS.md b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/CONTRIBUTORS.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/CONTRIBUTORS.md
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/CONTRIBUTORS.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/README.md b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/component.json b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/component.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/component.json
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/component.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/es5-sham.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/es5-sham.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.min.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/es5-sham.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/es5-sham.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/es5-shim.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/es5-shim.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.min.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/es5-shim.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/es5-shim.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/package.json b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-kill.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-kill.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-kill.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-kill.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-matchers.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-matchers.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-matchers.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-matchers.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/helpers/h.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/helpers/h.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/index.html b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine-html.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine-html.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine-html.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine-html.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.css b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.css
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine_favicon.png b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine_favicon.png
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine_favicon.png
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine_favicon.png
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/json2.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/json2.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/json2.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/lib/json2.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-array.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-array.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-array.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-array.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-date.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-date.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-date.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-date.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-function.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-function.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-function.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-function.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-object.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-object.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-object.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-object.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-string.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-string.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-string.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/es5-shim/tests/spec/s-string.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/.travis.yml b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/.travis.yml
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/.travis.yml
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/.travis.yml
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/advice.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/advice.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/advice.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/advice.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/component.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/component.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/component.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/component.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/compose.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/compose.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/compose.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/compose.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/index.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/logger.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/logger.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/logger.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/logger.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/registry.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/registry.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/registry.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/registry.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/utils.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/utils.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/lib/utils.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/lib/utils.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/tools/debug/debug.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/tools/debug/debug.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/flight/tools/debug/debug.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/flight/tools/debug/debug.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight/LICENSE.md b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight/LICENSE.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight/LICENSE.md
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight/LICENSE.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight/README.md b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight/bower.json b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight/lib/jasmine-flight.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight/lib/jasmine-flight.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-flight/lib/jasmine-flight.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-flight/lib/jasmine-flight.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-jquery/lib/jasmine-jquery.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-jquery/lib/jasmine-jquery.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jasmine-jquery/lib/jasmine-jquery.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jasmine-jquery/lib/jasmine-jquery.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery/component.json b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery/component.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery/component.json
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery/component.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery/composer.json b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery/composer.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery/composer.json
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery/composer.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery/jquery.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery/jquery.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery/jquery.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery/jquery.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery/jquery.min.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery/jquery.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/jquery/jquery.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/jquery/jquery.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/mustache/mustache.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/mustache/mustache.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/mustache/mustache.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/mustache/mustache.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/requirejs/require.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/requirejs/require.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/components/requirejs/require.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/components/requirejs/require.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/index.html b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/karma.conf.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/karma.conf.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/karma.conf.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/karma.conf.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/package.json b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/requireMain.js b/third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/requireMain.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/flightjs-example-app/requireMain.js
rename to third_party/blink/perf_tests/speedometer20/resources/flightjs-example-app/requireMain.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/gauge.png b/third_party/blink/perf_tests/speedometer20/resources/gauge.png
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/gauge.png
rename to third_party/blink/perf_tests/speedometer20/resources/gauge.png
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/gauge@2x.png b/third_party/blink/perf_tests/speedometer20/resources/gauge@2x.png
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/gauge@2x.png
rename to third_party/blink/perf_tests/speedometer20/resources/gauge@2x.png
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/logo.png b/third_party/blink/perf_tests/speedometer20/resources/logo.png
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/logo.png
rename to third_party/blink/perf_tests/speedometer20/resources/logo.png
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/logo@2x.png b/third_party/blink/perf_tests/speedometer20/resources/logo@2x.png
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/logo@2x.png
rename to third_party/blink/perf_tests/speedometer20/resources/logo@2x.png
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/main.css b/third_party/blink/perf_tests/speedometer20/resources/main.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/main.css
rename to third_party/blink/perf_tests/speedometer20/resources/main.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/main.js b/third_party/blink/perf_tests/speedometer20/resources/main.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/main.js
rename to third_party/blink/perf_tests/speedometer20/resources/main.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/tests.js b/third_party/blink/perf_tests/speedometer20/resources/tests.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/tests.js
rename to third_party/blink/perf_tests/speedometer20/resources/tests.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/.angular-cli.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/.angular-cli.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/.angular-cli.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/.angular-cli.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/.editorconfig b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/.editorconfig
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/.editorconfig
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/.editorconfig
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/assets/css/todomvc-app.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/assets/css/todomvc-app.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/assets/css/todomvc-app.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/assets/css/todomvc-app.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/assets/css/todomvc-common.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/assets/css/todomvc-common.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/assets/css/todomvc-common.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/assets/css/todomvc-common.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/favicon.ico b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/favicon.ico
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/favicon.ico
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/favicon.ico
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/inline.3b7f8ce2e6bc2f77dd83.bundle.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/inline.3b7f8ce2e6bc2f77dd83.bundle.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/inline.3b7f8ce2e6bc2f77dd83.bundle.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/inline.3b7f8ce2e6bc2f77dd83.bundle.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/main.f1c5d33a6950c335064d.bundle.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/main.f1c5d33a6950c335064d.bundle.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/main.f1c5d33a6950c335064d.bundle.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/main.f1c5d33a6950c335064d.bundle.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/polyfills.3a2aed82a0c9b24e6585.bundle.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/polyfills.3a2aed82a0c9b24e6585.bundle.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/polyfills.3a2aed82a0c9b24e6585.bundle.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/polyfills.3a2aed82a0c9b24e6585.bundle.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/styles.d41d8cd98f00b204e980.bundle.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/styles.d41d8cd98f00b204e980.bundle.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/styles.d41d8cd98f00b204e980.bundle.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/styles.d41d8cd98f00b204e980.bundle.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/vendor.9a296bbc1909830a9106.bundle.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/vendor.9a296bbc1909830a9106.bundle.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/dist/vendor.9a296bbc1909830a9106.bundle.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/dist/vendor.9a296bbc1909830a9106.bundle.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/karma.conf.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/karma.conf.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/karma.conf.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/karma.conf.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/protractor.conf.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/protractor.conf.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/protractor.conf.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/protractor.conf.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/app.component.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/app.component.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.spec.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/app.component.spec.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.spec.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/app.component.spec.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/app.component.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/app.component.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/app.module.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/app.module.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/app.module.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/app.module.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.spec.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.spec.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.spec.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.spec.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.spec.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/todo.spec.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.spec.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/todo.spec.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/todo.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/app/todo.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-app.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-app.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-app.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-app.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-common.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-common.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-common.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-common.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.prod.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/environments/environment.prod.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.prod.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/environments/environment.prod.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/environments/environment.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/environments/environment.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/favicon.ico b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/favicon.ico
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/favicon.ico
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/favicon.ico
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/main.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/main.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/main.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/main.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/polyfills.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/polyfills.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/polyfills.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/polyfills.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/styles.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/styles.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/styles.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/styles.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/test.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/test.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/test.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/test.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.app.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/tsconfig.app.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.app.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/tsconfig.app.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.spec.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/tsconfig.spec.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.spec.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/tsconfig.spec.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/typings.d.ts b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/typings.d.ts
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/src/typings.d.ts
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/src/typings.d.ts
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/tsconfig.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/tsconfig.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/tsconfig.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/tsconfig.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/tslint.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/tslint.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angular/tslint.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angular/tslint.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/controllers/todoCtrl.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/controllers/todoCtrl.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/controllers/todoCtrl.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/controllers/todoCtrl.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoEscape.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/directives/todoEscape.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoEscape.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/directives/todoEscape.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoFocus.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/directives/todoFocus.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoFocus.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/directives/todoFocus.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/services/todoStorage.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/services/todoStorage.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/js/services/todoStorage.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/js/services/todoStorage.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.min.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.min.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.min.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-resource/angular-resource.min.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.min.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.min.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.min.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular-route/angular-route.min.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.min.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.min.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.min.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/angular/angular.min.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-app-css/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/node_modules/todomvc-common/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/todomvc-index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/todomvc-index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/angularjs/todomvc-index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/angularjs/todomvc-index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/backbone.sync.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/backbone.sync.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/backbone.sync.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/backbone.sync.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/collections/todos.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/collections/todos.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/collections/todos.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/collections/todos.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/models/todo.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/models/todo.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/models/todo.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/models/todo.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/routers/router.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/routers/router.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/routers/router.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/routers/router.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/views/app-view.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/views/app-view.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/views/app-view.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/views/app-view.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone-min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone-min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone-min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone-min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone-min.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone-min.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone-min.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone-min.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/backbone/backbone.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.min.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.min.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.min.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/jquery/dist/jquery.min.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore-min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore-min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore-min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore-min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore-min.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore-min.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore-min.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore-min.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/node_modules/underscore/underscore.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/backbone/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/backbone/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/assets/todomvc.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/assets/todomvc.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/assets/todomvc.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/assets/todomvc.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/assets/vendor.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/assets/vendor.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/assets/vendor.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/assets/vendor.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/assets/vendor.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/assets/vendor.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/assets/vendor.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/assets/vendor.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/crossdomain.xml b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/crossdomain.xml
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/crossdomain.xml
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/crossdomain.xml
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/robots.txt b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/robots.txt
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/robots.txt
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/robots.txt
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.bowerrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.bowerrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.bowerrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.bowerrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.editorconfig b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.editorconfig
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.editorconfig
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.editorconfig
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.ember-cli b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.ember-cli
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.ember-cli
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.ember-cli
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.gitignore b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.gitignore
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.gitignore
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.gitignore
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.jshintrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.jshintrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.jshintrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.jshintrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.travis.yml b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.travis.yml
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.travis.yml
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.travis.yml
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.watchmanconfig b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.watchmanconfig
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/.watchmanconfig
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/.watchmanconfig
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/components/todo-item.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/components/todo-item.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/components/todo-item.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/components/todo-item.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/components/todo-list.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/components/todo-list.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/components/todo-list.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/components/todo-list.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/active.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/active.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/active.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/active.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/application.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/application.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/application.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/application.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/completed.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/completed.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/completed.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/controllers/completed.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/helpers/gt.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/helpers/gt.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/helpers/gt.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/helpers/gt.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/helpers/pluralize.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/helpers/pluralize.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/helpers/pluralize.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/helpers/pluralize.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/instance-initializers/global.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/instance-initializers/global.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/instance-initializers/global.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/instance-initializers/global.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/resolver.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/resolver.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/resolver.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/resolver.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/router.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/router.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/router.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/router.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/routes/application.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/routes/application.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/routes/application.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/routes/application.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/services/memory.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/services/memory.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/services/memory.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/services/memory.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/services/repo.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/services/repo.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/services/repo.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/services/repo.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/active.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/active.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/active.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/active.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/application.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/application.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/application.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/application.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/completed.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/completed.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/completed.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/completed.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/components/todo-item.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/components/todo-item.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/components/todo-item.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/components/todo-item.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/components/todo-list.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/components/todo-list.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/components/todo-list.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/components/todo-list.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/index.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/index.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/index.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/app/templates/index.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/bower.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/config/environment.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/config/environment.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/config/environment.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/config/environment.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/ember-cli-build.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/ember-cli-build.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/ember-cli-build.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/ember-cli-build.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/public/crossdomain.xml b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/public/crossdomain.xml
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/public/crossdomain.xml
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/public/crossdomain.xml
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/public/robots.txt b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/public/robots.txt
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/public/robots.txt
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/public/robots.txt
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/testem.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/testem.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/testem.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/testem.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/.jshintrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/.jshintrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/.jshintrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/.jshintrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/destroy-app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/destroy-app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/destroy-app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/destroy-app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/module-for-acceptance.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/module-for-acceptance.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/module-for-acceptance.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/module-for-acceptance.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/resolver.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/resolver.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/resolver.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/resolver.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/start-app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/start-app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/start-app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/helpers/start-app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/test-helper.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/test-helper.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/tests/test-helper.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/tests/test-helper.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/vendor/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/vendor/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/vendor/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/vendor/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/vendor/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/vendor/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/source/vendor/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/source/vendor/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/testem.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/testem.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/testem.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/testem.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/tests/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/tests/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs-debug/tests/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs-debug/tests/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.bowerrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.bowerrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.bowerrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.bowerrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.editorconfig b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.editorconfig
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.editorconfig
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.editorconfig
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.ember-cli b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.ember-cli
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.ember-cli
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.ember-cli
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.gitignore b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.gitignore
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.gitignore
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.gitignore
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.jshintrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.jshintrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/.jshintrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/.jshintrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/components/todo-item.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/components/todo-item.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/components/todo-item.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/components/todo-item.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/components/todo-list.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/components/todo-list.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/components/todo-list.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/components/todo-list.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/controllers/active.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/controllers/active.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/controllers/active.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/controllers/active.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/controllers/application.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/controllers/application.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/controllers/application.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/controllers/application.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/controllers/completed.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/controllers/completed.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/controllers/completed.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/controllers/completed.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/helpers/gt.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/helpers/gt.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/helpers/gt.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/helpers/gt.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/helpers/pluralize.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/helpers/pluralize.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/helpers/pluralize.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/helpers/pluralize.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/resolver.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/resolver.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/resolver.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/resolver.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/router.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/router.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/router.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/router.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/routes/application.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/routes/application.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/routes/application.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/routes/application.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/services/memory.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/services/memory.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/services/memory.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/services/memory.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/services/repo.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/services/repo.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/services/repo.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/services/repo.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/styles/.gitkeep b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/styles/.gitkeep
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/styles/.gitkeep
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/styles/.gitkeep
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/active.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/active.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/active.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/active.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/application.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/application.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/application.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/application.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/completed.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/completed.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/completed.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/completed.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/components/todo-item.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/components/todo-item.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/components/todo-item.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/components/todo-item.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/components/todo-list.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/components/todo-list.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/components/todo-list.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/components/todo-list.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/index.hbs b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/index.hbs
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/app/templates/index.hbs
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/app/templates/index.hbs
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/bower.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/config/environment.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/config/environment.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/config/environment.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/config/environment.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/assets/todomvc-5d3e8eb3d5b3740a33185edcb11eeb57.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/assets/todomvc-5d3e8eb3d5b3740a33185edcb11eeb57.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/assets/todomvc-5d3e8eb3d5b3740a33185edcb11eeb57.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/assets/todomvc-5d3e8eb3d5b3740a33185edcb11eeb57.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/assets/vendor-820919567eb7bd4d9fac358a90a5aac4.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/assets/vendor-820919567eb7bd4d9fac358a90a5aac4.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/assets/vendor-820919567eb7bd4d9fac358a90a5aac4.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/assets/vendor-820919567eb7bd4d9fac358a90a5aac4.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/assets/vendor-a45c44bc56b4692cca4a96b6916c0fde.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/assets/vendor-a45c44bc56b4692cca4a96b6916c0fde.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/assets/vendor-a45c44bc56b4692cca4a96b6916c0fde.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/assets/vendor-a45c44bc56b4692cca4a96b6916c0fde.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/crossdomain.xml b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/crossdomain.xml
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/crossdomain.xml
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/crossdomain.xml
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/robots.txt b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/robots.txt
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/dist/robots.txt
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/dist/robots.txt
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/ember-cli-build.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/ember-cli-build.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/ember-cli-build.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/ember-cli-build.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/public/crossdomain.xml b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/public/crossdomain.xml
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/public/crossdomain.xml
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/public/crossdomain.xml
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/public/robots.txt b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/public/robots.txt
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/public/robots.txt
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/public/robots.txt
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/testem.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/testem.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/testem.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/testem.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/helpers/destroy-app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/helpers/destroy-app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/helpers/destroy-app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/helpers/destroy-app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/helpers/module-for-acceptance.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/helpers/module-for-acceptance.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/helpers/module-for-acceptance.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/helpers/module-for-acceptance.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/helpers/resolver.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/helpers/resolver.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/helpers/resolver.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/helpers/resolver.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/helpers/start-app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/helpers/start-app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/helpers/start-app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/helpers/start-app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/test-helper.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/test-helper.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/tests/test-helper.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/tests/test-helper.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/vendor/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/vendor/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/vendor/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/vendor/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/vendor/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/vendor/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/emberjs/vendor/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/emberjs/vendor/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/dist/bundle.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/dist/bundle.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/dist/bundle.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/dist/bundle.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-app-css/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/node_modules/todomvc-common/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/item.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/item.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/item.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/item.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/model.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/model.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/model.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/model.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/share.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/share.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/src/share.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/src/share.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/webpack.config.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/webpack.config.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/inferno/webpack.config.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/inferno/webpack.config.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/css/app.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/css/app.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/css/app.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/css/app.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/js/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/js/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/js/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/js/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/bower.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/director.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/director.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/director.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/director.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/director.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/director.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/director.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/director.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/ender.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/ender.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/ender.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/dist/ender.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/director/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/director/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/handlebars/dist/handlebars.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/handlebars/dist/handlebars.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/handlebars/dist/handlebars.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/handlebars/dist/handlebars.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/jquery/dist/jquery.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/jquery/dist/jquery.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/jquery/dist/jquery.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/jquery/dist/jquery.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-app-css/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/node_modules/todomvc-common/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/jquery/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/jquery/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/.babelrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/.babelrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/.babelrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/.babelrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/app.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/app.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/app.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/app.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/todomvc.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/todomvc.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/dist/todomvc.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/dist/todomvc.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/rollup.config.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/rollup.config.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/rollup.config.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/rollup.config.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/footer.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/footer.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/footer.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/footer.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/item.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/item.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/item.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/item.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/model.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/model.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/model.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/model.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/util.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/util.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/app/util.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/app/util.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/src/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/src/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/webpack.config.babel.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/webpack.config.babel.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/preact/webpack.config.babel.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/preact/webpack.config.babel.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/asset-manifest.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/asset-manifest.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/asset-manifest.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/asset-manifest.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/service-worker.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/service-worker.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/service-worker.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/service-worker.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/css/main.21111742.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/css/main.21111742.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/css/main.21111742.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/css/main.21111742.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/css/main.21111742.css.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/css/main.21111742.css.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/css/main.21111742.css.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/css/main.21111742.css.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/js/main.18b409e1.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/js/main.18b409e1.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/js/main.18b409e1.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/js/main.18b409e1.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/js/main.18b409e1.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/js/main.18b409e1.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/dist/static/js/main.18b409e1.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/dist/static/js/main.18b409e1.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/public/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/public/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/public/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/public/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/actions/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/actions/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/actions/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/actions/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/actions/index.spec.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/actions/index.spec.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/actions/index.spec.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/actions/index.spec.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/Footer.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/Footer.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.spec.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/Footer.spec.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.spec.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/Footer.spec.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/Header.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/Header.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.spec.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/Header.spec.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.spec.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/Header.spec.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.spec.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.spec.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.spec.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.spec.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.spec.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.spec.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.spec.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.spec.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.spec.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.spec.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.spec.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.spec.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/constants/ActionTypes.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/constants/ActionTypes.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/constants/ActionTypes.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/constants/ActionTypes.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/constants/TodoFilters.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/constants/TodoFilters.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/constants/TodoFilters.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/constants/TodoFilters.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/containers/App.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/containers/App.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/containers/App.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/containers/App.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/reducers/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/reducers/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/reducers/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/reducers/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/reducers/todos.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/reducers/todos.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/reducers/todos.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/reducers/todos.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/reducers/todos.spec.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/reducers/todos.spec.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react-redux/src/reducers/todos.spec.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react-redux/src/reducers/todos.spec.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/build.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/build.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/build.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/build.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/js/app.jsx b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/js/app.jsx
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/js/app.jsx
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/js/app.jsx
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/license.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/license.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/license.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/license.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/bind.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/bind.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/bind.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/bind.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/bower.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/dedupe.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/dedupe.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/dedupe.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/dedupe.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/classnames/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/classnames/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/director/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/director/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/director/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/director/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/director/bower.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/director/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/director/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/director/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/director/build/director.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/director/build/director.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/director/build/director.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/director/build/director.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react-dom/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react-dom/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react-dom/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react-dom/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react-dom/dist/react-dom.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react-dom/dist/react-dom.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react-dom/dist/react-dom.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react-dom/dist/react-dom.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react/dist/react-with-addons.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react/dist/react-with-addons.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react/dist/react-with-addons.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react/dist/react-with-addons.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react/dist/react.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react/dist/react.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/react/dist/react.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/react/dist/react.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/react/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/react/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/.babelrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/.babelrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/.babelrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/.babelrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/.editorconfig b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/.editorconfig
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/.editorconfig
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/.editorconfig
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/.eslintignore b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/.eslintignore
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/.eslintignore
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/.eslintignore
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/.eslintrc.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/.eslintrc.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/.eslintrc.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/.eslintrc.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/build.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/build.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/build.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/build.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/check-versions.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/check-versions.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/check-versions.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/check-versions.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/dev-client.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/dev-client.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/dev-client.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/dev-client.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/dev-server.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/dev-server.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/dev-server.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/dev-server.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/utils.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/utils.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/utils.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/utils.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/vue-loader.conf.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/vue-loader.conf.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/vue-loader.conf.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/vue-loader.conf.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.base.conf.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.base.conf.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.base.conf.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.base.conf.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.dev.conf.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.dev.conf.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.dev.conf.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.dev.conf.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.prod.conf.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.prod.conf.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.prod.conf.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.prod.conf.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.test.conf.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.test.conf.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.test.conf.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/build/webpack.test.conf.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/config/dev.env.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/config/dev.env.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/config/dev.env.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/config/dev.env.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/config/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/config/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/config/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/config/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/config/prod.env.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/config/prod.env.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/config/prod.env.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/config/prod.env.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/css/app.5b47040a23ec3fcb78037de398c53557.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/css/app.5b47040a23ec3fcb78037de398c53557.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/css/app.5b47040a23ec3fcb78037de398c53557.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/css/app.5b47040a23ec3fcb78037de398c53557.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/css/app.5b47040a23ec3fcb78037de398c53557.css.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/css/app.5b47040a23ec3fcb78037de398c53557.css.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/css/app.5b47040a23ec3fcb78037de398c53557.css.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/css/app.5b47040a23ec3fcb78037de398c53557.css.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/app.e6c010d57d53537f4ad2.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/app.e6c010d57d53537f4ad2.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/app.e6c010d57d53537f4ad2.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/app.e6c010d57d53537f4ad2.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/app.e6c010d57d53537f4ad2.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/app.e6c010d57d53537f4ad2.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/app.e6c010d57d53537f4ad2.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/app.e6c010d57d53537f4ad2.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/manifest.aa9978aa96ee948f2a4c.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/manifest.aa9978aa96ee948f2a4c.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/manifest.aa9978aa96ee948f2a4c.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/manifest.aa9978aa96ee948f2a4c.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/manifest.aa9978aa96ee948f2a4c.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/manifest.aa9978aa96ee948f2a4c.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/manifest.aa9978aa96ee948f2a4c.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/manifest.aa9978aa96ee948f2a4c.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/vendor.e7008001a8bed009bbf1.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/vendor.e7008001a8bed009bbf1.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/vendor.e7008001a8bed009bbf1.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/vendor.e7008001a8bed009bbf1.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/vendor.e7008001a8bed009bbf1.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/vendor.e7008001a8bed009bbf1.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/vendor.e7008001a8bed009bbf1.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/dist/static/js/vendor.e7008001a8bed009bbf1.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/src/App.vue b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/src/App.vue
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/src/App.vue
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/src/App.vue
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/src/components/Todos.vue b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/src/components/Todos.vue
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/src/components/Todos.vue
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/src/components/Todos.vue
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/src/components/todo.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/src/components/todo.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/src/components/todo.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/src/components/todo.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/src/main.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/src/main.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/src/main.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/src/main.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/yarn.lock b/third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/yarn.lock
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/architecture-examples/vuejs-cli/yarn.lock
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/architecture-examples/vuejs-cli/yarn.lock
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/data/stats.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/data/stats.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/data/stats.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/data/stats.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/data/todos.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/data/todos.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/data/todos.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/data/todos.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/main.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/main.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/main.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/main.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/page/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/page/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/page/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/page/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/store.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/store.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/store.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/store.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/main_selector.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/main_selector.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/main_selector.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/main_selector.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/new_item.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/new_item.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/new_item.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/new_item.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/stats.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/stats.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/stats.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/stats.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/todo_list.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/todo_list.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/todo_list.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/todo_list.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/toggle_all.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/toggle_all.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/toggle_all.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/toggle_all.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/with_filters.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/with_filters.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/ui/with_filters.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/ui/with_filters.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/utils.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/utils.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/js/utils.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/js/utils.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/templates/stats.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/templates/stats.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/templates/stats.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/templates/stats.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/templates/todo.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/templates/todo.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/app/templates/todo.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/app/templates/todo.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/depot.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/depot.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/depot.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/depot.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/depot.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/depot.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/depot.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/depot.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/depot/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-sham.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-sham.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-sham.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-sham.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-sham.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-sham.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-sham.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-sham.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-shim.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-shim.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-shim.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-shim.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-shim.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-shim.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-shim.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/es5-shim/es5-shim.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/index.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/index.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/index.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/index.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/advice.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/advice.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/advice.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/advice.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/component.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/component.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/component.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/component.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/compose.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/compose.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/compose.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/compose.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/debug.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/debug.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/debug.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/debug.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/logger.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/logger.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/logger.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/logger.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/registry.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/registry.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/registry.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/registry.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/utils.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/utils.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/utils.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/flight/lib/utils.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist/jquery.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist/jquery.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist/jquery.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist/jquery.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist/jquery.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist/jquery.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist/jquery.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/dist/jquery.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/jquery/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/memorystorage/memorystorage.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/memorystorage/memorystorage.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/memorystorage/memorystorage.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/memorystorage/memorystorage.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/bower.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/text.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/text.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/text.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs-text/text.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/require.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/require.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/require.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/requirejs/require.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-app-css/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/node_modules/todomvc-common/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/dependency-examples/flight/flight/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/dependency-examples/flight/flight/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/Todo.elm b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/Todo.elm
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/Todo.elm
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/Todo.elm
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/Todo/Task.elm b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/Todo/Task.elm
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/Todo/Task.elm
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/Todo/Task.elm
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/dist/elm.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/dist/elm.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/dist/elm.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/dist/elm.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/functional-prog-examples/elm/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/functional-prog-examples/elm/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/LICENSE b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/LICENSE
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/LICENSE
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/LICENSE
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/director.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/director.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/director.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/director.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/director.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/director.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/director.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/director.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/ender.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/ender.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/ender.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/director/build/ender.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react/JSXTransformer.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react/JSXTransformer.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react/JSXTransformer.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react/JSXTransformer.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react/bower.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react/bower.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react/bower.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react/bower.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react/react.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react/react.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react/react.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react/react.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react/react.min.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react/react.min.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/react/react.min.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/react/react.min.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/bg.png b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/bg.png
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/bg.png
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/bower_components/todomvc-common/bg.png
Binary files differ
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/js/app.jsx b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/app.jsx
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/js/app.jsx
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/app.jsx
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/js/footer.jsx b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/footer.jsx
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/js/footer.jsx
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/footer.jsx
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/js/todoItem.jsx b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/todoItem.jsx
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/js/todoItem.jsx
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/todoItem.jsx
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/js/utils.jsx b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/utils.jsx
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/js/utils.jsx
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/utils.jsx
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/labs/architecture-examples/react/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/learn.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/learn.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/learn.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/learn.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/license.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/license.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/license.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/license.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/.babelrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/.babelrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/.babelrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/.babelrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/.eslintignore b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/.eslintignore
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/.eslintignore
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/.eslintignore
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.app.930ad8b83126862d7445.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.app.930ad8b83126862d7445.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.app.930ad8b83126862d7445.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.app.930ad8b83126862d7445.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.app.930ad8b83126862d7445.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.app.930ad8b83126862d7445.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.app.930ad8b83126862d7445.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.app.930ad8b83126862d7445.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.manifest.e81199b00da2921d9c94.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.manifest.e81199b00da2921d9c94.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.manifest.e81199b00da2921d9c94.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.manifest.e81199b00da2921d9c94.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.manifest.e81199b00da2921d9c94.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.manifest.e81199b00da2921d9c94.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.manifest.e81199b00da2921d9c94.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.manifest.e81199b00da2921d9c94.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.vendor.577c6bc09319b27fed34.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.vendor.577c6bc09319b27fed34.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.vendor.577c6bc09319b27fed34.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.vendor.577c6bc09319b27fed34.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.vendor.577c6bc09319b27fed34.js.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.vendor.577c6bc09319b27fed34.js.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.vendor.577c6bc09319b27fed34.js.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/bundle.vendor.577c6bc09319b27fed34.js.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.app.930ad8b83126862d7445.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.app.930ad8b83126862d7445.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.app.930ad8b83126862d7445.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.app.930ad8b83126862d7445.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.app.930ad8b83126862d7445.css.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.app.930ad8b83126862d7445.css.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.app.930ad8b83126862d7445.css.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.app.930ad8b83126862d7445.css.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.vendor.577c6bc09319b27fed34.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.vendor.577c6bc09319b27fed34.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.vendor.577c6bc09319b27fed34.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.vendor.577c6bc09319b27fed34.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.vendor.577c6bc09319b27fed34.css.map b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.vendor.577c6bc09319b27fed34.css.map
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.vendor.577c6bc09319b27fed34.css.map
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/dist/styles.vendor.577c6bc09319b27fed34.css.map
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/package-lock.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/package-lock.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/package-lock.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/package-lock.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/app.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/app.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/app.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/app.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/bootstrap.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/bootstrap.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/bootstrap.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/bootstrap.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/controller.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/controller.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/controller.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/controller.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/controller.test.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/controller.test.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/controller.test.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/controller.test.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/helpers.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/helpers.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/helpers.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/helpers.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/memory.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/memory.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/memory.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/memory.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/model.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/model.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/model.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/model.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/store.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/store.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/store.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/store.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/template.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/template.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/template.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/template.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/todo.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/todo.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/todo.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/todo.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/view.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/view.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/view.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/src/view.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/webpack.config.babel.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/webpack.config.babel.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015-babel-webpack/webpack.config.babel.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015-babel-webpack/webpack.config.babel.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/README.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/README.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/README.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/README.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-app-css/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/node_modules/todomvc-common/readme.md
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/.jshintrc b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/.jshintrc
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/.jshintrc
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/.jshintrc
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/controller.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/controller.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/controller.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/controller.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/helpers.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/helpers.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/helpers.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/helpers.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/model.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/model.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/model.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/model.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/store.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/store.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/store.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/store.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/template.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/template.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/template.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/template.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/view.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/view.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/es2015/src/view.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/es2015/src/view.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/index.html b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/index.html
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/index.html
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/index.html
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/app.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/app.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/app.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/app.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/controller.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/controller.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/controller.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/controller.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/helpers.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/helpers.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/helpers.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/helpers.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/model.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/model.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/model.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/model.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/store.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/store.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/store.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/store.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/template.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/template.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/template.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/template.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/view.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/view.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/js/view.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/js/view.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-app-css/index.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-app-css/index.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-app-css/index.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-app-css/index.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-common/base.css b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-common/base.css
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-common/base.css
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-common/base.css
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-common/base.js b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-common/base.js
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-common/base.js
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/node_modules/todomvc-common/base.js
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/package.json b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/package.json
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/package.json
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/package.json
diff --git a/third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/readme.md b/third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/readme.md
similarity index 100%
rename from third_party/blink/perf_tests/speedometer/resources/todomvc/vanilla-examples/vanillajs/readme.md
rename to third_party/blink/perf_tests/speedometer20/resources/todomvc/vanilla-examples/vanillajs/readme.md
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn
index 4712e60..5e959aa 100644
--- a/third_party/blink/public/common/BUILD.gn
+++ b/third_party/blink/public/common/BUILD.gn
@@ -298,6 +298,7 @@
     "security/security_style.h",
     "security_context/insecure_request_policy.h",
     "service_worker/service_worker_loader_helpers.h",
+    "service_worker/service_worker_router_rule.h",
     "service_worker/service_worker_scope_match.h",
     "service_worker/service_worker_status_code.h",
     "service_worker/service_worker_subresource_load_metrics.h",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 2deded6..b5b7bdf 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -242,6 +242,35 @@
 BLINK_COMMON_EXPORT extern const base::FeatureParam<ForceDarkImageClassifier>
     kForceDarkImageClassifierParam;
 
+// TODO(crbug/1431792): Speculatively warm-up service worker.
+BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kSpeculativeServiceWorkerWarmUp);
+BLINK_COMMON_EXPORT extern const base::FeatureParam<bool>
+    kSpeculativeServiceWorkerWarmUpDryRun;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta>
+    kSpeculativeServiceWorkerWarmUpBatchTimer;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<int>
+    kSpeculativeServiceWorkerWarmUpMaxCount;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<int>
+    kSpeculativeServiceWorkerWarmUpRequestCacheSize;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<int>
+    kSpeculativeServiceWorkerWarmUpRequestQueueLength;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<int>
+    kSpeculativeServiceWorkerWarmUpRequestLimit;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta>
+    kSpeculativeServiceWorkerWarmUpDuration;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta>
+    kSpeculativeServiceWorkerWarmUpReWarmUpThreshold;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<bool>
+    kSpeculativeServiceWorkerWarmUpIntersectionObserver;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<int>
+    kSpeculativeServiceWorkerWarmUpIntersectionObserverDelay;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<bool>
+    kSpeculativeServiceWorkerWarmUpOnVisible;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<bool>
+    kSpeculativeServiceWorkerWarmUpOnPointerover;
+BLINK_COMMON_EXPORT extern const base::FeatureParam<bool>
+    kSpeculativeServiceWorkerWarmUpOnPointerdown;
+
 // Returns true when PlzDedicatedWorker is enabled.
 BLINK_COMMON_EXPORT bool IsPlzDedicatedWorkerEnabled();
 
diff --git a/third_party/blink/public/common/origin_trials/trial_token_validator.h b/third_party/blink/public/common/origin_trials/trial_token_validator.h
index a280a43..d7aa710 100644
--- a/third_party/blink/public/common/origin_trials/trial_token_validator.h
+++ b/third_party/blink/public/common/origin_trials/trial_token_validator.h
@@ -14,6 +14,7 @@
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "third_party/blink/public/common/common_export.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_feature.h"
 #include "third_party/blink/public/common/origin_trials/trial_token.h"
 #include "url/origin.h"
 
@@ -67,14 +68,14 @@
                                                  const url::Origin& origin,
                                                  base::Time current_time) const;
 
-  // Validates a trial token as |ValidateToken|. If the token itself is valid,
+  // Validates a trial token as `ValidateToken`. If the token itself is valid,
   // it is then validated against the trial configurations in
   // runtime_enabled_features.json5 to ensure that
   // * The trial exists
   // * If the token is third-party, that the trial allows third-party
-  // * If the trial does not allow insecure origins, |origin| is checked to
+  // * If the trial does not allow insecure origins, `origin` is checked to
   //   confirm it is secure, and if the token is a third_party token, the
-  //   |third_party_origins| are checked to ensure the token is validated
+  //   `third_party_origins` are checked to ensure the token is validated
   //   against a secure origin.
   virtual TrialTokenResult ValidateTokenAndTrial(
       base::StringPiece token,
@@ -82,10 +83,10 @@
       base::span<const url::Origin> third_party_origins,
       base::Time current_time) const;
 
-  // Dedicated version of |ValidateTokenAndTrial| intended for use by
-  // |blink::OriginTrialContext|, so it can pass in its own evaluation
-  // of origin security based on |blink::OriginTrialContext::IsSecureContext|.
-  // The browser process should call |ValidateTokenAndTrial| instead, which
+  // Dedicated version of `ValidateTokenAndTrial` intended for use by
+  // `blink::OriginTrialContext`, so it can pass in its own evaluation
+  // of origin security based on `blink::OriginTrialContext::IsSecureContext`.
+  // The browser process should call `ValidateTokenAndTrial` instead, which
   // takes care of the origin security evaluation internally.
   virtual TrialTokenResult ValidateTokenAndTrialWithOriginInfo(
       base::StringPiece token,
@@ -101,9 +102,9 @@
   virtual TrialTokenResult ValidateToken(base::StringPiece token,
                                          const url::Origin& origin,
                                          base::Time current_time) const;
-  // Validates a token for the given |origin|. If identified as a third-party
-  // token, instead validate for the given list in |third_party_origins|.
-  // Validation of a third-party token will fail if |third_party_origins| is
+  // Validates a token for the given `origin`. If identified as a third-party
+  // token, instead validate for the given list in `third_party_origins`.
+  // Validation of a third-party token will fail if `third_party_origins` is
   // empty. Returns the same result as ValidateToken() above.
   // This method is thread-safe.
   virtual TrialTokenResult ValidateToken(
@@ -112,9 +113,9 @@
       base::span<const url::Origin> third_party_origins,
       base::Time current_time) const;
 
-  // Re-validate that |trial_name| is still enabled given the token information.
+  // Re-validate that `trial_name` is still enabled given the token information.
   // The token from which the information was obtained should previously have
-  // been validated with either |ValidateToken| or |ValidateTokenAndTrial|, to
+  // been validated with either `ValidateToken` or `ValidateTokenAndTrial`, to
   // ensure that it was a valid token for the origin to which we are applying
   // it.
   virtual bool RevalidateTokenAndTrial(
@@ -124,7 +125,19 @@
       const base::StringPiece token_signature,
       const base::Time current_time) const;
 
-  // |request| must not be nullptr.
+  // Return the set of features enabled by the given `trial_name`.
+  // TODO(crbug.com/1227440): Refactor this to be a part of more general
+  //                          validation flows instead of a stand-alone.
+  std::vector<OriginTrialFeature> FeaturesEnabledByTrial(
+      base::StringPiece trial_name);
+
+  // Return true if the trial in question enables at least one feature on the
+  // current OS platform.
+  // TODO(crbug.com/1227440): Refactor this to be a part of more general
+  //                          validation flows instead of a stand-alone.
+  bool TrialEnablesFeaturesForOS(base::StringPiece trial_name);
+
+  // `request` must not be nullptr.
   // NOTE: This is not currently used, but remains here for future trials.
   bool RequestEnablesFeature(const net::URLRequest* request,
                              base::StringPiece feature_name,
@@ -133,36 +146,36 @@
   // Returns whether the given response for the given URL enables the named
   // Origin or Deprecation Trial at the given time.
   //
-  // |response_headers| must not be nullptr.
+  // `response_headers` must not be nullptr.
   bool RequestEnablesFeature(const GURL& request_url,
                              const net::HttpResponseHeaders* response_headers,
                              base::StringPiece feature_name,
                              base::Time current_time) const;
 
-  // Similar to |RequestEnablesFeature()|, but for Deprecation Trials that may
+  // Similar to `RequestEnablesFeature()`, but for Deprecation Trials that may
   // be enabled on insecure origins.
   //
   // For Origin Trials (as opposed to Deprecation Trials) or Deprecation Trials
   // that are enabled exclusively on secure origins, use
-  // |RequestEnablesFeature()| instead.
+  // `RequestEnablesFeature()` instead.
   //
   // Functionally, the only difference is that this can return true even if
-  // |request_url|'s origin is not secure.
+  // `request_url`'s origin is not secure.
   //
-  // |response_headers| must not be nullptr.
+  // `response_headers` must not be nullptr.
   bool RequestEnablesDeprecatedFeature(
       const GURL& request_url,
       const net::HttpResponseHeaders* response_headers,
       base::StringPiece feature_name,
       base::Time current_time) const;
 
-  // Returns all valid tokens in |headers|.
+  // Returns all valid tokens in `headers`.
   std::unique_ptr<FeatureToTokensMap> GetValidTokensFromHeaders(
       const url::Origin& origin,
       const net::HttpResponseHeaders* headers,
       base::Time current_time) const;
 
-  // Returns all valid tokens in |tokens|. This method is used to re-validate
+  // Returns all valid tokens in `tokens`. This method is used to re-validate
   // previously stored tokens.
   std::unique_ptr<FeatureToTokensMap> GetValidTokens(
       const url::Origin& origin,
@@ -176,8 +189,8 @@
   static bool IsTrialPossibleOnOrigin(const GURL& url);
 
  private:
-  // Helper for |RequestEnablesFeature()| and
-  // |RequestEnablesDeprecatedFeature()|.
+  // Helper for `RequestEnablesFeature()` and
+  // `RequestEnablesDeprecatedFeature()`.
   bool ResponseBearsValidTokenForFeature(
       const GURL& request_url,
       const net::HttpResponseHeaders& response_headers,
diff --git a/third_party/blink/public/common/service_worker/OWNERS b/third_party/blink/public/common/service_worker/OWNERS
index c07cce4c..8622fb20 100644
--- a/third_party/blink/public/common/service_worker/OWNERS
+++ b/third_party/blink/public/common/service_worker/OWNERS
@@ -2,3 +2,5 @@
 
 per-file *_type_converter*.*=set noparent
 per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/public/common/service_worker/service_worker_router_rule.h b/third_party/blink/public/common/service_worker/service_worker_router_rule.h
new file mode 100644
index 0000000..290e562
--- /dev/null
+++ b/third_party/blink/public/common/service_worker/service_worker_router_rule.h
@@ -0,0 +1,64 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_RULE_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_RULE_H_
+
+#include <vector>
+
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/url_pattern.h"
+
+namespace blink {
+
+// TODO(crbug.com/1371756): implement other conditions in the proposal.
+struct ServiceWorkerRouterCondition {
+  // Type of conditions.
+  enum class ConditionType {
+    // URLPattern is used as a condition.
+    kUrlPattern,
+  };
+  ConditionType type;
+
+  // URLPattern to be used for matching.
+  // This field is valid if `type` is `kUrlPattern`.
+  absl::optional<UrlPattern> url_pattern;
+};
+
+// Network source structure.
+// TODO(crbug.com/1371756): implement fields in the proposal.
+struct ServiceWorkerRouterNetworkSource {};
+
+// This represents a source of the router rule.
+// TODO(crbug.com/1371756): implement other sources in the proposal.
+struct ServiceWorkerRouterSource {
+  // Type of sources.
+  enum class SourceType {
+    kNetwork,
+  };
+  SourceType type;
+
+  absl::optional<ServiceWorkerRouterNetworkSource> network_source;
+};
+
+// This represents a ServiceWorker static routing API's router rule.
+// It represents each route.
+struct ServiceWorkerRouterRule {
+  // There can be a list of conditions, and expected to be evaluated
+  // from front to back.
+  std::vector<ServiceWorkerRouterCondition> conditions;
+  // There can be a list of sources, and expected to be routed from
+  // front to back.
+  std::vector<ServiceWorkerRouterSource> sources;
+};
+
+// This represents a condition of the router rule.
+// This represents a list of ServiceWorker static routing API's router rules.
+struct ServiceWorkerRouterRules {
+  std::vector<ServiceWorkerRouterRule> rules;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_RULE_H_
diff --git a/third_party/blink/public/common/service_worker/service_worker_router_rule_mojom_traits.h b/third_party/blink/public/common/service_worker/service_worker_router_rule_mojom_traits.h
new file mode 100644
index 0000000..53404d58
--- /dev/null
+++ b/third_party/blink/public/common/service_worker/service_worker_router_rule_mojom_traits.h
@@ -0,0 +1,92 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_RULE_MOJOM_TRAITS_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_RULE_MOJOM_TRAITS_H_
+
+#include "mojo/public/cpp/bindings/struct_traits.h"
+
+#include "third_party/blink/public/common/common_export.h"
+#include "third_party/blink/public/common/service_worker/service_worker_router_rule.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom.h"
+#include "third_party/blink/public/mojom/url_pattern.mojom.h"
+
+namespace mojo {
+
+template <>
+struct BLINK_COMMON_EXPORT
+    UnionTraits<blink::mojom::ServiceWorkerRouterConditionDataView,
+                blink::ServiceWorkerRouterCondition> {
+  static blink::mojom::ServiceWorkerRouterConditionDataView::Tag GetTag(
+      const blink::ServiceWorkerRouterCondition& data);
+
+  static const blink::UrlPattern& url_pattern(
+      const blink::ServiceWorkerRouterCondition& data) {
+    return *data.url_pattern;
+  }
+
+  static bool Read(blink::mojom::ServiceWorkerRouterConditionDataView data,
+                   blink::ServiceWorkerRouterCondition* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+    StructTraits<blink::mojom::ServiceWorkerRouterNetworkSourceDataView,
+                 blink::ServiceWorkerRouterNetworkSource> {
+  static bool Read(blink::mojom::ServiceWorkerRouterNetworkSourceDataView data,
+                   blink::ServiceWorkerRouterNetworkSource* out) {
+    return true;
+  }
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+    UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView,
+                blink::ServiceWorkerRouterSource> {
+  static blink::mojom::ServiceWorkerRouterSourceDataView::Tag GetTag(
+      const blink::ServiceWorkerRouterSource& data);
+
+  static const blink::ServiceWorkerRouterNetworkSource& network_source(
+      const blink::ServiceWorkerRouterSource& data) {
+    return *data.network_source;
+  }
+
+  static bool Read(blink::mojom::ServiceWorkerRouterSourceDataView data,
+                   blink::ServiceWorkerRouterSource* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+    StructTraits<blink::mojom::ServiceWorkerRouterRuleDataView,
+                 blink::ServiceWorkerRouterRule> {
+  static const std::vector<blink::ServiceWorkerRouterCondition>& conditions(
+      const blink::ServiceWorkerRouterRule& in) {
+    return in.conditions;
+  }
+
+  static const std::vector<blink::ServiceWorkerRouterSource>& sources(
+      const blink::ServiceWorkerRouterRule& in) {
+    return in.sources;
+  }
+
+  static bool Read(blink::mojom::ServiceWorkerRouterRuleDataView data,
+                   blink::ServiceWorkerRouterRule* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+    StructTraits<blink::mojom::ServiceWorkerRouterRulesDataView,
+                 blink::ServiceWorkerRouterRules> {
+  static const std::vector<blink::ServiceWorkerRouterRule>& rules(
+      const blink::ServiceWorkerRouterRules& in) {
+    return in.rules;
+  }
+
+  static bool Read(blink::mojom::ServiceWorkerRouterRulesDataView data,
+                   blink::ServiceWorkerRouterRules* out);
+};
+
+}  // namespace mojo
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_RULE_MOJOM_TRAITS_H_
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index 4ee4bb9..64ca4c8 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -275,6 +275,7 @@
     "//components/payments/mojom",
     "//components/schema_org/common:mojom",
     "//components/services/filesystem/public/mojom",
+    "//device/bluetooth/public/mojom",
     "//mojo/public/mojom/base",
     "//services/device/public/mojom",
     "//services/network/public/mojom",
@@ -1260,6 +1261,7 @@
     "service_worker/service_worker_object.mojom",
     "service_worker/service_worker_provider.mojom",
     "service_worker/service_worker_registration.mojom",
+    "service_worker/service_worker_router_rule.mojom",
 
     # Similarly, shared_worker.mojom and shared_worker_connector.mojom have a
     # dependency on message_port_descriptor.mojom, so are put here rather than
@@ -1413,6 +1415,16 @@
       ]
       traits_private_headers = [ "//third_party/blink/public/common/messaging/transferable_message_mojom_traits.h" ]
     },
+    {
+      types = [
+        {
+          mojom = "blink.mojom.ServiceWorkerRouterRules"
+          cpp = "::blink::ServiceWorkerRouterRules"
+        },
+      ]
+      traits_headers = [ "//third_party/blink/public/common/service_worker/service_worker_router_rule.h" ]
+      traits_private_headers = [ "//third_party/blink/public/common/service_worker/service_worker_router_rule_mojom_traits.h" ]
+    },
   ]
   cpp_typemaps += shared_cpp_typemaps
 
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom
index 82f5ac8..3c8cb6e 100644
--- a/third_party/blink/public/mojom/frame/frame.mojom
+++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -705,22 +705,28 @@
 
 // Implemented in Browser, this interface defines frame-specific methods
 // that will be invoked from the renderer process
-// (e.g. blink::LocalFrame) but processed at a higher priority than
-// methods invoked on the LocalFrameHost interface.
+// (e.g. blink::LocalFrame).
 //
 // Note this interface is not a channel-associated interface and as such
 // there are no ordering guarantees for messages sent on this interface
-// against the messages sent on LocalFrameHost. This interface is for
-// experimental purposes (https://crbug.com/1377753).
+// against messages sent to LocalFrameHost. These messages are only
+// meaningful if they arrive before navigation because these messages
+// are intended to prepare for navigation. This is why this interface is
+// not a channel-associated interface. This interface is for
+// experimental purposes (https://crbug.com/1377753,
+// https://crbug.com/1431792).
 interface NonAssociatedLocalFrameHost {
-  // Notifies that a renderer-initiated navigation to |url| will
-  // potentially start soon. This is fired before the beforeunload event
-  // (if it's needed) gets dispatched in the renderer, so that the
-  // browser can speculatively start service worker before processing
-  // beforeunload event, which might take a long time. Note that the
-  // navigation might not actually start, e.g. if it gets canceled by
-  // beforeunload.
-  WillPotentiallyStartOutermostMainFrameNavigation(url.mojom.Url url);
+  // Notifies that a renderer-initiated navigation to `urls` will
+  // potentially start.
+  // This is fired in the following situations so that the browser can
+  // speculatively start or warm-up service workers, which might take a
+  // long time to start.
+  // - The anchor tag is in the viewport.
+  // - The mouse hovered the anchor tag.
+  // - The mousedown event gets dispatched on the anchor tag.
+  // - The beforeunload event gets dispatched.
+  // Note that the navigation might not actually start.
+  MaybeStartOutermostMainFrameNavigation(array<url.mojom.Url> urls);
 };
 
 // Implemented in Blink, this interface defines frame-specific methods that will
diff --git a/third_party/blink/public/mojom/serial/serial.mojom b/third_party/blink/public/mojom/serial/serial.mojom
index 9e0f585..5d2e37a 100644
--- a/third_party/blink/public/mojom/serial/serial.mojom
+++ b/third_party/blink/public/mojom/serial/serial.mojom
@@ -4,6 +4,7 @@
 
 module blink.mojom;
 
+import "device/bluetooth/public/mojom/uuid.mojom";
 import "mojo/public/mojom/base/unguessable_token.mojom";
 import "services/device/public/mojom/serial.mojom";
 
@@ -16,6 +17,9 @@
   bool has_usb_vendor_id = false;
   uint16 usb_product_id;
   bool has_usb_product_id = false;
+
+  // Bluetooth service class UUID if the port is from a Bluetooth device.
+  bluetooth.mojom.UUID? bluetooth_service_class_id;
 };
 
 struct SerialPortFilter {
@@ -24,6 +28,9 @@
   bool has_vendor_id;
   uint16 product_id;
   bool has_product_id;
+
+  // Bluetooth service class UUID.
+  bluetooth.mojom.UUID? bluetooth_service_class_id;
 };
 
 // This interface must be provided by the browser process in order for the
@@ -37,7 +44,9 @@
   GetPorts() => (array<SerialPortInfo> ports);
 
   // Requests permission to access a port.
-  RequestPort(array<SerialPortFilter> filters) => (SerialPortInfo? port);
+  RequestPort(array<SerialPortFilter> filters,
+              array<bluetooth.mojom.UUID> allowed_bluetooth_service_class_ids)
+      => (SerialPortInfo? port);
 
   // Opens the port represented by |token| using |options| and returns a
   // connection to it in |port|.
diff --git a/third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom b/third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom
new file mode 100644
index 0000000..9c272435
--- /dev/null
+++ b/third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom
@@ -0,0 +1,48 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module blink.mojom;
+
+import "third_party/blink/public/mojom/url_pattern.mojom";
+
+// TODO(crbug.com/1371756): leave a link to an explainer or a specification
+// when it get ready.
+
+// This represents a condition of the router rule.
+// TODO(crbug.com/1371756): implement other conditions in the proposal.
+union ServiceWorkerRouterCondition {
+  // URLPattern to be used for matching.
+  UrlPattern url_pattern;
+};
+
+// This is used for specifying the source is network.
+// TODO(crbug.com/1371756): implement fields in the proposal.
+struct ServiceWorkerRouterNetworkSource {
+};
+
+// This represents a source of the router rule.
+// TODO(crbug.com/1371756): implement other sources in the proposal.
+union ServiceWorkerRouterSource {
+  ServiceWorkerRouterNetworkSource network_source;
+};
+
+// This represents a ServiceWorker static routing API's router rule.
+// It represents each route.
+// When an request matches `conditions`, a response is fetched from `sources`.
+// `conditions` are evaluated sequentially to ensure all of them are fulfilled.
+// `sources` are tried sequentially, and quit once available source is found
+// and used.
+struct ServiceWorkerRouterRule {
+  // There can be a list of conditions, and expected to be evaluated
+  // from front to back.
+  array<ServiceWorkerRouterCondition> conditions;
+  // There can be a list of sources, and expected to be routed from
+  // front to back.
+  array<ServiceWorkerRouterSource> sources;
+};
+
+// This represents a list of ServiceWorker static routing API's router rules.
+struct ServiceWorkerRouterRules {
+  array<ServiceWorkerRouterRule> rules;
+};
diff --git a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
index dd4e3d9..52af66c 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
@@ -814,6 +814,7 @@
     kScrollStartTargetY = 760,
     kScrollStartTarget = 761,
     kTimelineScope = 762,
+    kScrollbarColor = 763,
     // 1. Add new features above this line (don't change the assigned numbers of
     //    the existing items).
     // 2. Run the src/tools/metrics/histograms/update_use_counter_css.py script
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
index 945924c..8cb66571 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3914,6 +3914,8 @@
   kCriticalCHRestartNavigationTiming = 4574,
   kTopLevelDocumentWithEmbeddedCredentials = 4575,
   kV8Navigator_GetInterestGroupAdAuctionData_Method = 4576,
+  kLongAnimationFrameObserver = 4577,
+  kLongAnimationFrameRequested = 4578,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/web/web_navigation_control.h b/third_party/blink/public/web/web_navigation_control.h
index dd9b753..05bb5ac 100644
--- a/third_party/blink/public/web/web_navigation_control.h
+++ b/third_party/blink/public/web/web_navigation_control.h
@@ -9,6 +9,7 @@
 
 #include "base/functional/callback.h"
 #include "third_party/blink/public/common/tokens/tokens.h"
+#include "third_party/blink/public/platform/web_vector.h"
 #include "third_party/blink/public/web/web_document_loader.h"
 #include "third_party/blink/public/web/web_frame_load_type.h"
 #include "third_party/blink/public/web/web_local_frame.h"
@@ -67,15 +68,18 @@
   virtual void SetIsNotOnInitialEmptyDocument() = 0;
   virtual bool IsOnInitialEmptyDocument() = 0;
 
-  // Notifies that a renderer-initiated navigation to `url` will
-  // potentially start soon. This is fired before the beforeunload event
-  // (if it's needed) gets dispatched in the renderer, so that the
-  // browser can speculatively start service worker before processing
-  // beforeunload event, which might take a long time. Note that the
-  // navigation might not actually start, e.g. if it gets canceled by
-  // beforeunload.
-  virtual void WillPotentiallyStartOutermostMainFrameNavigation(
-      const WebURL&) const = 0;
+  // Notifies that a renderer-initiated navigation to `urls` will
+  // potentially start.
+  // This is fired in the following situations so that the browser can
+  // speculatively warm-up service workers (start the renderer process and
+  // load scripts) or start (warm up + run the service worker script).
+  // - The anchor tag is in the viewport.
+  // - The mouse hovered the anchor tag.
+  // - The mousedown or touchstart event gets dispatched on the anchor tag.
+  // - The beforeunload event gets dispatched.
+  // Note that the navigation might not actually start.
+  virtual void MaybeStartOutermostMainFrameNavigation(
+      const WebVector<WebURL>& urls) const = 0;
 
   // Marks the frame as loading, before WebLocalFrameClient issues a navigation
   // request through the browser process on behalf of the frame.
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
index 0109365..f3465d2 100644
--- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
+++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -2031,7 +2031,6 @@
 
     logging_nodes = SequenceNode([
         make_report_deprecate_as(cg_context),
-        make_report_high_entropy(cg_context),
         make_report_measure_as(cg_context),
         make_log_activity(cg_context),
     ])
@@ -2129,6 +2128,7 @@
 
     body.extend([
         make_report_deprecate_as(cg_context),
+        make_report_high_entropy(cg_context),
         make_report_measure_as(cg_context),
         make_log_activity(cg_context),
         EmptyNode(),
@@ -2155,6 +2155,10 @@
               "${class_name}::GetWrapperTypeInfo(), ${v8_receiver});"))
         body.append(T("bindings::V8SetReturnValue(${info}, v8_wrapper);"))
 
+    body.extend([
+        make_report_high_entropy_direct(cg_context),
+    ])
+
     return func_def
 
 
diff --git a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
index 4bbe68a..c96606f6 100755
--- a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
+++ b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
@@ -56,6 +56,7 @@
     'IntrinsicLength',
     'TextDecorationThickness',
     'StyleAspectRatio',
+    'absl::optional<StyleScrollbarColor>',
     'absl::optional<StyleIntrinsicLength>',
     'absl::optional<StyleOverflowClipMargin>',
     # Aligns like float
diff --git a/third_party/blink/renderer/core/css/cascade_layer.cc b/third_party/blink/renderer/core/css/cascade_layer.cc
index af4262b..12767e0 100644
--- a/third_party/blink/renderer/core/css/cascade_layer.cc
+++ b/third_party/blink/renderer/core/css/cascade_layer.cc
@@ -44,8 +44,7 @@
 void CascadeLayer::ToStringInternal(StringBuilder& result,
                                     const String& prefix) const {
   for (const auto& sub_layer : direct_sub_layers_) {
-    AtomicString name =
-        sub_layer->name_.length() ? sub_layer->name_ : "(anonymous)";
+    String name = sub_layer->name_.length() ? sub_layer->name_ : "(anonymous)";
     if (result.length()) {
       result.Append(",");
     }
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.cc b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.cc
index 0dd24b77..03369ff 100644
--- a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.cc
+++ b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.cc
@@ -12,13 +12,19 @@
 const CSSSelector*
 CheckPseudoHasArgumentContext::GetCurrentRelationAndNextCompound(
     const CSSSelector* compound_selector,
-    CSSSelector::RelationType& relation) {
+    CSSSelector::RelationType& relation,
+    bool& compound_contains_sibling_relationship) {
   DCHECK(compound_selector);
+  compound_contains_sibling_relationship = false;
   for (const CSSSelector* simple_selector = compound_selector; simple_selector;
        simple_selector = simple_selector->NextSimpleSelector()) {
     CheckPseudoHasFastRejectFilter::CollectPseudoHasArgumentHashes(
         pseudo_has_argument_hashes_, simple_selector);
 
+    if (simple_selector->IsChildIndexedSelector()) {
+      compound_contains_sibling_relationship = true;
+    }
+
     relation = simple_selector->Relation();
     if (relation != CSSSelector::kSubSelector) {
       return simple_selector->NextSimpleSelector();
@@ -35,10 +41,24 @@
   adjacent_distance_limit_ = 0;
   bool contains_child_or_descendant_combinator = false;
   bool sibling_combinator_at_leftmost = false;
+  bool compound_contains_sibling_relationship = false;
 
-  for (selector = GetCurrentRelationAndNextCompound(selector, relation);
+  for (selector = GetCurrentRelationAndNextCompound(
+           selector, relation, compound_contains_sibling_relationship);
        selector;
-       selector = GetCurrentRelationAndNextCompound(selector, relation)) {
+       selector = GetCurrentRelationAndNextCompound(
+           selector, relation, compound_contains_sibling_relationship)) {
+    if (compound_contains_sibling_relationship) {
+      // If the compound contains an :nth-child() or another child-indexed
+      // selector, we need to do the same invalidation as for an indirect
+      // adjacent combinator since inserting or removing a sibling at any place
+      // may change matching of a :has() selector on any of its siblings.
+      if (contains_child_or_descendant_combinator) {
+        sibling_combinator_at_leftmost = true;
+      } else {
+        sibling_combinator_at_rightmost_ = true;
+      }
+    }
     switch (relation) {
       case CSSSelector::kRelativeDescendant:
         leftmost_relation_ = relation;
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.h b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.h
index b88d93c..8c17637 100644
--- a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.h
+++ b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.h
@@ -130,7 +130,8 @@
 
   inline const CSSSelector* GetCurrentRelationAndNextCompound(
       const CSSSelector* compound_selector,
-      CSSSelector::RelationType& relation);
+      CSSSelector::RelationType& relation,
+      bool& contains_child_indexed);
 
   // Indicate the :has argument relative type and subtree traversal scope.
   // If 'adjacent_distance_limit' is integer max, it means that all the
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 12ebc6f..1df7723e 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -4139,6 +4139,21 @@
       supports_incremental_style: true,
     },
     {
+      // TODO: This should be interpolable: true
+      name: "scrollbar-color",
+      property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      inherited: true,
+      name_for_methods: "ScrollbarColor",
+      type_name: "absl::optional<StyleScrollbarColor>",
+      converter: "ConvertScrollbarColor",
+      keywords: ["auto"],
+      field_group: "*",
+      field_template: "external",
+      default_value: "absl::optional<StyleScrollbarColor>()",
+      include_paths: ["third_party/blink/renderer/core/style/style_scrollbar_color.h"],
+      runtime_flag: "ScrollbarColor",
+    },
+    {
       name: "scrollbar-gutter",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
       inherited: false,
diff --git a/third_party/blink/renderer/core/css/css_property_equality.cc b/third_party/blink/renderer/core/css/css_property_equality.cc
index 13ed1eab..39e7bcb6 100644
--- a/third_party/blink/renderer/core/css/css_property_equality.cc
+++ b/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -590,6 +590,8 @@
       return a.Right() == b.Right();
     case CSSPropertyID::kRubyPosition:
       return a.GetRubyPosition() == b.GetRubyPosition();
+    case CSSPropertyID::kScrollbarColor:
+      return a.ScrollbarColor() == b.ScrollbarColor();
     case CSSPropertyID::kScrollbarGutter:
       return a.ScrollbarGutter() == b.ScrollbarGutter();
     case CSSPropertyID::kScrollbarWidth:
diff --git a/third_party/blink/renderer/core/css/css_selector.cc b/third_party/blink/renderer/core/css/css_selector.cc
index c9d836b..e6d9cbf 100644
--- a/third_party/blink/renderer/core/css/css_selector.cc
+++ b/third_party/blink/renderer/core/css/css_selector.cc
@@ -1533,6 +1533,24 @@
   }
 }
 
+bool CSSSelector::IsChildIndexedSelector() const {
+  switch (GetPseudoType()) {
+    case kPseudoFirstChild:
+    case kPseudoFirstOfType:
+    case kPseudoLastChild:
+    case kPseudoLastOfType:
+    case kPseudoNthChild:
+    case kPseudoNthLastChild:
+    case kPseudoNthLastOfType:
+    case kPseudoNthOfType:
+    case kPseudoOnlyChild:
+    case kPseudoOnlyOfType:
+      return true;
+    default:
+      return false;
+  }
+}
+
 CSSSelector::RelationType ConvertRelationToRelative(
     CSSSelector::RelationType relation) {
   switch (relation) {
diff --git a/third_party/blink/renderer/core/css/css_selector.h b/third_party/blink/renderer/core/css/css_selector.h
index ab38689b..4e54d796 100644
--- a/third_party/blink/renderer/core/css/css_selector.h
+++ b/third_party/blink/renderer/core/css/css_selector.h
@@ -541,6 +541,10 @@
   // nested rules that would otherwise lack the nesting selector (&).
   bool IsImplicit() const { return is_implicitly_added_; }
 
+  // Returns true for simple selectors whose evaluation depends on DOM tree
+  // position like :first-of-type and :nth-child().
+  bool IsChildIndexedSelector() const;
+
   void Trace(Visitor* visitor) const;
 
   static String FormatPseudoTypeForDebugging(PseudoType);
diff --git a/third_party/blink/renderer/core/css/cssom/css_numeric_value_type.cc b/third_party/blink/renderer/core/css/cssom/css_numeric_value_type.cc
index 3438a44..63a7443 100644
--- a/third_party/blink/renderer/core/css/cssom/css_numeric_value_type.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_numeric_value_type.cc
@@ -96,7 +96,7 @@
 
 }  // namespace
 
-AtomicString CSSNumericValueType::BaseTypeToString(BaseType base_type) {
+String CSSNumericValueType::BaseTypeToString(BaseType base_type) {
   switch (base_type) {
     case BaseType::kLength:
       return "length";
diff --git a/third_party/blink/renderer/core/css/cssom/css_numeric_value_type.h b/third_party/blink/renderer/core/css/cssom/css_numeric_value_type.h
index 5722ac7..1f880b96 100644
--- a/third_party/blink/renderer/core/css/cssom/css_numeric_value_type.h
+++ b/third_party/blink/renderer/core/css/cssom/css_numeric_value_type.h
@@ -30,7 +30,7 @@
   static constexpr unsigned kNumBaseTypes =
       static_cast<unsigned>(BaseType::kNumBaseTypes);
 
-  static AtomicString BaseTypeToString(BaseType);
+  static String BaseTypeToString(BaseType);
 
   explicit CSSNumericValueType(
       CSSPrimitiveValue::UnitType = CSSPrimitiveValue::UnitType::kNumber);
diff --git a/third_party/blink/renderer/core/css/dom_window_css.cc b/third_party/blink/renderer/core/css/dom_window_css.cc
index 25d938a5..f99d778 100644
--- a/third_party/blink/renderer/core/css/dom_window_css.cc
+++ b/third_party/blink/renderer/core/css/dom_window_css.cc
@@ -53,7 +53,7 @@
         MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLStandardMode);
     bool is_animation_tainted = false;
     return CSSParser::ParseValueForCustomProperty(
-               dummy_style, "--valid", value, false,
+               dummy_style, AtomicString("--valid"), value, false,
                execution_context->GetSecureContextMode(), nullptr,
                is_animation_tainted) != MutableCSSPropertyValueSet::kParseError;
   }
diff --git a/third_party/blink/renderer/core/css/font_face_set.cc b/third_party/blink/renderer/core/css/font_face_set.cc
index 72205d9..84da803 100644
--- a/third_party/blink/renderer/core/css/font_face_set.cc
+++ b/third_party/blink/renderer/core/css/font_face_set.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/core/css/font_face_cache.h"
 #include "third_party/blink/renderer/core/css/font_face_set_load_event.h"
+#include "third_party/blink/renderer/platform/font_family_names.h"
 #include "third_party/blink/renderer/platform/fonts/font.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -14,7 +15,11 @@
 namespace blink {
 
 const int FontFaceSet::kDefaultFontSize = 10;
-const char FontFaceSet::kDefaultFontFamily[] = "sans-serif";
+
+// static
+const AtomicString& FontFaceSet::DefaultFontFamily() {
+  return font_family_names::kSansSerif;
+}
 
 void FontFaceSet::HandlePendingEventsAndPromisesSoon() {
   if (!pending_task_queued_) {
diff --git a/third_party/blink/renderer/core/css/font_face_set.h b/third_party/blink/renderer/core/css/font_face_set.h
index 00277262..dc0b6bdb 100644
--- a/third_party/blink/renderer/core/css/font_face_set.h
+++ b/third_party/blink/renderer/core/css/font_face_set.h
@@ -72,7 +72,7 @@
 
  protected:
   static const int kDefaultFontSize;
-  static const char kDefaultFontFamily[];
+  static const AtomicString& DefaultFontFamily();
 
   virtual bool ResolveFontStyle(const String&, Font&) = 0;
   virtual bool InActiveContext() const = 0;
diff --git a/third_party/blink/renderer/core/css/font_face_set_document.cc b/third_party/blink/renderer/core/css/font_face_set_document.cc
index 3ac000f..09c5ebd 100644
--- a/third_party/blink/renderer/core/css/font_face_set_document.cc
+++ b/third_party/blink/renderer/core/css/font_face_set_document.cc
@@ -191,8 +191,8 @@
 
   FontFamily font_family;
   font_family.SetFamily(
-      FontFaceSet::kDefaultFontFamily,
-      FontFamily::InferredTypeFor(FontFaceSet::kDefaultFontFamily));
+      FontFaceSet::DefaultFontFamily(),
+      FontFamily::InferredTypeFor(FontFaceSet::DefaultFontFamily()));
 
   FontDescription default_font_description;
   default_font_description.SetFamily(font_family);
diff --git a/third_party/blink/renderer/core/css/font_face_set_worker.cc b/third_party/blink/renderer/core/css/font_face_set_worker.cc
index 548a199..85cfaa8 100644
--- a/third_party/blink/renderer/core/css/font_face_set_worker.cc
+++ b/third_party/blink/renderer/core/css/font_face_set_worker.cc
@@ -85,8 +85,8 @@
 
   FontFamily font_family;
   font_family.SetFamily(
-      FontFaceSet::kDefaultFontFamily,
-      FontFamily::InferredTypeFor(FontFaceSet::kDefaultFontFamily));
+      FontFaceSet::DefaultFontFamily(),
+      FontFamily::InferredTypeFor(FontFaceSet::DefaultFontFamily()));
 
   FontDescription default_font_description;
   default_font_description.SetFamily(font_family);
diff --git a/third_party/blink/renderer/core/css/parser/container_query_parser.cc b/third_party/blink/renderer/core/css/parser/container_query_parser.cc
index 69f5f6f..d05fd35 100644
--- a/third_party/blink/renderer/core/css/parser/container_query_parser.cc
+++ b/third_party/blink/renderer/core/css/parser/container_query_parser.cc
@@ -172,7 +172,7 @@
     if (const MediaQueryExpNode* query =
             ConsumeFeatureQuery(block, offsets, StyleFeatureSet())) {
       context_.Count(WebFeature::kCSSStyleContainerQuery);
-      return MediaQueryExpNode::Function(query, "style");
+      return MediaQueryExpNode::Function(query, AtomicString("style"));
     }
   }
   range = original_range;
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
index f8d2bbad..7c03a25 100644
--- a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
+++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
@@ -676,8 +676,9 @@
 
   CSSSelector selector;
   selector.SetMatch(CSSSelector::kPseudoClass);
-  selector.UpdatePseudoType("-internal-relative-anchor", *context_,
-                            false /*has_arguments*/, context_->Mode());
+  selector.UpdatePseudoType(AtomicString("-internal-relative-anchor"),
+                            *context_, false /*has_arguments*/,
+                            context_->Mode());
   DCHECK_EQ(selector.GetPseudoType(), CSSSelector::kPseudoRelativeAnchor);
   output_.push_back(selector);
 
@@ -737,7 +738,7 @@
     return CSSSelector(parent_rule_for_nesting, /*is_implicit=*/true);
   }
   DCHECK_EQ(nesting_type, CSSNestingType::kScope);
-  return CSSSelector("scope", /*is_implicit=*/true);
+  return CSSSelector(AtomicString("scope"), /*is_implicit=*/true);
 }
 
 // Within @scope, each compound that contains either :scope or '&' is prepended
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index 726962f3..fa8dcf0 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -2333,7 +2333,8 @@
     // allow it for backward compatibility.
     // See https://github.com/w3c/csswg-drafts/issues/5795 for details.
     if (args.Peek().Id() == CSSValueID::kNone) {
-      list_style = MakeGarbageCollected<CSSCustomIdentValue>("none");
+      list_style =
+          MakeGarbageCollected<CSSCustomIdentValue>(AtomicString("none"));
       args.ConsumeIncludingWhitespace();
     } else {
       list_style = css_parsing_utils::ConsumeCounterStyleName(args, context);
@@ -6813,6 +6814,53 @@
   return list;
 }
 
+// https://www.w3.org/TR/css-scrollbars/
+// auto | <color>{2}
+const CSSValue* ScrollbarColor::ParseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    const CSSParserLocalContext&) const {
+  DCHECK(RuntimeEnabledFeatures::ScrollbarColorEnabled());
+
+  CSSValueID id = range.Peek().Id();
+  if (id == CSSValueID::kAuto) {
+    return css_parsing_utils::ConsumeIdent(range);
+  }
+
+  CSSValue* thumb_color = css_parsing_utils::ConsumeColor(range, context);
+  if (!thumb_color) {
+    return nullptr;
+  }
+
+  CSSValue* track_color = css_parsing_utils::ConsumeColor(range, context);
+  if (!track_color) {
+    return nullptr;
+  }
+  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+  list->Append(*thumb_color);
+  list->Append(*track_color);
+  return list;
+}
+
+const CSSValue* ScrollbarColor::CSSValueFromComputedStyleInternal(
+    const ComputedStyle& style,
+    const LayoutObject*,
+    bool allow_visited_style) const {
+  absl::optional<StyleScrollbarColor> scrollbar_color = style.ScrollbarColor();
+  if (scrollbar_color == absl::nullopt) {
+    return CSSIdentifierValue::Create(CSSValueID::kAuto);
+  }
+
+  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+  list->Append(*ComputedStyleUtils::CurrentColorOrValidColor(
+      style, scrollbar_color.value().GetThumbColor(),
+      CSSValuePhase::kComputedValue));
+  list->Append(*ComputedStyleUtils::CurrentColorOrValidColor(
+      style, scrollbar_color.value().GetTrackColor(),
+      CSSValuePhase::kComputedValue));
+  return list;
+}
+
 // https://www.w3.org/TR/css-overflow-4
 // auto | stable && both-edges?
 const CSSValue* ScrollbarGutter::ParseSingleValue(
diff --git a/third_party/blink/renderer/core/css/properties/longhands/variable.h b/third_party/blink/renderer/core/css/properties/longhands/variable.h
index 01a4df1..ad43bc9 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/variable.h
+++ b/third_party/blink/renderer/core/css/properties/longhands/variable.h
@@ -24,7 +24,7 @@
   bool IsAffectedByAll() const override { return false; }
   CSSPropertyName GetCSSPropertyName() const override {
     NOTREACHED();
-    return CSSPropertyName("");
+    return CSSPropertyName(g_empty_atom);
   }
   const char* GetPropertyName() const override { return "variable"; }
   const WTF::AtomicString& GetPropertyNameAtomicString() const override {
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
index d8daae8..24be3255 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -768,7 +768,7 @@
 
   builder.SetTextShadow(ComputedStyleInitialValues::InitialTextShadow());
   builder.SetBoxShadow(ComputedStyleInitialValues::InitialBoxShadow());
-  builder.SetColorScheme({"light", "dark"});
+  builder.SetColorScheme({AtomicString("light"), AtomicString("dark")});
   if (builder.ShouldForceColor(builder.AccentColor())) {
     builder.SetAccentColor(ComputedStyleInitialValues::InitialAccentColor());
   }
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index d8788c2..02ef85b 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -2777,6 +2777,23 @@
   return RubyPosition::kBefore;
 }
 
+absl::optional<StyleScrollbarColor>
+StyleBuilderConverter::ConvertScrollbarColor(StyleResolverState& state,
+                                             const CSSValue& value) {
+  auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
+  if (identifier_value && identifier_value->GetValueID() == CSSValueID::kAuto) {
+    return absl::nullopt;
+  }
+
+  const CSSValueList& list = To<CSSValueList>(value);
+  DCHECK_GE(list.length(), 1u);
+  DCHECK_LE(list.length(), 2u);
+  const StyleColor thumb_color = ConvertStyleColor(state, list.First());
+  const StyleColor track_color = ConvertStyleColor(state, list.Last());
+
+  return StyleScrollbarColor(thumb_color, track_color);
+}
+
 ScrollbarGutter StyleBuilderConverter::ConvertScrollbarGutter(
     StyleResolverState& state,
     const CSSValue& value) {
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
index b089245..fc8b616 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
@@ -332,6 +332,10 @@
   static RubyPosition ConvertRubyPosition(StyleResolverState& state,
                                           const CSSValue& value);
 
+  static absl::optional<StyleScrollbarColor> ConvertScrollbarColor(
+      StyleResolverState& state,
+      const CSSValue& value);
+
   static ScrollbarGutter ConvertScrollbarGutter(StyleResolverState& state,
                                                 const CSSValue& value);
 
diff --git a/third_party/blink/renderer/core/css/style_environment_variables.cc b/third_party/blink/renderer/core/css/style_environment_variables.cc
index f847c10..550d332 100644
--- a/third_party/blink/renderer/core/css/style_environment_variables.cc
+++ b/third_party/blink/renderer/core/css/style_environment_variables.cc
@@ -70,41 +70,41 @@
     const FeatureContext* feature_context) {
   switch (variable) {
     case UADefinedVariable::kSafeAreaInsetTop:
-      return "safe-area-inset-top";
+      return AtomicString("safe-area-inset-top");
     case UADefinedVariable::kSafeAreaInsetLeft:
-      return "safe-area-inset-left";
+      return AtomicString("safe-area-inset-left");
     case UADefinedVariable::kSafeAreaInsetBottom:
-      return "safe-area-inset-bottom";
+      return AtomicString("safe-area-inset-bottom");
     case UADefinedVariable::kSafeAreaInsetRight:
-      return "safe-area-inset-right";
+      return AtomicString("safe-area-inset-right");
     case UADefinedVariable::kKeyboardInsetTop:
-      return "keyboard-inset-top";
+      return AtomicString("keyboard-inset-top");
     case UADefinedVariable::kKeyboardInsetLeft:
-      return "keyboard-inset-left";
+      return AtomicString("keyboard-inset-left");
     case UADefinedVariable::kKeyboardInsetBottom:
-      return "keyboard-inset-bottom";
+      return AtomicString("keyboard-inset-bottom");
     case UADefinedVariable::kKeyboardInsetRight:
-      return "keyboard-inset-right";
+      return AtomicString("keyboard-inset-right");
     case UADefinedVariable::kKeyboardInsetWidth:
-      return "keyboard-inset-width";
+      return AtomicString("keyboard-inset-width");
     case UADefinedVariable::kKeyboardInsetHeight:
-      return "keyboard-inset-height";
+      return AtomicString("keyboard-inset-height");
     case UADefinedVariable::kTitlebarAreaX:
       DCHECK(RuntimeEnabledFeatures::WebAppWindowControlsOverlayEnabled(
           feature_context));
-      return "titlebar-area-x";
+      return AtomicString("titlebar-area-x");
     case UADefinedVariable::kTitlebarAreaY:
       DCHECK(RuntimeEnabledFeatures::WebAppWindowControlsOverlayEnabled(
           feature_context));
-      return "titlebar-area-y";
+      return AtomicString("titlebar-area-y");
     case UADefinedVariable::kTitlebarAreaWidth:
       DCHECK(RuntimeEnabledFeatures::WebAppWindowControlsOverlayEnabled(
           feature_context));
-      return "titlebar-area-width";
+      return AtomicString("titlebar-area-width");
     case UADefinedVariable::kTitlebarAreaHeight:
       DCHECK(RuntimeEnabledFeatures::WebAppWindowControlsOverlayEnabled(
           feature_context));
-      return "titlebar-area-height";
+      return AtomicString("titlebar-area-height");
     default:
       break;
   }
@@ -118,22 +118,22 @@
   switch (variable) {
     case UADefinedTwoDimensionalVariable::kViewportSegmentTop:
       DCHECK(RuntimeEnabledFeatures::CSSFoldablesEnabled());
-      return "viewport-segment-top";
+      return AtomicString("viewport-segment-top");
     case UADefinedTwoDimensionalVariable::kViewportSegmentRight:
       DCHECK(RuntimeEnabledFeatures::CSSFoldablesEnabled());
-      return "viewport-segment-right";
+      return AtomicString("viewport-segment-right");
     case UADefinedTwoDimensionalVariable::kViewportSegmentBottom:
       DCHECK(RuntimeEnabledFeatures::CSSFoldablesEnabled());
-      return "viewport-segment-bottom";
+      return AtomicString("viewport-segment-bottom");
     case UADefinedTwoDimensionalVariable::kViewportSegmentLeft:
       DCHECK(RuntimeEnabledFeatures::CSSFoldablesEnabled());
-      return "viewport-segment-left";
+      return AtomicString("viewport-segment-left");
     case UADefinedTwoDimensionalVariable::kViewportSegmentWidth:
       DCHECK(RuntimeEnabledFeatures::CSSFoldablesEnabled());
-      return "viewport-segment-width";
+      return AtomicString("viewport-segment-width");
     case UADefinedTwoDimensionalVariable::kViewportSegmentHeight:
       DCHECK(RuntimeEnabledFeatures::CSSFoldablesEnabled());
-      return "viewport-segment-height";
+      return AtomicString("viewport-segment-height");
     default:
       break;
   }
diff --git a/third_party/blink/renderer/core/css/ua_counter_style_map.cc b/third_party/blink/renderer/core/css/ua_counter_style_map.cc
index 87d0769..a868948 100644
--- a/third_party/blink/renderer/core/css/ua_counter_style_map.cc
+++ b/third_party/blink/renderer/core/css/ua_counter_style_map.cc
@@ -30,60 +30,60 @@
 
   // https://drafts.csswg.org/css-counter-styles-3/#simple-numeric
 
-  ua_rules.Set("decimal", R"CSS(
+  ua_rules.Set(keywords::kDecimal, R"CSS(
     system: numeric;
     symbols: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9';
   )CSS");
 
-  ua_rules.Set("decimal-leading-zero", R"CSS(
+  ua_rules.Set(AtomicString("decimal-leading-zero"), R"CSS(
     system: extends decimal;
     pad: 2 '0';
   )CSS");
 
   // ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩
-  ua_rules.Set("arabic-indic", R"CSS(
+  ua_rules.Set(AtomicString("arabic-indic"), R"CSS(
     system: numeric;
     symbols: "\660" "\661" "\662" "\663" "\664" "\665" "\666" "\667" "\668" "\669";
   )CSS");
 
   // Officially, 'armenian' is specified as an additive counter style supporting
   // 1-9999. We extend the range to 99999999 using a special algorithm.
-  ua_rules.Set("armenian", R"CSS(
+  ua_rules.Set(AtomicString("armenian"), R"CSS(
     system: -internal-upper-armenian;
     range: 1 99999999;
   )CSS");
 
-  ua_rules.Set("upper-armenian", R"CSS(
+  ua_rules.Set(AtomicString("upper-armenian"), R"CSS(
     system: extends armenian;
   )CSS");
 
   // Officially, 'lower-armenian' is specified as an additive counter style
   // supporting 1-9999. We extend the range to 99999999 using a special
   // algorithm.
-  ua_rules.Set("lower-armenian", R"CSS(
+  ua_rules.Set(AtomicString("lower-armenian"), R"CSS(
     system: -internal-lower-armenian;
     range: 1 99999999;
   )CSS");
 
   // ০ ১ ২ ৩ ৪ ৫ ৬ ৭ ৮ ৯
-  ua_rules.Set("bengali", R"CSS(
+  ua_rules.Set(AtomicString("bengali"), R"CSS(
     system: numeric;
     symbols: "\9E6" "\9E7" "\9E8" "\9E9" "\9EA" "\9EB" "\9EC" "\9ED" "\9EE" "\9EF";
   )CSS");
 
   // ០ ១ ២ ៣ ៤ ៥ ៦ ៧ ៨ ៩
-  ua_rules.Set("cambodian", R"CSS(
+  ua_rules.Set(AtomicString("cambodian"), R"CSS(
     system: numeric;
     symbols: "\17E0" "\17E1" "\17E2" "\17E3" "\17E4" "\17E5" "\17E6" "\17E7" "\17E8" "\17E9";
   )CSS");
 
-  ua_rules.Set("khmer", R"CSS(
+  ua_rules.Set(AtomicString("khmer"), R"CSS(
     system: extends cambodian;
   )CSS");
 
   // symbols: 〇 一 二 三 四 五 六 七 八 九
   // suffix: "、"
-  ua_rules.Set("cjk-decimal", R"CSS(
+  ua_rules.Set(AtomicString("cjk-decimal"), R"CSS(
     system: numeric;
     range: 0 infinite;
     symbols: "\3007" "\4E00" "\4E8C" "\4E09" "\56DB" "\4E94" "\516D" "\4E03" "\516B" "\4E5D";
@@ -91,7 +91,7 @@
   )CSS");
 
   // ० १ २ ३ ४ ५ ६ ७ ८ ९
-  ua_rules.Set("devanagari", R"CSS(
+  ua_rules.Set(AtomicString("devanagari"), R"CSS(
     system: numeric;
     symbols: "\966" "\967" "\968" "\969" "\96A" "\96B" "\96C" "\96D" "\96E" "\96F";
   )CSS");
@@ -100,138 +100,138 @@
   // 3000 ძ, 2000 ც, 1000 ჩ, 900 შ, 800 ყ, 700 ღ, 600 ქ, 500 ფ, 400 ჳ, 300 ტ,
   // 200 ს, 100 რ, 90 ჟ, 80 პ, 70 ო, 60 ჲ, 50 ნ, 40 მ, 30 ლ, 20 კ, 10 ი, 9 თ, 8
   // ჱ, 7 ზ, 6 ვ, 5 ე, 4 დ, 3 გ, 2 ბ, 1 ა
-  ua_rules.Set("georgian", R"CSS(
+  ua_rules.Set(AtomicString("georgian"), R"CSS(
     system: additive;
     range: 1 19999;
     additive-symbols: 10000 \10F5, 9000 \10F0, 8000 \10EF, 7000 \10F4, 6000 \10EE, 5000 \10ED, 4000 \10EC, 3000 \10EB, 2000 \10EA, 1000 \10E9, 900 \10E8, 800 \10E7, 700 \10E6, 600 \10E5, 500 \10E4, 400 \10F3, 300 \10E2, 200 \10E1, 100 \10E0, 90 \10DF, 80 \10DE, 70 \10DD, 60 \10F2, 50 \10DC, 40 \10DB, 30 \10DA, 20 \10D9, 10 \10D8, 9 \10D7, 8 \10F1, 7 \10D6, 6 \10D5, 5 \10D4, 4 \10D3, 3 \10D2, 2 \10D1, 1 \10D0;
   )CSS");
 
   // ૦ ૧ ૨ ૩ ૪ ૫ ૬ ૭ ૮ ૯
-  ua_rules.Set("gujarati", R"CSS(
+  ua_rules.Set(AtomicString("gujarati"), R"CSS(
     system: numeric;
     symbols: "\AE6" "\AE7" "\AE8" "\AE9" "\AEA" "\AEB" "\AEC" "\AED" "\AEE" "\AEF";
   )CSS");
 
   // ੦ ੧ ੨ ੩ ੪ ੫ ੬ ੭ ੮ ੯
-  ua_rules.Set("gurmukhi", R"CSS(
+  ua_rules.Set(AtomicString("gurmukhi"), R"CSS(
     system: numeric;
     symbols: "\A66" "\A67" "\A68" "\A69" "\A6A" "\A6B" "\A6C" "\A6D" "\A6E" "\A6F";
   )CSS");
 
   // Officially, 'hebrew' is specified as an additive counter style supporting
   // 1-10999. We extend the range to 0-999999 using a special algorithm.
-  ua_rules.Set("hebrew", R"CSS(
+  ua_rules.Set(AtomicString("hebrew"), R"CSS(
     system: -internal-hebrew;
     range: 0 999999;
   )CSS");
 
   // ೦ ೧ ೨ ೩ ೪ ೫ ೬ ೭ ೮ ೯
-  ua_rules.Set("kannada", R"CSS(
+  ua_rules.Set(AtomicString("kannada"), R"CSS(
     system: numeric;
     symbols: "\CE6" "\CE7" "\CE8" "\CE9" "\CEA" "\CEB" "\CEC" "\CED" "\CEE" "\CEF";
   )CSS");
 
   // ໐ ໑ ໒ ໓ ໔ ໕ ໖ ໗ ໘ ໙
-  ua_rules.Set("lao", R"CSS(
+  ua_rules.Set(AtomicString("lao"), R"CSS(
     system: numeric;
     symbols: "\ED0" "\ED1" "\ED2" "\ED3" "\ED4" "\ED5" "\ED6" "\ED7" "\ED8" "\ED9";
   )CSS");
 
   // ൦ ൧ ൨ ൩ ൪ ൫ ൬ ൭ ൮ ൯
-  ua_rules.Set("malayalam", R"CSS(
+  ua_rules.Set(AtomicString("malayalam"), R"CSS(
     system: numeric;
     symbols: "\D66" "\D67" "\D68" "\D69" "\D6A" "\D6B" "\D6C" "\D6D" "\D6E" "\D6F";
   )CSS");
 
   // ᠐ ᠑ ᠒ ᠓ ᠔ ᠕ ᠖ ᠗ ᠘ ᠙
-  ua_rules.Set("mongolian", R"CSS(
+  ua_rules.Set(AtomicString("mongolian"), R"CSS(
     system: numeric;
     symbols: "\1810" "\1811" "\1812" "\1813" "\1814" "\1815" "\1816" "\1817" "\1818" "\1819";
   )CSS");
 
   // ၀ ၁ ၂ ၃ ၄ ၅ ၆ ၇ ၈ ၉
-  ua_rules.Set("myanmar", R"CSS(
+  ua_rules.Set(AtomicString("myanmar"), R"CSS(
     system: numeric;
     symbols: "\1040" "\1041" "\1042" "\1043" "\1044" "\1045" "\1046" "\1047" "\1048" "\1049";
   )CSS");
 
   // ୦ ୧ ୨ ୩ ୪ ୫ ୬ ୭ ୮ ୯
-  ua_rules.Set("oriya", R"CSS(
+  ua_rules.Set(AtomicString("oriya"), R"CSS(
     system: numeric;
     symbols: "\B66" "\B67" "\B68" "\B69" "\B6A" "\B6B" "\B6C" "\B6D" "\B6E" "\B6F";
   )CSS");
 
   // ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹
-  ua_rules.Set("persian", R"CSS(
+  ua_rules.Set(AtomicString("persian"), R"CSS(
     system: numeric;
     symbols: "\6F0" "\6F1" "\6F2" "\6F3" "\6F4" "\6F5" "\6F6" "\6F7" "\6F8" "\6F9";
   )CSS");
 
-  ua_rules.Set("lower-roman", R"CSS(
+  ua_rules.Set(keywords::kLowerRoman, R"CSS(
     system: additive;
     range: 1 3999;
     additive-symbols: 1000 m, 900 cm, 500 d, 400 cd, 100 c, 90 xc, 50 l, 40 xl, 10 x, 9 ix, 5 v, 4 iv, 1 i;
   )CSS");
 
-  ua_rules.Set("upper-roman", R"CSS(
+  ua_rules.Set(keywords::kUpperRoman, R"CSS(
     system: additive;
     range: 1 3999;
     additive-symbols: 1000 M, 900 CM, 500 D, 400 CD, 100 C, 90 XC, 50 L, 40 XL, 10 X, 9 IX, 5 V, 4 IV, 1 I;
   )CSS");
 
   // ௦ ௧ ௨ ௩ ௪ ௫ ௬ ௭ ௮ ௯
-  ua_rules.Set("tamil", R"CSS(
+  ua_rules.Set(AtomicString("tamil"), R"CSS(
     system: numeric;
     symbols: "\BE6" "\BE7" "\BE8" "\BE9" "\BEA" "\BEB" "\BEC" "\BED" "\BEE" "\BEF";
   )CSS");
 
   // ౦ ౧ ౨ ౩ ౪ ౫ ౬ ౭ ౮ ౯
-  ua_rules.Set("telugu", R"CSS(
+  ua_rules.Set(AtomicString("telugu"), R"CSS(
     system: numeric;
     symbols: "\C66" "\C67" "\C68" "\C69" "\C6A" "\C6B" "\C6C" "\C6D" "\C6E" "\C6F";
   )CSS");
 
   // ๐ ๑ ๒ ๓ ๔ ๕ ๖ ๗ ๘ ๙
-  ua_rules.Set("thai", R"CSS(
+  ua_rules.Set(AtomicString("thai"), R"CSS(
     system: numeric;
     symbols: "\E50" "\E51" "\E52" "\E53" "\E54" "\E55" "\E56" "\E57" "\E58" "\E59";
   )CSS");
 
   // ༠ ༡ ༢ ༣ ༤ ༥ ༦ ༧ ༨ ༩
-  ua_rules.Set("tibetan", R"CSS(
+  ua_rules.Set(AtomicString("tibetan"), R"CSS(
     system: numeric;
     symbols: "\F20" "\F21" "\F22" "\F23" "\F24" "\F25" "\F26" "\F27" "\F28" "\F29";
   )CSS");
 
   // https://drafts.csswg.org/css-counter-styles-3/#simple-alphabetic
 
-  ua_rules.Set("lower-alpha", R"CSS(
+  ua_rules.Set(keywords::kLowerAlpha, R"CSS(
     system: alphabetic;
     symbols: a b c d e f g h i j k l m n o p q r s t u v w x y z;
   )CSS");
 
-  ua_rules.Set("lower-latin", R"CSS(
+  ua_rules.Set(AtomicString("lower-latin"), R"CSS(
     system: extends lower-alpha;
   )CSS");
 
-  ua_rules.Set("upper-alpha", R"CSS(
+  ua_rules.Set(keywords::kUpperAlpha, R"CSS(
     system: alphabetic;
     symbols: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z;
   )CSS");
 
-  ua_rules.Set("upper-latin", R"CSS(
+  ua_rules.Set(AtomicString("upper-latin"), R"CSS(
     system: extends upper-alpha;
   )CSS");
 
   // α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω
-  ua_rules.Set("lower-greek", R"CSS(
+  ua_rules.Set(AtomicString("lower-greek"), R"CSS(
     system: alphabetic;
     symbols: "\3B1" "\3B2" "\3B3" "\3B4" "\3B5" "\3B6" "\3B7" "\3B8" "\3B9" "\3BA" "\3BB" "\3BC" "\3BD" "\3BE" "\3BF" "\3C0" "\3C1" "\3C3" "\3C4" "\3C5" "\3C6" "\3C7" "\3C8" "\3C9";
   )CSS");
 
   // あ い う え お か き く け こ さ し す せ そ た ち つ て と な に ぬ
   // ね の は ひ ふ へ ほ ま み む め も や ゆ よ ら り る れ ろ わ ゐ ゑ を ん
-  ua_rules.Set("hiragana", R"CSS(
+  ua_rules.Set(AtomicString("hiragana"), R"CSS(
     system: alphabetic;
     symbols: "\3042" "\3044" "\3046" "\3048" "\304A" "\304B" "\304D" "\304F" "\3051" "\3053" "\3055" "\3057" "\3059" "\305B" "\305D" "\305F" "\3061" "\3064" "\3066" "\3068" "\306A" "\306B" "\306C" "\306D" "\306E" "\306F" "\3072" "\3075" "\3078" "\307B" "\307E" "\307F" "\3080" "\3081" "\3082" "\3084" "\3086" "\3088" "\3089" "\308A" "\308B" "\308C" "\308D" "\308F" "\3090" "\3091" "\3092" "\3093";
     suffix: "\3001";
@@ -239,7 +239,7 @@
 
   // い ろ は に ほ へ と ち り ぬ る を わ か よ た れ そ つ ね な ら む
   // う ゐ の お く や ま け ふ こ え て あ さ き ゆ め み し ゑ ひ も せ す
-  ua_rules.Set("hiragana-iroha", R"CSS(
+  ua_rules.Set(AtomicString("hiragana-iroha"), R"CSS(
     system: alphabetic;
     symbols: "\3044" "\308D" "\306F" "\306B" "\307B" "\3078" "\3068" "\3061" "\308A" "\306C" "\308B" "\3092" "\308F" "\304B" "\3088" "\305F" "\308C" "\305D" "\3064" "\306D" "\306A" "\3089" "\3080" "\3046" "\3090" "\306E" "\304A" "\304F" "\3084" "\307E" "\3051" "\3075" "\3053" "\3048" "\3066" "\3042" "\3055" "\304D" "\3086" "\3081" "\307F" "\3057" "\3091" "\3072" "\3082" "\305B" "\3059";
     suffix: "\3001";
@@ -247,7 +247,7 @@
 
   // ア イ ウ エ オ カ キ ク ケ コ サ シ ス セ ソ タ チ ツ テ ト ナ ニ ヌ
   // ネ ノ ハ ヒ フ ヘ ホ マ ミ ム メ モ ヤ ユ ヨ ラ リ ル レ ロ ワ ヰ ヱ ヲ ン
-  ua_rules.Set("katakana", R"CSS(
+  ua_rules.Set(AtomicString("katakana"), R"CSS(
     system: alphabetic;
     symbols: "\30A2" "\30A4" "\30A6" "\30A8" "\30AA" "\30AB" "\30AD" "\30AF" "\30B1" "\30B3" "\30B5" "\30B7" "\30B9" "\30BB" "\30BD" "\30BF" "\30C1" "\30C4" "\30C6" "\30C8" "\30CA" "\30CB" "\30CC" "\30CD" "\30CE" "\30CF" "\30D2" "\30D5" "\30D8" "\30DB" "\30DE" "\30DF" "\30E0" "\30E1" "\30E2" "\30E4" "\30E6" "\30E8" "\30E9" "\30EA" "\30EB" "\30EC" "\30ED" "\30EF" "\30F0" "\30F1" "\30F2" "\30F3";
     suffix: "\3001";
@@ -255,7 +255,7 @@
 
   // イ ロ ハ ニ ホ ヘ ト チ リ ヌ ル ヲ ワ カ ヨ タ レ ソ ツ ネ ナ ラ ム
   // ウ ヰ ノ オ ク ヤ マ ケ フ コ エ テ ア サ キ ユ メ ミ シ ヱ ヒ モ セ ス */
-  ua_rules.Set("katakana-iroha", R"CSS(
+  ua_rules.Set(AtomicString("katakana-iroha"), R"CSS(
     system: alphabetic;
     symbols: "\30A4" "\30ED" "\30CF" "\30CB" "\30DB" "\30D8" "\30C8" "\30C1" "\30EA" "\30CC" "\30EB" "\30F2" "\30EF" "\30AB" "\30E8" "\30BF" "\30EC" "\30BD" "\30C4" "\30CD" "\30CA" "\30E9" "\30E0" "\30A6" "\30F0" "\30CE" "\30AA" "\30AF" "\30E4" "\30DE" "\30B1" "\30D5" "\30B3" "\30A8" "\30C6" "\30A2" "\30B5" "\30AD" "\30E6" "\30E1" "\30DF" "\30B7" "\30F1" "\30D2" "\30E2" "\30BB" "\30B9";
     suffix: "\3001";
@@ -299,14 +299,14 @@
   // https://drafts.csswg.org/css-counter-styles-3/#simple-fixed
 
   // 子 丑 寅 卯 辰 巳 午 未 申 酉 戌 亥
-  ua_rules.Set("cjk-earthly-branch", R"CSS(
+  ua_rules.Set(AtomicString("cjk-earthly-branch"), R"CSS(
     system: alphabetic;
     symbols: "\5B50" "\4E11" "\5BC5" "\536F" "\8FB0" "\5DF3" "\5348" "\672A" "\7533" "\9149" "\620C" "\4EA5";
     suffix: "\3001";
   )CSS");
 
   // 甲 乙 丙 丁 戊 己 庚 辛 壬 癸
-  ua_rules.Set("cjk-heavenly-stem", R"CSS(
+  ua_rules.Set(AtomicString("cjk-heavenly-stem"), R"CSS(
     system: alphabetic;
     symbols: "\7532" "\4E59" "\4E19" "\4E01" "\620A" "\5DF1" "\5E9A" "\8F9B" "\58EC" "\7678";
     suffix: "\3001";
@@ -319,7 +319,7 @@
   // 400 四百, 300 三百, 200 二百, 100 百, 90 九十, 80 八十, 70 七十, 60 六十,
   // 50 五十, 40 四十, 30 三十, 20 二十, 10 十, 9 九, 8 八, 7 七, 6 六, 5 五, 4
   // 四, 3 三, 2 二, 1 一, 0 〇
-  ua_rules.Set("japanese-informal", R"CSS(
+  ua_rules.Set(AtomicString("japanese-informal"), R"CSS(
     system: additive;
     range: -9999 9999;
     additive-symbols: 9000 \4E5D\5343, 8000 \516B\5343, 7000 \4E03\5343, 6000 \516D\5343, 5000 \4E94\5343, 4000 \56DB\5343, 3000 \4E09\5343, 2000 \4E8C\5343, 1000 \5343, 900 \4E5D\767E, 800 \516B\767E, 700 \4E03\767E, 600 \516D\767E, 500 \4E94\767E, 400 \56DB\767E, 300 \4E09\767E, 200 \4E8C\767E, 100 \767E, 90 \4E5D\5341, 80 \516B\5341, 70 \4E03\5341, 60 \516D\5341, 50 \4E94\5341, 40 \56DB\5341, 30 \4E09\5341, 20 \4E8C\5341, 10 \5341, 9 \4E5D, 8 \516B, 7 \4E03, 6 \516D, 5 \4E94, 4 \56DB, 3 \4E09, 2 \4E8C, 1 \4E00, 0 \3007;
@@ -333,7 +333,7 @@
   // 伍百, 400 四百, 300 参百, 200 弐百, 100 壱百, 90 九拾, 80 八拾, 70 七拾, 60
   // 六拾, 50 伍拾, 40 四拾, 30 参拾, 20 弐拾, 10 壱拾, 9 九, 8 八, 7 七, 6 六,
   // 5 伍, 4 四, 3 参, 2 弐, 1 壱, 0 零
-  ua_rules.Set("japanese-formal", R"CSS(
+  ua_rules.Set(AtomicString("japanese-formal"), R"CSS(
     system: additive;
     range: -9999 9999;
     additive-symbols: 9000 \4E5D\9621, 8000 \516B\9621, 7000 \4E03\9621, 6000 \516D\9621, 5000 \4F0D\9621, 4000 \56DB\9621, 3000 \53C2\9621, 2000 \5F10\9621, 1000 \58F1\9621, 900 \4E5D\767E, 800 \516B\767E, 700 \4E03\767E, 600 \516D\767E, 500 \4F0D\767E, 400 \56DB\767E, 300 \53C2\767E, 200 \5F10\767E, 100 \58F1\767E, 90 \4E5D\62FE, 80 \516B\62FE, 70 \4E03\62FE, 60 \516D\62FE, 50 \4F0D\62FE, 40 \56DB\62FE, 30 \53C2\62FE, 20 \5F10\62FE, 10 \58F1\62FE, 9 \4E5D, 8 \516B, 7 \4E03, 6 \516D, 5 \4F0D, 4 \56DB, 3 \53C2, 2 \5F10, 1 \58F1, 0 \96F6;
@@ -349,7 +349,7 @@
   // investigative purposes. Therefore, we support the full int range.
 
   // negative: 마이너스 (followed by a space)
-  ua_rules.Set("korean-hangul-formal", R"CSS(
+  ua_rules.Set(AtomicString("korean-hangul-formal"), R"CSS(
     system: -internal-korean-hangul-formal;
     suffix: ', ';
     negative: "\B9C8\C774\B108\C2A4  ";
@@ -357,7 +357,7 @@
   )CSS");
 
   // negative: 마이너스 (followed by a space)
-  ua_rules.Set("korean-hanja-informal", R"CSS(
+  ua_rules.Set(AtomicString("korean-hanja-informal"), R"CSS(
     system: -internal-korean-hanja-informal;
     suffix: ', ';
     negative: "\B9C8\C774\B108\C2A4  ";
@@ -365,7 +365,7 @@
   )CSS");
 
   // negative: 마이너스 (followed by a space)
-  ua_rules.Set("korean-hanja-formal", R"CSS(
+  ua_rules.Set(AtomicString("korean-hanja-formal"), R"CSS(
     system: -internal-korean-hanja-formal;
     suffix: ', ';
     negative: "\B9C8\C774\B108\C2A4  ";
@@ -379,7 +379,7 @@
   // investigative purposes. Therefore, we support the full int range.
 
   // negative: 负
-  ua_rules.Set("simp-chinese-informal", R"CSS(
+  ua_rules.Set(AtomicString("simp-chinese-informal"), R"CSS(
     system: -internal-simp-chinese-informal;
     suffix: \3001;
     negative: \8D1F;
@@ -387,7 +387,7 @@
   )CSS");
 
   // negative: 负
-  ua_rules.Set("simp-chinese-formal", R"CSS(
+  ua_rules.Set(AtomicString("simp-chinese-formal"), R"CSS(
     system: -internal-simp-chinese-formal;
     suffix: \3001;
     negative: \8D1F;
@@ -395,7 +395,7 @@
   )CSS");
 
   // negative: 負
-  ua_rules.Set("trad-chinese-informal", R"CSS(
+  ua_rules.Set(AtomicString("trad-chinese-informal"), R"CSS(
     system: -internal-trad-chinese-informal;
     suffix: \3001;
     negative: \8CA0;
@@ -403,20 +403,20 @@
   )CSS");
 
   // negative: 負
-  ua_rules.Set("trad-chinese-formal", R"CSS(
+  ua_rules.Set(AtomicString("trad-chinese-formal"), R"CSS(
     system: -internal-trad-chinese-formal;
     suffix: \3001;
     negative: \8CA0;
     fallback: cjk-decimal;
   )CSS");
 
-  ua_rules.Set("cjk-ideographic", R"CSS(
+  ua_rules.Set(AtomicString("cjk-ideographic"), R"CSS(
     system: extends trad-chinese-informal;
   )CSS");
 
   // https://drafts.csswg.org/css-counter-styles-3/#ethiopic-numeric-counter-style
 
-  ua_rules.Set("ethiopic-numeric", R"CSS(
+  ua_rules.Set(AtomicString("ethiopic-numeric"), R"CSS(
     system: -internal-ethiopic-numeric;
     range: 1 infinite;
     suffix: "/ ";
@@ -424,41 +424,41 @@
 
   // Non-standard counter styles that we've been supporting
 
-  ua_rules.Set("ethiopic-halehame", R"CSS(
+  ua_rules.Set(AtomicString("ethiopic-halehame"), R"CSS(
     system: alphabetic;
     symbols: '\1200' '\1208' '\1210' '\1218' '\1220' '\1228' '\1230' '\1240' '\1260' '\1270' '\1280' '\1290' '\12A0' '\12A8' '\12C8' '\12D0' '\12D8' '\12E8' '\12F0' '\1308' '\1320' '\1330' '\1338' '\1340' '\1348' '\1350';
     suffix: '\1366 ';
   )CSS");
 
-  ua_rules.Set("ethiopic-halehame-am", R"CSS(
+  ua_rules.Set(AtomicString("ethiopic-halehame-am"), R"CSS(
     system: alphabetic;
     symbols: '\1200' '\1208' '\1210' '\1218' '\1220' '\1228' '\1230' '\1238' '\1240' '\1260' '\1270' '\1278' '\1280' '\1290' '\1298' '\12A0' '\12A8' '\12B8' '\12C8' '\12D0' '\12D8' '\12E0' '\12E8' '\12F0' '\1300' '\1308' '\1320' '\1328' '\1330' '\1338' '\1340' '\1348' '\1350';
     suffix: '\1366 ';
   )CSS");
 
-  ua_rules.Set("ethiopic-halehame-ti-er", R"CSS(
+  ua_rules.Set(AtomicString("ethiopic-halehame-ti-er"), R"CSS(
     system: alphabetic;
     symbols: '\1200' '\1208' '\1210' '\1218' '\1228' '\1230' '\1238' '\1240' '\1250' '\1260' '\1270' '\1278' '\1290' '\1298' '\12A0' '\12A8' '\12B8' '\12C8' '\12D0' '\12D8' '\12E0' '\12E8' '\12F0' '\1300' '\1308' '\1320' '\1328' '\1330' '\1338' '\1348' '\1350';
     suffix: '\1366 ';
   )CSS");
 
-  ua_rules.Set("ethiopic-halehame-ti-et", R"CSS(
+  ua_rules.Set(AtomicString("ethiopic-halehame-ti-et"), R"CSS(
     system: alphabetic;
     symbols: '\1200' '\1208' '\1210' '\1218' '\1220' '\1228' '\1230' '\1238' '\1240' '\1250' '\1260' '\1270' '\1278' '\1280' '\1290' '\1298' '\12A0' '\12A8' '\12B8' '\12C8' '\12D0' '\12D8' '\12E0' '\12E8' '\12F0' '\1300' '\1308' '\1320' '\1328' '\1330' '\1338' '\1340' '\1348' '\1350';
     suffix: '\1366 ';
   )CSS");
 
-  ua_rules.Set("hangul", R"CSS(
+  ua_rules.Set(AtomicString("hangul"), R"CSS(
     system: alphabetic;
     symbols: '\AC00' '\B098' '\B2E4' '\B77C' '\B9C8' '\BC14' '\C0AC' '\C544' '\C790' '\CC28' '\CE74' '\D0C0' '\D30C' '\D558';
   )CSS");
 
-  ua_rules.Set("hangul-consonant", R"CSS(
+  ua_rules.Set(AtomicString("hangul-consonant"), R"CSS(
     system: alphabetic;
     symbols: '\3131' '\3134' '\3137' '\3139' '\3141' '\3142' '\3145' '\3147' '\3148' '\314A' '\314B' '\314C' '\314D' '\314E';
   )CSS");
 
-  ua_rules.Set("urdu", R"CSS(
+  ua_rules.Set(AtomicString("urdu"), R"CSS(
     system: extends persian;
   )CSS");
 
diff --git a/third_party/blink/renderer/core/css/vision_deficiency.cc b/third_party/blink/renderer/core/css/vision_deficiency.cc
index f2d1bdf8..fffe4883 100644
--- a/third_party/blink/renderer/core/css/vision_deficiency.cc
+++ b/third_party/blink/renderer/core/css/vision_deficiency.cc
@@ -82,7 +82,7 @@
           "\"/>");
     case VisionDeficiency::kNoVisionDeficiency:
       NOTREACHED();
-      return "";
+      return g_empty_atom;
   }
 }
 
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 7809c80..293b01d5 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -201,6 +201,7 @@
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
+#include "third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_font_cache.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
 #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
@@ -342,6 +343,7 @@
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
 #include "third_party/blink/renderer/platform/language.h"
 #include "third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
 #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
 #include "third_party/blink/renderer/platform/network/http_parsers.h"
@@ -3783,6 +3785,14 @@
   if (lazy_load_image_observer_) {
     lazy_load_image_observer_->DocumentOnLoadFinished(this);
   }
+
+  if (base::FeatureList::IsEnabled(
+          blink::features::kSpeculativeServiceWorkerWarmUp)) {
+    if (auto* observer =
+            AnchorElementObserverForServiceWorker::From(TopDocument())) {
+      observer->MaybeSendPendingWarmUpRequests();
+    }
+  }
 }
 
 static bool AllDescendantsAreComplete(Document* document) {
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 788f961..c66f6b9 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -80,7 +80,6 @@
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
 #include "third_party/blink/renderer/platform/heap_observer_set.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
 #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/supplementable.h"
 #include "third_party/blink/renderer/platform/timer.h"
@@ -214,6 +213,7 @@
 class Range;
 class RenderBlockingResourceManager;
 class ResizeObserver;
+class Resource;
 class ResourceFetcher;
 class RootScrollerController;
 class SVGDocumentExtensions;
diff --git a/third_party/blink/renderer/core/fileapi/blob.cc b/third_party/blink/renderer/core/fileapi/blob.cc
index a84587a1..9f1a565 100644
--- a/third_party/blink/renderer/core/fileapi/blob.cc
+++ b/third_party/blink/renderer/core/fileapi/blob.cc
@@ -271,7 +271,7 @@
 }
 
 void Blob::AppendTo(BlobData& blob_data) const {
-  blob_data.AppendBlob(blob_data_handle_, 0, blob_data_handle_->size());
+  blob_data.AppendBlob(blob_data_handle_, 0, size());
 }
 
 URLRegistry& Blob::Registry() const {
@@ -287,7 +287,7 @@
   blob_data_handle_->CloneBlobRemote(std::move(receiver));
 }
 
-mojo::PendingRemote<mojom::blink::Blob> Blob::AsMojoBlob() {
+mojo::PendingRemote<mojom::blink::Blob> Blob::AsMojoBlob() const {
   return blob_data_handle_->CloneBlobRemote();
 }
 
diff --git a/third_party/blink/renderer/core/fileapi/blob.h b/third_party/blink/renderer/core/fileapi/blob.h
index cf392ac8..fecb6d4 100644
--- a/third_party/blink/renderer/core/fileapi/blob.h
+++ b/third_party/blink/renderer/core/fileapi/blob.h
@@ -73,10 +73,10 @@
   ~Blob() override;
 
   virtual uint64_t size() const { return blob_data_handle_->size(); }
-  virtual Blob* slice(int64_t start,
-                      int64_t end,
-                      const String& content_type,
-                      ExceptionState&) const;
+  Blob* slice(int64_t start,
+              int64_t end,
+              const String& content_type,
+              ExceptionState&) const;
 
   // To allow ExceptionState to be passed in last, manually enumerate the
   // optional argument overloads.
@@ -108,13 +108,13 @@
   virtual bool HasBackingFile() const { return false; }
 
   // Used by the JavaScript Blob and File constructors.
-  virtual void AppendTo(BlobData&) const;
+  void AppendTo(BlobData&) const;
 
   // URLRegistrable to support PublicURLs.
   URLRegistry& Registry() const final;
   bool IsMojoBlob() final;
   void CloneMojoBlob(mojo::PendingReceiver<mojom::blink::Blob>) final;
-  mojo::PendingRemote<mojom::blink::Blob> AsMojoBlob();
+  mojo::PendingRemote<mojom::blink::Blob> AsMojoBlob() const;
 
   // ImageBitmapSource implementation
   bool IsBlob() const override { return true; }
diff --git a/third_party/blink/renderer/core/fileapi/file.cc b/third_party/blink/renderer/core/fileapi/file.cc
index d2a5e39..80d8386 100644
--- a/third_party/blink/renderer/core/fileapi/file.cc
+++ b/third_party/blink/renderer/core/fileapi/file.cc
@@ -344,28 +344,6 @@
   return 0;
 }
 
-Blob* File::slice(int64_t start,
-                  int64_t end,
-                  const String& content_type,
-                  ExceptionState& exception_state) const {
-  if (!has_backing_file_)
-    return Blob::slice(start, end, content_type, exception_state);
-
-  // FIXME: Calling size triggers capturing a snapshot, if we don't have one
-  // already. This involves synchronous file operation. We need to figure out
-  // how to make it asynchronous (or make sure snapshot state is always passed
-  // in when creating a File instance).
-  ClampSliceOffsets(size(), start, end);
-
-  uint64_t length = end - start;
-  auto blob_data = std::make_unique<BlobData>();
-  blob_data->SetContentType(NormalizeType(content_type));
-  DCHECK(!path_.empty());
-  blob_data->AppendFile(path_, start, length, snapshot_modification_time_);
-  return MakeGarbageCollected<Blob>(
-      BlobDataHandle::Create(std::move(blob_data), length));
-}
-
 void File::CaptureSnapshotIfNeeded() const {
   if (HasValidSnapshotMetadata() && snapshot_modification_time_)
     return;
@@ -377,19 +355,6 @@
   }
 }
 
-void File::AppendTo(BlobData& blob_data) const {
-  if (!has_backing_file_) {
-    Blob::AppendTo(blob_data);
-    return;
-  }
-
-  // FIXME: This involves synchronous file operation. We need to figure out how
-  // to make it asynchronous.
-  CaptureSnapshotIfNeeded();
-  DCHECK(!path_.empty());
-  blob_data.AppendFile(path_, 0, *snapshot_size_, snapshot_modification_time_);
-}
-
 bool File::HasSameSource(const File& other) const {
   if (has_backing_file_ != other.has_backing_file_)
     return false;
diff --git a/third_party/blink/renderer/core/fileapi/file.h b/third_party/blink/renderer/core/fileapi/file.h
index 6ad3b11..2cc436a 100644
--- a/third_party/blink/renderer/core/fileapi/file.h
+++ b/third_party/blink/renderer/core/fileapi/file.h
@@ -38,7 +38,6 @@
 
 namespace blink {
 
-class ExceptionState;
 class FilePropertyBag;
 class FileMetadata;
 class FormControlState;
@@ -192,17 +191,13 @@
 
   File* Clone(const String& name = String()) const;
 
+  // This method calls CaptureSnapshotIfNeeded, and thus can involve synchronous
+  // IPC and file operations.
   uint64_t size() const override;
-  Blob* slice(int64_t start,
-              int64_t end,
-              const String& content_type,
-              ExceptionState&) const override;
 
   bool IsFile() const override { return true; }
   bool HasBackingFile() const override { return has_backing_file_; }
 
-  void AppendTo(BlobData&) const override;
-
   const String& GetPath() const {
 #if DCHECK_IS_ON()
     DCHECK(HasValidFilePath());
@@ -213,14 +208,20 @@
 
   // Getter for the lastModified IDL attribute,
   // http://dev.w3.org/2006/webapi/FileAPI/#file-attrs
+  // This method calls CaptureSnapshotIfNeeded, and thus can involve synchronous
+  // IPC and file operations.
   int64_t lastModified() const;
 
   // Getter for the lastModifiedDate IDL attribute,
   // http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate
+  // This method calls CaptureSnapshotIfNeeded, and thus can involve synchronous
+  // IPC and file operations.
   ScriptValue lastModifiedDate(ScriptState* script_state) const;
 
   // Returns File's last modified time.
   // If the modification time isn't known, the current time is returned.
+  // This method calls CaptureSnapshotIfNeeded, and thus can involve synchronous
+  // IPC and file operations.
   base::Time LastModifiedTime() const;
 
   // Similar to |LastModifiedTime()|, except this returns absl::nullopt rather
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index c01a9165..0648530 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1944,13 +1944,12 @@
   return false;
 }
 
-void LocalFrame::WillPotentiallyStartOutermostMainFrameNavigation(
-    const KURL& url) const {
-  TRACE_EVENT1("navigation",
-               "LocalFrame::WillPotentiallyStartOutermostMainFrameNavigation",
-               "url", url);
+void LocalFrame::MaybeStartOutermostMainFrameNavigation(
+    const Vector<KURL>& urls) const {
+  TRACE_EVENT0("navigation",
+               "LocalFrame::MaybeStartOutermostMainFrameNavigation");
   mojo_handler_->NonAssociatedLocalFrameHostRemote()
-      .WillPotentiallyStartOutermostMainFrameNavigation(url);
+      .MaybeStartOutermostMainFrameNavigation(urls);
 }
 
 ContentCaptureManager* LocalFrame::GetOrResetContentCaptureManager() {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index 50e103a..4e00ed3b 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -459,7 +459,7 @@
   // navigation at a later time.
   bool CanNavigate(const Frame&, const KURL& destination_url = KURL());
 
-  void WillPotentiallyStartOutermostMainFrameNavigation(const KURL& url) const;
+  void MaybeStartOutermostMainFrameNavigation(const Vector<KURL>& urls) const;
 
   // Whether a navigation should replace the current history entry or not.
   // Note this isn't exhaustive; there are other cases where a navigation does a
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 1760444..63cb39adf 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2816,9 +2816,11 @@
                           std::move(blob_url_token));
 }
 
-void WebLocalFrameImpl::WillPotentiallyStartOutermostMainFrameNavigation(
-    const WebURL& url) const {
-  GetFrame()->WillPotentiallyStartOutermostMainFrameNavigation(url);
+void WebLocalFrameImpl::MaybeStartOutermostMainFrameNavigation(
+    const WebVector<WebURL>& urls) const {
+  Vector<KURL> kurls;
+  std::move(urls.begin(), urls.end(), std::back_inserter(kurls));
+  GetFrame()->MaybeStartOutermostMainFrameNavigation(std::move(kurls));
 }
 
 bool WebLocalFrameImpl::WillStartNavigation(const WebNavigationInfo& info) {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index 8ce3bef..56f09dfb 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -387,8 +387,8 @@
           soft_navigation_heuristics_task_id) override;
   void SetIsNotOnInitialEmptyDocument() override;
   bool IsOnInitialEmptyDocument() override;
-  void WillPotentiallyStartOutermostMainFrameNavigation(
-      const WebURL&) const override;
+  void MaybeStartOutermostMainFrameNavigation(
+      const WebVector<WebURL>& urls) const override;
   bool WillStartNavigation(const WebNavigationInfo&) override;
   void DidDropNavigation() override;
   void DownloadURL(
diff --git a/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.cc b/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.cc
new file mode 100644
index 0000000..f53ca38
--- /dev/null
+++ b/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.cc
@@ -0,0 +1,203 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.h"
+
+#include "base/time/time.h"
+#include "base/trace_event/base_tracing.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/events/pointer_event.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/html/html_anchor_element.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+
+namespace blink {
+
+// static
+const char AnchorElementObserverForServiceWorker::kSupplementName[] =
+    "AnchorElementObserverForServiceWorker";
+
+// static
+AnchorElementObserverForServiceWorker*
+AnchorElementObserverForServiceWorker::From(Document& document) {
+  TRACE_EVENT0("ServiceWorker", "AnchorElementObserverForServiceWorker::From");
+  const KURL& url = document.Url();
+  if (!document.IsInOutermostMainFrame() || !url.IsValid() ||
+      !url.ProtocolIsInHTTPFamily()) {
+    return nullptr;
+  }
+
+  AnchorElementObserverForServiceWorker* observer =
+      Supplement<Document>::From<AnchorElementObserverForServiceWorker>(
+          document);
+
+  if (!observer) {
+    observer = MakeGarbageCollected<AnchorElementObserverForServiceWorker>(
+        base::PassKey<AnchorElementObserverForServiceWorker>(), document);
+    ProvideTo(document, observer);
+  }
+
+  return observer;
+}
+
+AnchorElementObserverForServiceWorker::AnchorElementObserverForServiceWorker(
+    base::PassKey<AnchorElementObserverForServiceWorker>,
+    Document& document)
+    : Supplement<Document>(document),
+      warm_up_request_cache_(
+          blink::features::kSpeculativeServiceWorkerWarmUpRequestCacheSize
+              .Get()),
+      batch_timer_(
+          document.GetTaskRunner(TaskType::kInternalDefault),
+          this,
+          &AnchorElementObserverForServiceWorker::SendPendingWarmUpRequests) {
+  CHECK(document.IsInOutermostMainFrame());
+  if (blink::features::kSpeculativeServiceWorkerWarmUpIntersectionObserver
+          .Get()) {
+    intersection_observer_ = IntersectionObserver::Create(
+        {}, {std::numeric_limits<float>::min()}, &document,
+        WTF::BindRepeating(
+            &AnchorElementObserverForServiceWorker::UpdateVisibleAnchors,
+            WrapWeakPersistent(this)),
+        LocalFrameUkmAggregator::kAnchorElementMetricsIntersectionObserver,
+        IntersectionObserver::kPostTaskToDeliver,
+        IntersectionObserver::kFractionOfTarget,
+        /*delay=*/
+        blink::features::
+            kSpeculativeServiceWorkerWarmUpIntersectionObserverDelay.Get());
+  }
+}
+
+void AnchorElementObserverForServiceWorker::ObserveAnchorElementVisibility(
+    HTMLAnchorElement& element) {
+  if (blink::features::kSpeculativeServiceWorkerWarmUpIntersectionObserver
+          .Get()) {
+    TRACE_EVENT0("ServiceWorker",
+                 "AnchorElementObserverForServiceWorker::"
+                 "ObserveAnchorElementVisibility");
+    intersection_observer_->observe(&element);
+  }
+}
+
+void AnchorElementObserverForServiceWorker::UpdateVisibleAnchors(
+    const HeapVector<Member<IntersectionObserverEntry>>& entries) {
+  if (!blink::features::kSpeculativeServiceWorkerWarmUpOnVisible.Get()) {
+    return;
+  }
+
+  TRACE_EVENT0("ServiceWorker",
+               "AnchorElementObserverForServiceWorker::UpdateVisibleAnchors");
+
+  Vector<KURL> urls;
+  for (const auto& entry : entries) {
+    if (!entry->isIntersecting()) {
+      continue;
+    }
+
+    Element* element = entry->target();
+    if (!element) {
+      continue;
+    }
+
+    // Once an element is evaluated, we stop observing the element to reduce the
+    // computational load caused by IntersectionObserver.
+    intersection_observer_->unobserve(element);
+
+    CHECK(IsA<HTMLAnchorElement>(*element));
+    HTMLAnchorElement& anchor = To<HTMLAnchorElement>(*element);
+    if (anchor.IsLink()) {
+      urls.push_back(anchor.Url());
+    }
+  }
+
+  MaybeSendNavigationTargetUrls(urls);
+}
+
+void AnchorElementObserverForServiceWorker::MaybeSendNavigationTargetUrls(
+    const Vector<KURL>& candidate_urls) {
+  if (candidate_urls.empty()) {
+    return;
+  }
+
+  TRACE_EVENT0("ServiceWorker",
+               "AnchorElementObserverForServiceWorker::"
+               "MaybeSendNavigationTargetUrls");
+
+  const base::TimeDelta kReWarmUpThreshold =
+      blink::features::kSpeculativeServiceWorkerWarmUpReWarmUpThreshold.Get();
+  const int kWarmUpRequestLimit =
+      blink::features::kSpeculativeServiceWorkerWarmUpRequestLimit.Get();
+
+  const KURL& document_url = GetSupplementable()->Url();
+  for (KURL url : candidate_urls) {
+    if (!url.IsValid() || !url.ProtocolIsInHTTPFamily() ||
+        EqualIgnoringFragmentIdentifier(document_url, url)) {
+      continue;
+    }
+
+    url.RemoveFragmentIdentifier();
+    url.SetUser(String());
+    url.SetPass(String());
+
+    // Prevents excessive duplicate warm-up requests.
+    base::TimeTicks now = base::TimeTicks::Now();
+    auto found = warm_up_request_cache_.Get(url.GetString());
+    if (found != warm_up_request_cache_.end() &&
+        now - found->second < kReWarmUpThreshold) {
+      continue;
+    }
+
+    if (total_request_count_ < kWarmUpRequestLimit) {
+      warm_up_request_cache_.Put(url.GetString(), now);
+      pending_warm_up_requests_.push_back(std::move(url));
+      ++total_request_count_;
+    }
+  }
+
+  MaybeSendPendingWarmUpRequests();
+}
+
+void AnchorElementObserverForServiceWorker::MaybeSendPendingWarmUpRequests() {
+  TRACE_EVENT0(
+      "ServiceWorker",
+      "AnchorElementObserverForServiceWorker::MaybeSendPendingWarmUpRequests");
+  if (!pending_warm_up_requests_.empty() &&
+      GetSupplementable()->LoadEventFinished() && !batch_timer_.IsActive()) {
+    batch_timer_.StartOneShot(
+        blink::features::kSpeculativeServiceWorkerWarmUpBatchTimer.Get(),
+        FROM_HERE);
+  }
+}
+
+void AnchorElementObserverForServiceWorker::SendPendingWarmUpRequests(
+    TimerBase*) {
+  LocalFrame* local_frame = GetSupplementable()->GetFrame();
+
+  if (!local_frame) {
+    return;
+  }
+
+  TRACE_EVENT1(
+      "ServiceWorker",
+      "AnchorElementObserverForServiceWorker::SendPendingWarmUpRequests",
+      "url_count", pending_warm_up_requests_.size());
+
+  Vector<KURL> urls;
+  pending_warm_up_requests_.swap(urls);
+  local_frame->MaybeStartOutermostMainFrameNavigation(std::move(urls));
+}
+
+void AnchorElementObserverForServiceWorker::Trace(Visitor* visitor) const {
+  Supplement<Document>::Trace(visitor);
+  visitor->Trace(intersection_observer_);
+  visitor->Trace(batch_timer_);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.h b/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.h
new file mode 100644
index 0000000..b7f96d8
--- /dev/null
+++ b/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.h
@@ -0,0 +1,78 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_OBSERVER_FOR_SERVICE_WORKER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_OBSERVER_FOR_SERVICE_WORKER_H_
+
+#include "base/containers/lru_cache.h"
+#include "base/time/time.h"
+#include "base/types/pass_key.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+#include "third_party/blink/renderer/platform/timer.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl_hash.h"
+
+namespace blink {
+
+class Document;
+class HTMLAnchorElement;
+class IntersectionObserver;
+class IntersectionObserverEntry;
+
+class CORE_EXPORT AnchorElementObserverForServiceWorker
+    : public GarbageCollected<AnchorElementObserverForServiceWorker>,
+      public Supplement<Document> {
+ public:
+  static const char kSupplementName[];
+  static AnchorElementObserverForServiceWorker* From(Document&);
+  explicit AnchorElementObserverForServiceWorker(
+      base::PassKey<AnchorElementObserverForServiceWorker>,
+      Document& document);
+  AnchorElementObserverForServiceWorker(
+      AnchorElementObserverForServiceWorker&&) = delete;
+  AnchorElementObserverForServiceWorker& operator=(
+      AnchorElementObserverForServiceWorker&&) = delete;
+  AnchorElementObserverForServiceWorker(
+      const AnchorElementObserverForServiceWorker&) = delete;
+  AnchorElementObserverForServiceWorker& operator=(
+      const AnchorElementObserverForServiceWorker&) = delete;
+  virtual ~AnchorElementObserverForServiceWorker() = default;
+
+  void MaybeSendNavigationTargetUrls(const Vector<KURL>& candidate_urls);
+  void MaybeSendPendingWarmUpRequests();
+  void ObserveAnchorElementVisibility(HTMLAnchorElement& element);
+  void Trace(Visitor* visitor) const override;
+
+ private:
+  void UpdateVisibleAnchors(
+      const HeapVector<Member<IntersectionObserverEntry>>& entries);
+  void SendPendingWarmUpRequests(TimerBase*);
+
+  Member<IntersectionObserver> intersection_observer_;
+
+  // Remember recent warm-up requests to prevent excessive duplicate warm-up
+  // requests.
+  base::HashingLRUCache<String, base::TimeTicks> warm_up_request_cache_;
+
+  // The following Vector keeps the pending warm-up requests until the document
+  // is loaded to prioritize loading the document.
+  Vector<KURL> pending_warm_up_requests_;
+
+  // Sent URL count to browser process.
+  int total_request_count_ = 0;
+
+  // This timer is used to avoid frequent warm-up mojo calls. Before actually
+  // sending URL candidates, we wait for a while to accept more requests, and
+  // then send the accumulated URL candidates in one batch.
+  HeapTaskRunnerTimer<AnchorElementObserverForServiceWorker> batch_timer_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_OBSERVER_FOR_SERVICE_WORKER_H_
diff --git a/third_party/blink/renderer/core/html/build.gni b/third_party/blink/renderer/core/html/build.gni
index bf312108..10bb1e9e 100644
--- a/third_party/blink/renderer/core/html/build.gni
+++ b/third_party/blink/renderer/core/html/build.gni
@@ -9,6 +9,8 @@
   "anchor_element_metrics_sender.h",
   "anchor_element_observer.cc",
   "anchor_element_observer.h",
+  "anchor_element_observer_for_service_worker.cc",
+  "anchor_element_observer_for_service_worker.h",
   "blocking_attribute.cc",
   "blocking_attribute.h",
   "canvas/canvas_async_blob_creator.cc",
diff --git a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
index 5504f8e..88823f6 100644
--- a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
+++ b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
@@ -374,12 +374,13 @@
 
   if (touches->length() == 1) {
     if (event->type() == event_type_names::kTouchstart) {
-      start_point_ = touches->item(0)->AbsoluteLocation();
+      start_point_ = touches->item(0)->AbsoluteLocation().ToLayoutPoint();
       sliding_direction_ = Direction::kNoMove;
       touch_started_ = true;
-      thumb->SetPositionFromPoint(touches->item(0)->AbsoluteLocation());
+      thumb->SetPositionFromPoint(start_point_);
     } else if (touch_started_) {
-      LayoutPoint current_point = touches->item(0)->AbsoluteLocation();
+      LayoutPoint current_point =
+          touches->item(0)->AbsoluteLocation().ToLayoutPoint();
       if (sliding_direction_ == Direction::kNoMove) {
         // Still needs to update the direction.
         sliding_direction_ = GetDirection(current_point, start_point_);
@@ -388,7 +389,7 @@
       // sliding_direction_ has been updated, so check whether it's okay to
       // slide again.
       if (CanSlide()) {
-        thumb->SetPositionFromPoint(touches->item(0)->AbsoluteLocation());
+        thumb->SetPositionFromPoint(current_point);
         event->SetDefaultHandled();
       }
     }
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc
index e4432ac..157a9b0a 100644
--- a/third_party/blink/renderer/core/html/html_anchor_element.cc
+++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -35,6 +35,7 @@
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
 #include "third_party/blink/renderer/core/events/mouse_event.h"
+#include "third_party/blink/renderer/core/events/pointer_event.h"
 #include "third_party/blink/renderer/core/frame/ad_tracker.h"
 #include "third_party/blink/renderer/core/frame/attribution_src_loader.h"
 #include "third_party/blink/renderer/core/frame/deprecation/deprecation.h"
@@ -43,6 +44,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/html/anchor_element_metrics_sender.h"
+#include "third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.h"
 #include "third_party/blink/renderer/core/html/html_image_element.h"
 #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
 #include "third_party/blink/renderer/core/html_names.h"
@@ -198,6 +200,27 @@
 
 void HTMLAnchorElement::DefaultEventHandler(Event& event) {
   if (IsLink()) {
+    if (base::FeatureList::IsEnabled(
+            blink::features::kSpeculativeServiceWorkerWarmUp) &&
+        Url().IsValid()) {
+      Document& top_document = GetDocument().TopDocument();
+      if (auto* observer =
+              AnchorElementObserverForServiceWorker::From(top_document)) {
+        if (blink::features::kSpeculativeServiceWorkerWarmUpOnPointerover
+                .Get() &&
+            (event.type() == event_type_names::kMouseover ||
+             event.type() == event_type_names::kPointerover)) {
+          observer->MaybeSendNavigationTargetUrls(Vector<KURL>({Url()}));
+        } else if (blink::features::kSpeculativeServiceWorkerWarmUpOnPointerdown
+                       .Get() &&
+                   (event.type() == event_type_names::kMousedown ||
+                    event.type() == event_type_names::kPointerdown ||
+                    event.type() == event_type_names::kTouchstart)) {
+          observer->MaybeSendNavigationTargetUrls(Vector<KURL>({Url()}));
+        }
+      }
+    }
+
     if (IsFocused() && IsEnterKeyKeydownEvent(event) && IsLiveLink()) {
       event.SetDefaultHandled();
       DispatchSimulatedClick(&event);
@@ -599,6 +622,15 @@
     AnchorElementMetricsSender::From(top_document)->AddAnchorElement(*this);
   }
 
+  if (base::FeatureList::IsEnabled(
+          blink::features::kSpeculativeServiceWorkerWarmUp) &&
+      blink::features::kSpeculativeServiceWorkerWarmUpOnVisible.Get()) {
+    if (auto* observer =
+            AnchorElementObserverForServiceWorker::From(top_document)) {
+      observer->ObserveAnchorElementVisibility(*this);
+    }
+  }
+
   if (isConnected() && IsLink()) {
     if (auto* document_rules =
             DocumentSpeculationRules::FromIfExists(GetDocument())) {
diff --git a/third_party/blink/renderer/core/input/touch.cc b/third_party/blink/renderer/core/input/touch.cc
index 2c741bdf..ebc17392 100644
--- a/third_party/blink/renderer/core/input/touch.cc
+++ b/third_party/blink/renderer/core/input/touch.cc
@@ -47,14 +47,14 @@
   return offset;
 }
 
-LayoutPoint PageToAbsolute(LocalFrame* frame, const gfx::PointF& page_pos) {
+PhysicalOffset PageToAbsolute(LocalFrame* frame, const gfx::PointF& page_pos) {
   float scale_factor = frame ? frame->PageZoomFactor() : 1.0f;
   gfx::PointF converted_point = gfx::ScalePoint(page_pos, scale_factor);
 
   if (frame && frame->View())
     converted_point = frame->View()->DocumentToFrame(converted_point);
 
-  return LayoutPoint(converted_point);
+  return PhysicalOffset::FromPointFFloor(converted_point);
 }
 
 }  // namespace
@@ -85,7 +85,7 @@
              const gfx::SizeF& radius,
              float rotation_angle,
              float force,
-             LayoutPoint absolute_location)
+             PhysicalOffset absolute_location)
     : target_(target),
       identifier_(identifier),
       client_pos_(client_pos),
diff --git a/third_party/blink/renderer/core/input/touch.h b/third_party/blink/renderer/core/input/touch.h
index 68e5722..227a781d 100644
--- a/third_party/blink/renderer/core/input/touch.h
+++ b/third_party/blink/renderer/core/input/touch.h
@@ -29,8 +29,8 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/geometry/layout_point.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/size_f.h"
@@ -77,7 +77,7 @@
         const gfx::SizeF& radius,
         float rotation_angle,
         float force,
-        LayoutPoint absolute_location);
+        PhysicalOffset absolute_location);
 
   Touch(LocalFrame*, const TouchInit*);
 
@@ -96,7 +96,7 @@
   float force() const { return force_; }
 
   // Blink-internal methods
-  const LayoutPoint& AbsoluteLocation() const { return absolute_location_; }
+  const PhysicalOffset& AbsoluteLocation() const { return absolute_location_; }
   const gfx::PointF& ScreenLocation() const { return screen_pos_; }
   Touch* CloneWithNewTarget(EventTarget*) const;
 
@@ -118,7 +118,7 @@
   // FIXME(rbyers): Shouldn't we be able to migrate callers to relying on
   // screenPos, pagePos or clientPos? absoluteLocation appears to be the same as
   // pagePos but without browser scale applied.
-  LayoutPoint absolute_location_;
+  PhysicalOffset absolute_location_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 52ca3dc..6c888d90 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -1342,8 +1342,9 @@
     } else if (use_score_line_break) {
       DCHECK(score_line_break_context->LineBreakPoints().empty());
       DCHECK_EQ(score_line_break_context->LineBreakPointsIndex(), 0u);
-      NGScoreLineBreaker optimizer(Node(), ConstraintSpace(), line_opportunity);
-      optimizer.OptimalBreakPoints(break_token, *score_line_break_context);
+      NGScoreLineBreaker optimizer(Node(), ConstraintSpace(), line_opportunity,
+                                   break_token);
+      optimizer.OptimalBreakPoints(*score_line_break_context);
     }
 
     bool is_line_info_cached = false;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker.cc
index 3972540a..6ed9f76c 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker.cc
@@ -17,26 +17,21 @@
   scores_out_for_testing_ = scores_out;
 }
 
-void NGScoreLineBreaker::OptimalBreakPoints(
-    const NGInlineBreakToken* break_token,
-    NGScoreLineBreakContext& context) {
-  DCHECK(!is_balanced_ || !break_token);
+void NGScoreLineBreaker::OptimalBreakPoints(NGScoreLineBreakContext& context) {
+  DCHECK(!is_balanced_ || !break_token_);
   DCHECK(context.LineBreakPoints().empty());
   DCHECK(!node_.IsScoreLineBreakDisabled());
   DCHECK(context.IsActive());
   NGLineInfoList& line_info_list = context.LineInfoList();
   DCHECK_LT(line_info_list.Size(), NGLineInfoList::kCapacity);
   if (!line_info_list.IsEmpty()) {
-    // The incoming `break_token` should match the first cached line.
-    DCHECK_EQ((break_token ? break_token->Start() : NGInlineItemTextIndex()),
-              line_info_list.Front().Start());
-    // To compute the next line after the last cached line, update `break_token`
-    // to the last cached break token.
+    // To compute the next line after the last cached line, update
+    // `break_token_` to the last cached break token.
     const NGLineInfo& last_line = line_info_list.Back();
-    break_token = last_line.BreakToken();
+    break_token_ = last_line.BreakToken();
     // The last line should not be the end of paragraph.
     // `SuspendUntilConsumed()` should have prevented this from happening.
-    DCHECK(break_token && !last_line.HasForcedBreak());
+    DCHECK(break_token_ && !last_line.HasForcedBreak());
   }
 
   // Compute line breaks and cache the results (`NGLineInfo`) up to
@@ -46,11 +41,12 @@
   NGLineBreaker line_breaker(
       node_, NGLineBreakerMode::kContent, ConstraintSpace(), line_opportunity_,
       empty_leading_floats,
-      /* handled_leading_floats_index */ 0u, break_token,
+      /* handled_leading_floats_index */ 0u, break_token_,
       /* column_spanner_path */ nullptr, &empty_exclusion_space);
   for (;;) {
     NGLineInfo& line_info = line_info_list.Append();
     line_breaker.NextLine(&line_info);
+    break_token_ = line_info.BreakToken();
     if (UNLIKELY(line_breaker.ShouldDisableScoreLineBreak())) {
       context.SuspendUntilConsumed();
       return;
@@ -102,7 +98,7 @@
 
 void NGScoreLineBreaker::BalanceBreakPoints(NGScoreLineBreakContext& context) {
   is_balanced_ = true;
-  OptimalBreakPoints(/*break_token*/ nullptr, context);
+  OptimalBreakPoints(context);
 }
 
 bool NGScoreLineBreaker::Optimize(const NGLineInfoList& line_info_list,
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker.h
index 23e55e4..6deb03f 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker.h
@@ -44,15 +44,20 @@
  public:
   NGScoreLineBreaker(const NGInlineNode& node,
                      const NGConstraintSpace& space,
-                     const NGLineLayoutOpportunity& line_opportunity)
-      : node_(node), space_(space), line_opportunity_(line_opportunity) {
+                     const NGLineLayoutOpportunity& line_opportunity,
+                     const NGInlineBreakToken* break_token)
+      : node_(node),
+        space_(space),
+        line_opportunity_(line_opportunity),
+        break_token_(break_token) {
     DCHECK(!node.IsScoreLineBreakDisabled());
   }
 
+  const NGInlineBreakToken* BreakToken() const { return break_token_; }
+
   // The primary entry point of doing all the work described in the class
   // comment.
-  void OptimalBreakPoints(const NGInlineBreakToken* break_token,
-                          NGScoreLineBreakContext& context);
+  void OptimalBreakPoints(NGScoreLineBreakContext& context);
 
   // Makes the length of all lines balanced, by running the `OptimalBreakPoints`
   // with a higher penalty for the end of the paragraph.
@@ -97,6 +102,7 @@
   const NGInlineNode node_;
   const NGConstraintSpace& space_;
   const NGLineLayoutOpportunity& line_opportunity_;
+  const NGInlineBreakToken* break_token_;
   LayoutUnit available_width_;
   LayoutUnit first_line_indent_;
   float hyphen_penalty_ = .0f;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker_test.cc
index e8f5977..31152cb 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_score_line_breaker_test.cc
@@ -15,6 +15,12 @@
 
 namespace {
 
+LayoutUnit FragmentWidth(const NGInlineNode& node) {
+  const NGPhysicalBoxFragment* fragment =
+      node.GetLayoutBox()->GetPhysicalFragment(0);
+  return fragment->Size().width;
+}
+
 void TestLinesAreContiguous(const NGLineInfoList& line_info_list) {
   for (wtf_size_t i = 1; i < line_info_list.Size(); ++i) {
     EXPECT_EQ(line_info_list[i].Start(),
@@ -27,17 +33,15 @@
 class NGScoreLineBreakerTest : public RenderingTest {
  public:
   Vector<float> ComputeScores(const NGInlineNode& node) {
-    const NGPhysicalBoxFragment* fragment =
-        node.GetLayoutBox()->GetPhysicalFragment(0);
-    const LayoutUnit width = fragment->Size().width;
+    const LayoutUnit width = FragmentWidth(node);
     NGConstraintSpace space = ConstraintSpaceForAvailableSize(width);
     NGLineLayoutOpportunity line_opportunity(width);
-    NGScoreLineBreaker optimizer(node, space, line_opportunity);
+    const NGInlineBreakToken* break_token = nullptr;
+    NGScoreLineBreaker optimizer(node, space, line_opportunity, break_token);
     Vector<float> scores;
     optimizer.SetScoresOutForTesting(&scores);
     NGScoreLineBreakContext context;
-    const NGInlineBreakToken* break_token = nullptr;
-    optimizer.OptimalBreakPoints(break_token, context);
+    optimizer.OptimalBreakPoints(context);
     return scores;
   }
 };
@@ -63,19 +67,17 @@
     </div>
   )HTML");
   const NGInlineNode node = GetInlineNodeByElementId("target");
-  const NGPhysicalBoxFragment* fragment =
-      node.GetLayoutBox()->GetPhysicalFragment(0);
-  const LayoutUnit width = fragment->Size().width;
+  const LayoutUnit width = FragmentWidth(node);
   NGConstraintSpace space = ConstraintSpaceForAvailableSize(width);
   NGLineLayoutOpportunity line_opportunity(width);
   NGScoreLineBreakContext context;
   NGLineInfoList& line_info_list = context.LineInfoList();
-  NGScoreLineBreaker optimizer(node, space, line_opportunity);
+  const NGInlineBreakToken* break_token = nullptr;
+  NGScoreLineBreaker optimizer(node, space, line_opportunity, break_token);
 
   // Run the optimizer from the beginning of the `target`. This should cache
   // `NGLineInfoList::kCapacity` lines.
-  const NGInlineBreakToken* break_token = nullptr;
-  optimizer.OptimalBreakPoints(break_token, context);
+  optimizer.OptimalBreakPoints(context);
   EXPECT_EQ(line_info_list.Size(), NGLineInfoList::kCapacity);
   TestLinesAreContiguous(line_info_list);
 
@@ -89,7 +91,7 @@
     EXPECT_EQ(line_info_list.Size(), NGLineInfoList::kCapacity - 1);
     break_token = line_info0.BreakToken();
     // Running again should cache one more line.
-    optimizer.OptimalBreakPoints(break_token, context);
+    optimizer.OptimalBreakPoints(context);
     EXPECT_EQ(line_info_list.Size(), NGLineInfoList::kCapacity);
     TestLinesAreContiguous(line_info_list);
   }
@@ -118,15 +120,14 @@
     </div>
   )HTML");
   const NGInlineNode node = GetInlineNodeByElementId("target");
-  const NGPhysicalBoxFragment* fragment =
-      node.GetLayoutBox()->GetPhysicalFragment(0);
-  const LayoutUnit width = fragment->Size().width;
+  const LayoutUnit width = FragmentWidth(node);
   NGConstraintSpace space = ConstraintSpaceForAvailableSize(width);
   NGLineLayoutOpportunity line_opportunity(width);
   NGScoreLineBreakContext context;
   NGLineInfoList& line_info_list = context.LineInfoList();
   NGLineBreakPoints& break_points = context.LineBreakPoints();
-  NGScoreLineBreaker optimizer(node, space, line_opportunity);
+  const NGInlineBreakToken* break_token = nullptr;
+  NGScoreLineBreaker optimizer(node, space, line_opportunity, break_token);
 
   // Run the optimizer from the beginning of the `target`. This should stop at
   // `<br>` so that paragraphs separated by forced breaks are optimized
@@ -134,20 +135,18 @@
   //
   // Since the paragraphs has only 2 break candidates, it should return two
   // `NGLineInfo` without the optimization.
-  const NGInlineBreakToken* break_token = nullptr;
-  optimizer.OptimalBreakPoints(break_token, context);
+  optimizer.OptimalBreakPoints(context);
   EXPECT_EQ(break_points.size(), 0u);
   EXPECT_EQ(line_info_list.Size(), 2u);
 
   // Pretend all the lines are consumed.
-  break_token = line_info_list.Back().BreakToken();
-  EXPECT_TRUE(break_token);
+  EXPECT_TRUE(optimizer.BreakToken());
   line_info_list.Clear();
   context.DidCreateLine();
 
   // Run the optimizer again to continue. This should run up to the end of
   // `target`. It has 4 break candidates so the optimization should apply.
-  optimizer.OptimalBreakPoints(break_token, context);
+  optimizer.OptimalBreakPoints(context);
   EXPECT_EQ(break_points.size(), 3u);
   // `line_info_list` should be partially cleared, only after break points were
   // different.
@@ -251,15 +250,13 @@
     </style>
   )HTML") + data.html);
   const NGInlineNode node = GetInlineNodeByElementId("target");
-  const NGPhysicalBoxFragment* fragment =
-      node.GetLayoutBox()->GetPhysicalFragment(0);
-  const LayoutUnit width = fragment->Size().width;
+  const LayoutUnit width = FragmentWidth(node);
   NGConstraintSpace space = ConstraintSpaceForAvailableSize(width);
   NGLineLayoutOpportunity line_opportunity(width);
   NGScoreLineBreakContext context;
-  NGScoreLineBreaker optimizer(node, space, line_opportunity);
   const NGInlineBreakToken* break_token = nullptr;
-  optimizer.OptimalBreakPoints(break_token, context);
+  NGScoreLineBreaker optimizer(node, space, line_opportunity, break_token);
+  optimizer.OptimalBreakPoints(context);
   EXPECT_FALSE(context.IsActive());
   if (data.disabled) {
     EXPECT_EQ(context.LineBreakPoints().size(), 0u);
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
index 8cfa62a..4364926 100644
--- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -380,6 +380,10 @@
     }
   }
 
+  request.SetSharedDictionaryWriterEnabled(
+      RuntimeEnabledFeatures::CompressionDictionaryTransportEnabled(
+          GetExecutionContext()));
+
   GetLocalFrameClient()->DispatchWillSendRequest(request);
   FrameScheduler* frame_scheduler = GetFrame()->GetFrameScheduler();
   if (!for_redirect && frame_scheduler) {
diff --git a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector_test.cc
index 58ca6490..946a77d1 100644
--- a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector_test.cc
+++ b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector_test.cc
@@ -284,9 +284,18 @@
         SkImageInfo::MakeN32Premul(width, height, src_rgb_color_space);
     sk_sp<SkSurface> surface(SkSurfaces::Raster(raster_image_info));
     sk_sp<SkImage> image = surface->makeImageSnapshot();
+    scoped_refptr<UnacceleratedStaticBitmapImage> original_image_data =
+        UnacceleratedStaticBitmapImage::Create(image);
+    // To ensure that the image may be considered as an LCP candidate, allocate
+    // a small amount of memory for the image (0.1bpp should exceed the LCP
+    // entropy threshold).
+    int bytes = (width * height / 80) + 1;
+    Vector<char> img_data(bytes);
+    scoped_refptr<SharedBuffer> shared_buffer =
+        SharedBuffer::AdoptVector(img_data);
+    original_image_data->SetData(shared_buffer, /*all_data_received=*/true);
     ImageResourceContent* original_image_content =
-        ImageResourceContent::CreateLoaded(
-            UnacceleratedStaticBitmapImage::Create(image).get());
+        ImageResourceContent::CreateLoaded(original_image_data.get());
     return original_image_content;
   }
 
diff --git a/third_party/blink/renderer/core/paint/timing/largest_contentful_paint_calculator_test.cc b/third_party/blink/renderer/core/paint/timing/largest_contentful_paint_calculator_test.cc
index 4ae2a6b..51c6a98 100644
--- a/third_party/blink/renderer/core/paint/timing/largest_contentful_paint_calculator_test.cc
+++ b/third_party/blink/renderer/core/paint/timing/largest_contentful_paint_calculator_test.cc
@@ -218,7 +218,7 @@
     <img id='target'/>
     <p>.</p>
   )HTML");
-  SetImage("target", 100, 200);
+  SetImage("target", 100, 200, /*bytes=*/250);
   UpdateAllLifecyclePhasesForTest();
   SimulateImagePresentationPromise();
   EXPECT_EQ(LargestReportedSize(), 20000u);
@@ -227,7 +227,7 @@
 
   // Text should not be reported, since it is smaller than the image.
   EXPECT_EQ(LargestReportedSize(), 20000u);
-  EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.0f);
+  EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.1f);
   EXPECT_EQ(CountCandidates(), 1u);
   trace_analyzer::Stop();
 }
@@ -238,7 +238,7 @@
     <img id='target'/>
     <p>.</p>
   )HTML");
-  SetImage("target", 100, 200);
+  SetImage("target", 100, 200, /*bytes=*/250);
   UpdateAllLifecyclePhasesForTest();
   SimulateContentPresentationPromise();
 
@@ -253,11 +253,12 @@
     <img id='target'/>
     <p>This text should be larger than the image!!!!</p>
   )HTML");
-  SetImage("target", 3, 3);
+  SetImage("target", 3, 3, /*bytes=*/9);
   UpdateAllLifecyclePhasesForTest();
   SimulateContentPresentationPromise();
 
-  // Image should not be reported, since it is smaller than the text.
+  // Image should not be reported, since it is smaller than the text. No image
+  // BPP should be recorded.
   EXPECT_GT(LargestReportedSize(), 9u);
   EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.0f);
   EXPECT_EQ(CountCandidates(), 1u);
@@ -301,7 +302,7 @@
     </p>
     <p id='small'>.</p>
   )HTML");
-  SetImage("medium", 10, 5);
+  SetImage("medium", 10, 5, /*bytes=*/50);
   UpdateAllLifecyclePhasesForTest();
   SimulateImagePresentationPromise();
   SimulateTextPresentationPromise();
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni
index 58c8d7c..491a8c1 100644
--- a/third_party/blink/renderer/core/style/build.gni
+++ b/third_party/blink/renderer/core/style/build.gni
@@ -107,6 +107,8 @@
   "style_ray.cc",
   "style_ray.h",
   "style_reflection.h",
+  "style_scrollbar_color.cc",
+  "style_scrollbar_color.h",
   "style_self_alignment_data.h",
   "style_svg_resource.cc",
   "style_svg_resource.h",
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 9ee9df7..2d8a1fd 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -58,6 +58,7 @@
 #include "third_party/blink/renderer/core/style/font_size_style.h"
 #include "third_party/blink/renderer/core/style/style_cached_data.h"
 #include "third_party/blink/renderer/core/style/style_highlight_data.h"
+#include "third_party/blink/renderer/core/style/style_scrollbar_color.h"
 #include "third_party/blink/renderer/core/style/transform_origin.h"
 #include "third_party/blink/renderer/platform/geometry/length.h"
 #include "third_party/blink/renderer/platform/geometry/length_box.h"
diff --git a/third_party/blink/renderer/core/style/style_scrollbar_color.cc b/third_party/blink/renderer/core/style/style_scrollbar_color.cc
new file mode 100644
index 0000000..62507009
--- /dev/null
+++ b/third_party/blink/renderer/core/style/style_scrollbar_color.cc
@@ -0,0 +1,14 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/style/style_scrollbar_color.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+
+namespace blink {
+
+StyleScrollbarColor::StyleScrollbarColor(StyleColor thumbColor,
+                                         StyleColor trackColor)
+    : thumb_color_(thumbColor), track_color_(trackColor) {}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_scrollbar_color.h b/third_party/blink/renderer/core/style/style_scrollbar_color.h
new file mode 100644
index 0000000..13374d9
--- /dev/null
+++ b/third_party/blink/renderer/core/style/style_scrollbar_color.h
@@ -0,0 +1,37 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_SCROLLBAR_COLOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_SCROLLBAR_COLOR_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/style_color.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class CORE_EXPORT StyleScrollbarColor {
+  DISALLOW_NEW();
+
+ public:
+  StyleScrollbarColor();
+  StyleScrollbarColor(StyleColor thumb_color, StyleColor track_color);
+
+  StyleColor GetThumbColor() const { return thumb_color_; }
+  StyleColor GetTrackColor() const { return track_color_; }
+
+  bool operator==(const StyleScrollbarColor& o) const {
+    return thumb_color_ == o.thumb_color_ && track_color_ == o.track_color_;
+  }
+
+  bool operator!=(const StyleScrollbarColor& o) const { return !(*this == o); }
+
+ private:
+  StyleColor thumb_color_;
+  StyleColor track_color_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_SCROLLBAR_COLOR_H_
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc
index 2c01cce01..3ff9a56a 100644
--- a/third_party/blink/renderer/core/timing/performance.cc
+++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -587,6 +587,8 @@
     case PerformanceEntry::kLongAnimationFrame:
       if (RuntimeEnabledFeatures::LongAnimationFrameTimingEnabled(
               GetExecutionContext())) {
+        UseCounter::Count(GetExecutionContext(),
+                          WebFeature::kLongAnimationFrameRequested);
         entries = &long_animation_frame_buffer_;
       }
       break;
diff --git a/third_party/blink/renderer/core/timing/performance_observer.cc b/third_party/blink/renderer/core/timing/performance_observer.cc
index f2dad9f..81fc71e 100644
--- a/third_party/blink/renderer/core/timing/performance_observer.cc
+++ b/third_party/blink/renderer/core/timing/performance_observer.cc
@@ -245,6 +245,10 @@
     UseCounter::Count(GetExecutionContext(),
                       WebFeature::kVisibilityStateObserver);
   }
+  if (filter_options_ & PerformanceEntry::kLongAnimationFrame) {
+    UseCounter::Count(GetExecutionContext(),
+                      WebFeature::kLongAnimationFrameObserver);
+  }
 
   requires_dropped_entries_ = true;
   if (is_registered_)
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn
index 4a61101..5ee76559 100644
--- a/third_party/blink/renderer/modules/BUILD.gn
+++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -436,6 +436,7 @@
     "animationworklet/worklet_animation_test.cc",
     "background_fetch/background_fetch_icon_loader_test.cc",
     "background_fetch/background_fetch_manager_test.cc",
+    "bluetooth/bluetooth_uuid_unittest.cc",
     "broadcastchannel/broadcast_channel_unittest.cc",
     "cache_storage/cache_test.cc",
     "canvas/canvas2d/base_rendering_context_2d_test.cc",
@@ -714,7 +715,10 @@
   # current_os="linux" and target_os="android". Using target_os is necessary as
   # we need to compile in the same way as would happen when current_os="android".
   if (target_os != "android") {
-    deps += [ "//third_party/blink/renderer/modules/direct_sockets:unit_tests" ]
+    deps += [
+      "//third_party/blink/renderer/modules/direct_sockets:unit_tests",
+      "//third_party/blink/renderer/modules/serial:unit_tests",
+    ]
   }
 
   data_deps = [
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index e89ff89..c35d6358 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -70,6 +70,7 @@
 #include "third_party/blink/renderer/core/html/html_script_element.h"
 #include "third_party/blink/renderer/core/html/html_slot_element.h"
 #include "third_party/blink/renderer/core/html/html_style_element.h"
+#include "third_party/blink/renderer/core/html/html_table_cell_element.h"
 #include "third_party/blink/renderer/core/html/html_table_element.h"
 #include "third_party/blink/renderer/core/html/html_table_row_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
@@ -78,6 +79,9 @@
 #include "third_party/blink/renderer/core/layout/layout_text.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/page/focus_controller.h"
 #include "third_party/blink/renderer/core/page/page.h"
@@ -2141,19 +2145,17 @@
     }
   }
 
-  // Once we have reached the threshold number of roles that forces a data
-  // table, invalidate the AXTable if it was previously a layout table, so that
-  // its subtree recomputes roles.
-  if (IsA<HTMLTableRowElement>(node)) {
-    if (auto* table_element =
-            Traversal<HTMLTableElement>::FirstAncestor(*node)) {
-      if (table_element->rows()->length() >=
-          AXObjectCacheImpl::kDataTableHeuristicMinRows) {
-        if (AXObject* ax_table = Get(table_element)) {
-          if (ax_table->RoleValue() == ax::mojom::blink::Role::kLayoutTable)
-            HandleRoleChangeWithCleanLayout(table_element);
-        }
+  // Check if a row or cell's table changed to or from a data table.
+  if (IsA<HTMLTableRowElement>(node) || IsA<HTMLTableCellElement>(node)) {
+    Element* parent = node->parentElement();
+    while (parent) {
+      if (DynamicTo<HTMLTableElement>(parent)) {
+        break;
       }
+      parent = parent->parentElement();
+    }
+    if (parent) {
+      UpdateTableRoleWithCleanLayout(parent);
     }
   }
 }
@@ -2403,13 +2405,15 @@
     UpdateTreeIfNeededOnce();
   }
 
-#if EXPENSIVE_DCHECKS_ARE_ON()
-  for (const auto& entry : objects_) {
-    const AXObject* object = entry.value;
-    DCHECK(!object->HasDirtyDescendants())
-        << "No children in the tree should require an update at this point.";
-  }
-#endif
+  // TODO(chrishtr): re-enable this once crbug.com/1446721 is fixed.
+  // #if EXPENSIVE_DCHECKS_ARE_ON()
+  //   for (const auto& entry : objects_) {
+  //     const AXObject* object = entry.value;
+  //     DCHECK(!object->HasDirtyDescendants())
+  //         << "No children in the tree should require an update at this
+  //         point.";
+  //   }
+  // #endif
 }
 
 void AXObjectCacheImpl::ProcessDeferredAccessibilityEvents(Document& document) {
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.cc
index cf23f4fb..4443272 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.cc
@@ -318,6 +318,16 @@
   return &descriptors_map;
 }
 
+String GetUUIDFromV8Value(const V8UnionStringOrUnsignedLong* value) {
+  // unsigned long values interpret as 16-bit UUID values as per
+  // https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf.
+  if (value->IsUnsignedLong()) {
+    return blink::BluetoothUUID::canonicalUUID(value->GetAsUnsignedLong());
+  }
+
+  return value->GetAsString();
+}
+
 String GetUUIDForGATTAttribute(GATTAttribute attribute,
                                const V8UnionStringOrUnsignedLong* name,
                                ExceptionState& exception_state) {
@@ -328,14 +338,7 @@
   // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getcharacteristic
   // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getdescriptor
 
-  // If name is an unsigned long, return BluetoothUUID.canonicalUUID(name) and
-  // abort this steps.
-  if (name->IsUnsignedLong())
-    return BluetoothUUID::canonicalUUID(name->GetAsUnsignedLong());
-
-  const String& name_str = name->GetAsString();
-
-  // If name is a valid UUID, return name and abort these steps.
+  const String name_str = GetUUIDFromV8Value(name);
   if (WTF::IsValidUUID(name_str))
     return name_str;
 
@@ -395,10 +398,14 @@
 
 }  // namespace
 
+String GetBluetoothUUIDFromV8Value(const V8UnionStringOrUnsignedLong* value) {
+  const String value_str = GetUUIDFromV8Value(value);
+  return WTF::IsValidUUID(value_str) ? value_str : "";
+}
+
 // static
-String BluetoothUUID::getService(
-    const V8BluetoothServiceUUID* name,
-    ExceptionState& exception_state) {
+String BluetoothUUID::getService(const V8BluetoothServiceUUID* name,
+                                 ExceptionState& exception_state) {
   return GetUUIDForGATTAttribute(GATTAttribute::kService, name,
                                  exception_state);
 }
@@ -412,9 +419,8 @@
 }
 
 // static
-String BluetoothUUID::getDescriptor(
-    const V8BluetoothDescriptorUUID* name,
-    ExceptionState& exception_state) {
+String BluetoothUUID::getDescriptor(const V8BluetoothDescriptorUUID* name,
+                                    ExceptionState& exception_state) {
   return GetUUIDForGATTAttribute(GATTAttribute::kDescriptor, name,
                                  exception_state);
 }
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h
index c2701a7..3309674 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_UUID_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_UUID_H_
 
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 
@@ -28,6 +29,12 @@
   static String canonicalUUID(unsigned alias);
 };
 
+// Helper function to retrieve the UUID (as a string) from the V8 value.
+// The value may be a string or 16-bit unsigned integer. If the value cannot
+// be interpreted as a valid UUID then an empty string will be returned.
+BLINK_EXPORT String
+GetBluetoothUUIDFromV8Value(const V8UnionStringOrUnsignedLong* value);
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_UUID_H_
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid_unittest.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid_unittest.cc
new file mode 100644
index 0000000..692cfe4
--- /dev/null
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid_unittest.cc
@@ -0,0 +1,46 @@
+// Copyright 2023 The Chromium 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 "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unsignedlong.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+TEST(BluetoothUUIDTest, GetBluetoothUUIDFromV8Value_CanonicalUUID) {
+  const String expected_uuid("9260c06d-a6d7-4a0f-9817-0b0d5556461f");
+  V8UnionStringOrUnsignedLong v8_uuid(expected_uuid);
+  String uuid = GetBluetoothUUIDFromV8Value(&v8_uuid);
+  EXPECT_EQ(uuid, expected_uuid);
+}
+
+TEST(BluetoothUUIDTest, GetBluetoothUUIDFromV8Value_16bitUUID) {
+  const String expected_uuid("00001101-0000-1000-8000-00805f9b34fb");
+  V8UnionStringOrUnsignedLong v8_uuid(0x1101);
+  String uuid = GetBluetoothUUIDFromV8Value(&v8_uuid);
+  EXPECT_EQ(uuid, expected_uuid);
+}
+
+TEST(BluetoothUUIDTest, GetBluetoothUUIDFromV8Value_EmptyString) {
+  V8UnionStringOrUnsignedLong v8_uuid("");
+  String uuid = GetBluetoothUUIDFromV8Value(&v8_uuid);
+  EXPECT_TRUE(uuid.empty());
+}
+
+TEST(BluetoothUUIDTest, GetBluetoothUUIDFromV8Value_BluetoothName) {
+  // GetBluetoothUUIDFromV8Value doesn't support UUID names - verify that.
+  V8UnionStringOrUnsignedLong v8_uuid("height");
+  String uuid = GetBluetoothUUIDFromV8Value(&v8_uuid);
+  EXPECT_TRUE(uuid.empty());
+}
+
+TEST(BluetoothUUIDTest, GetBluetoothUUIDFromV8Value_InvalidUUID) {
+  V8UnionStringOrUnsignedLong v8_uuid("00000000-0000-0000-0000-000000000000-X");
+  String uuid = GetBluetoothUUIDFromV8Value(&v8_uuid);
+  EXPECT_TRUE(uuid.empty());
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_device.cc b/third_party/blink/renderer/modules/hid/hid_device.cc
index 1a831d9..88dfde6 100644
--- a/third_party/blink/renderer/modules/hid/hid_device.cc
+++ b/third_party/blink/renderer/modules/hid/hid_device.cc
@@ -555,7 +555,7 @@
 
 void HIDDevice::MarkRequestComplete(ScriptPromiseResolver* resolver) {
   auto find_result = device_requests_.find(resolver);
-  DCHECK_NE(device_requests_.end(), find_result);
+  CHECK_NE(device_requests_.end(), find_result);
   device_requests_.erase(find_result);
 }
 
diff --git a/third_party/blink/renderer/modules/scheduler/dom_timer.cc b/third_party/blink/renderer/modules/scheduler/dom_timer.cc
index 1421ae6..e65d92f6 100644
--- a/third_party/blink/renderer/modules/scheduler/dom_timer.cc
+++ b/third_party/blink/renderer/modules/scheduler/dom_timer.cc
@@ -38,7 +38,6 @@
 #include "third_party/blink/renderer/core/frame/page_dismissal_scope.h"
 #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
 #include "third_party/blink/renderer/core/probe/core_probes.h"
-#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/modules/scheduler/scheduled_action.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -136,43 +135,22 @@
   int timer_nesting_level_ = 0;
 };
 
-bool IsAllowed(ExecutionContext& execution_context,
-               bool is_eval,
-               const String& source) {
-  if (auto* window = DynamicTo<LocalDOMWindow>(execution_context)) {
-    if (!window->GetFrame()) {
-      return false;
-    }
-    if (is_eval && !window->GetContentSecurityPolicy()->AllowEval(
-                       ReportingDisposition::kReport,
-                       ContentSecurityPolicy::kWillNotThrowException, source)) {
-      return false;
-    }
-    if (PageDismissalScope::IsActive()) {
-      UseCounter::Count(execution_context,
-                        window->document()->ProcessingBeforeUnload()
-                            ? WebFeature::kTimerInstallFromBeforeUnload
-                            : WebFeature::kTimerInstallFromUnload);
-    }
-    return true;
+bool IsAllowed(ExecutionContext& context, bool is_eval, const String& source) {
+  if (context.IsContextDestroyed()) {
+    return false;
   }
-  if (auto* worker_global_scope =
-          DynamicTo<WorkerGlobalScope>(execution_context)) {
-    if (!worker_global_scope->ScriptController()) {
-      return false;
-    }
-    ContentSecurityPolicy* policy =
-        worker_global_scope->GetContentSecurityPolicy();
-    if (is_eval && policy &&
-        !policy->AllowEval(ReportingDisposition::kReport,
-                           ContentSecurityPolicy::kWillNotThrowException,
-                           source)) {
-      return false;
-    }
-    return true;
+  if (is_eval && !context.GetContentSecurityPolicy()->AllowEval(
+                     ReportingDisposition::kReport,
+                     ContentSecurityPolicy::kWillNotThrowException, source)) {
+    return false;
   }
-  NOTREACHED();
-  return false;
+  if (auto* window = DynamicTo<LocalDOMWindow>(context);
+      window && PageDismissalScope::IsActive()) {
+    UseCounter::Count(window, window->document()->ProcessingBeforeUnload()
+                                  ? WebFeature::kTimerInstallFromBeforeUnload
+                                  : WebFeature::kTimerInstallFromUnload);
+  }
+  return true;
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/modules/serial/BUILD.gn b/third_party/blink/renderer/modules/serial/BUILD.gn
index 46f9114..43d7442d 100644
--- a/third_party/blink/renderer/modules/serial/BUILD.gn
+++ b/third_party/blink/renderer/modules/serial/BUILD.gn
@@ -19,4 +19,26 @@
     "serial_port_underlying_source.cc",
     "serial_port_underlying_source.h",
   ]
+  deps = [ "//third_party/blink/renderer/modules/bluetooth" ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "serial_unittest.cc" ]
+
+  configs += [
+    "//third_party/blink/renderer:config",
+    "//third_party/blink/renderer:inside_blink",
+    "//third_party/blink/renderer/core:blink_core_pch",
+  ]
+
+  deps = [
+    "//base/test:test_support",
+    "//testing/gtest",
+    "//third_party/blink/renderer/controller:blink_bindings_test_sources",
+    "//third_party/blink/renderer/modules",
+    "//third_party/blink/renderer/platform",
+    "//third_party/blink/renderer/platform:test_support",
+    "//third_party/blink/renderer/platform/wtf",
+  ]
 }
diff --git a/third_party/blink/renderer/modules/serial/serial.cc b/third_party/blink/renderer/modules/serial/serial.cc
index ef6505c..9be90b08 100644
--- a/third_party/blink/renderer/modules/serial/serial.cc
+++ b/third_party/blink/renderer/modules/serial/serial.cc
@@ -10,6 +10,7 @@
 #include "base/unguessable_token.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-blink.h"
+#include "third_party/blink/public/mojom/serial/serial.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_serial_port_filter.h"
@@ -22,6 +23,7 @@
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h"
 #include "third_party/blink/renderer/modules/event_target_modules_names.h"
 #include "third_party/blink/renderer/modules/serial/serial_port.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -151,6 +153,53 @@
   return resolver->Promise();
 }
 
+// static
+mojom::blink::SerialPortFilterPtr Serial::CreateMojoFilter(
+    const SerialPortFilter* filter,
+    ExceptionState& exception_state) {
+  auto mojo_filter = mojom::blink::SerialPortFilter::New();
+
+  if (filter->hasBluetoothServiceClassId()) {
+    if (filter->hasUsbVendorId() || filter->hasUsbProductId()) {
+      exception_state.ThrowTypeError(
+          "A filter cannot specify both bluetoothServiceClassId and "
+          "usbVendorId or usbProductId.");
+      return nullptr;
+    }
+    mojo_filter->bluetooth_service_class_id =
+        ::bluetooth::mojom::blink::UUID::New(
+            GetBluetoothUUIDFromV8Value(filter->bluetoothServiceClassId()));
+    if (mojo_filter->bluetooth_service_class_id->uuid.empty()) {
+      exception_state.ThrowTypeError(
+          "Invalid Bluetooth service class ID filter value.");
+      return nullptr;
+    }
+    return mojo_filter;
+  }
+
+  mojo_filter->has_product_id = filter->hasUsbProductId();
+  mojo_filter->has_vendor_id = filter->hasUsbVendorId();
+  if (mojo_filter->has_product_id) {
+    if (!mojo_filter->has_vendor_id) {
+      exception_state.ThrowTypeError(
+          "A filter containing a usbProductId must also specify a "
+          "usbVendorId.");
+      return nullptr;
+    }
+    mojo_filter->product_id = filter->usbProductId();
+  }
+
+  if (mojo_filter->has_vendor_id) {
+    mojo_filter->vendor_id = filter->usbVendorId();
+  } else {
+    exception_state.ThrowTypeError(
+        "A filter must provide a property to filter by.");
+    return nullptr;
+  }
+
+  return mojo_filter;
+}
+
 ScriptPromise Serial::requestPort(ScriptState* script_state,
                                   const SerialPortRequestOptions* options,
                                   ExceptionState& exception_state) {
@@ -168,38 +217,34 @@
   Vector<mojom::blink::SerialPortFilterPtr> filters;
   if (options && options->hasFilters()) {
     for (const auto& filter : options->filters()) {
-      auto mojo_filter = mojom::blink::SerialPortFilter::New();
-
-      mojo_filter->has_vendor_id = filter->hasUsbVendorId();
-      if (mojo_filter->has_vendor_id) {
-        mojo_filter->vendor_id = filter->usbVendorId();
-      } else {
-        exception_state.ThrowTypeError(
-            "A filter must provide a property to filter by.");
+      auto mojo_filter = CreateMojoFilter(filter, exception_state);
+      if (!mojo_filter) {
+        CHECK(exception_state.HadException());
         return ScriptPromise();
       }
 
-      mojo_filter->has_product_id = filter->hasUsbProductId();
-      if (mojo_filter->has_product_id) {
-        if (!mojo_filter->has_vendor_id) {
-          exception_state.ThrowTypeError(
-              "A filter containing a usbProductId must also specify a "
-              "usbVendorId.");
-          return ScriptPromise();
-        }
-        mojo_filter->product_id = filter->usbProductId();
-      }
-
+      CHECK(!exception_state.HadException());
       filters.push_back(std::move(mojo_filter));
     }
   }
 
+  Vector<::bluetooth::mojom::blink::UUIDPtr>
+      allowed_bluetooth_service_class_ids;
+  if (options && options->hasAllowedBluetoothServiceClassIds()) {
+    for (const auto& id : options->allowedBluetoothServiceClassIds()) {
+      allowed_bluetooth_service_class_ids.push_back(
+          ::bluetooth::mojom::blink::UUID::New(
+              GetBluetoothUUIDFromV8Value(id)));
+    }
+  }
+
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(
       script_state, exception_state.GetContext());
   request_port_promises_.insert(resolver);
 
   EnsureServiceConnection();
   service_->RequestPort(std::move(filters),
+                        std::move(allowed_bluetooth_service_class_ids),
                         resolver->WrapCallbackInScriptScope(WTF::BindOnce(
                             &Serial::OnRequestPort, WrapPersistent(this))));
 
diff --git a/third_party/blink/renderer/modules/serial/serial.h b/third_party/blink/renderer/modules/serial/serial.h
index 5fceaec..2fd391e 100644
--- a/third_party/blink/renderer/modules/serial/serial.h
+++ b/third_party/blink/renderer/modules/serial/serial.h
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/core/dom/events/event_target.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
@@ -27,11 +28,12 @@
 class ScriptState;
 class SerialPort;
 class SerialPortRequestOptions;
+class SerialPortFilter;
 
-class Serial final : public EventTargetWithInlineData,
-                     public Supplement<NavigatorBase>,
-                     public ExecutionContextLifecycleObserver,
-                     public mojom::blink::SerialServiceClient {
+class MODULES_EXPORT Serial final : public EventTargetWithInlineData,
+                                    public Supplement<NavigatorBase>,
+                                    public ExecutionContextLifecycleObserver,
+                                    public mojom::blink::SerialServiceClient {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
@@ -40,6 +42,13 @@
   // Web-exposed navigator.serial
   static Serial* serial(NavigatorBase&);
 
+  // Given a JavaScript `filter` object create a Mojo filter object.
+  // Upon error an exception will be thrown (using `exception_state`) and a
+  // null Mojo filter object will be returned.
+  static mojom::blink::SerialPortFilterPtr CreateMojoFilter(
+      const SerialPortFilter* filter,
+      ExceptionState& exception_state);
+
   explicit Serial(NavigatorBase&);
 
   // EventTarget
diff --git a/third_party/blink/renderer/modules/serial/serial_port.cc b/third_party/blink/renderer/modules/serial/serial_port.cc
index e7661cc..6b44cd2 100644
--- a/third_party/blink/renderer/modules/serial/serial_port.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unsignedlong.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_serial_input_signals.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_serial_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_serial_output_signals.h"
@@ -127,6 +128,12 @@
     info->setUsbVendorId(info_->usb_vendor_id);
   if (info_->has_usb_product_id)
     info->setUsbProductId(info_->usb_product_id);
+  if (RuntimeEnabledFeatures::WebSerialBluetoothEnabled() &&
+      info_->bluetooth_service_class_id) {
+    info->setBluetoothServiceClassId(
+        MakeGarbageCollected<V8UnionStringOrUnsignedLong>(
+            info_->bluetooth_service_class_id->uuid));
+  }
   return info;
 }
 
diff --git a/third_party/blink/renderer/modules/serial/serial_port_filter.idl b/third_party/blink/renderer/modules/serial/serial_port_filter.idl
index 8c87785..d4256ea 100644
--- a/third_party/blink/renderer/modules/serial/serial_port_filter.idl
+++ b/third_party/blink/renderer/modules/serial/serial_port_filter.idl
@@ -7,4 +7,5 @@
 dictionary SerialPortFilter {
   unsigned short usbVendorId;
   unsigned short usbProductId;
+  BluetoothServiceUUID bluetoothServiceClassId;
 };
diff --git a/third_party/blink/renderer/modules/serial/serial_port_info.idl b/third_party/blink/renderer/modules/serial/serial_port_info.idl
index 36caedd72..2f0343d 100644
--- a/third_party/blink/renderer/modules/serial/serial_port_info.idl
+++ b/third_party/blink/renderer/modules/serial/serial_port_info.idl
@@ -7,4 +7,5 @@
 dictionary SerialPortInfo {
   unsigned short usbVendorId;
   unsigned short usbProductId;
+  BluetoothServiceUUID bluetoothServiceClassId;
 };
diff --git a/third_party/blink/renderer/modules/serial/serial_port_request_options.idl b/third_party/blink/renderer/modules/serial/serial_port_request_options.idl
index d995acf6..bec4dde8 100644
--- a/third_party/blink/renderer/modules/serial/serial_port_request_options.idl
+++ b/third_party/blink/renderer/modules/serial/serial_port_request_options.idl
@@ -6,4 +6,5 @@
 
 dictionary SerialPortRequestOptions {
   sequence<SerialPortFilter> filters;
+  sequence<BluetoothServiceUUID> allowedBluetoothServiceClassIds;
 };
diff --git a/third_party/blink/renderer/modules/serial/serial_unittest.cc b/third_party/blink/renderer/modules/serial/serial_unittest.cc
new file mode 100644
index 0000000..14fceed
--- /dev/null
+++ b/third_party/blink/renderer/modules/serial/serial_unittest.cc
@@ -0,0 +1,134 @@
+// Copyright 2023 The Chromium 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 "third_party/blink/renderer/modules/serial/serial.h"
+
+#include "third_party/blink/public/mojom/serial/serial.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unsignedlong.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_serial_port_filter.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.h"
+
+namespace blink {
+
+namespace {
+
+constexpr uint16_t kTestVendorId = 0x0001;
+constexpr uint16_t kTestProductId = 0x0002;
+constexpr char kTestServiceClassId[] = "05079c61-147f-473d-8127-fab1bbad7e1a";
+
+}  // namespace
+
+TEST(SerialTest, CreateMojoFilter_EmptyFilter) {
+  V8TestingScope scope;
+
+  SerialPortFilter* js_filter = SerialPortFilter::Create(scope.GetIsolate());
+
+  mojom::blink::SerialPortFilterPtr mojo_filter =
+      Serial::CreateMojoFilter(js_filter, scope.GetExceptionState());
+  EXPECT_FALSE(mojo_filter);
+  EXPECT_TRUE(scope.GetExceptionState().HadException());
+  EXPECT_EQ(ToExceptionCode(ESErrorType::kTypeError),
+            scope.GetExceptionState().Code());
+}
+
+TEST(SerialTest, CreateMojoFilter_VendorId) {
+  V8TestingScope scope;
+
+  SerialPortFilter* js_filter = SerialPortFilter::Create(scope.GetIsolate());
+  js_filter->setUsbVendorId(kTestVendorId);
+
+  mojom::blink::SerialPortFilterPtr mojo_filter =
+      Serial::CreateMojoFilter(js_filter, scope.GetExceptionState());
+  ASSERT_TRUE(mojo_filter);
+  EXPECT_FALSE(scope.GetExceptionState().HadException());
+  EXPECT_TRUE(mojo_filter->has_vendor_id);
+  EXPECT_EQ(kTestVendorId, mojo_filter->vendor_id);
+  EXPECT_FALSE(mojo_filter->has_product_id);
+  EXPECT_FALSE(mojo_filter->bluetooth_service_class_id);
+}
+
+TEST(SerialTest, CreateMojoFilter_ProductNoVendorId) {
+  V8TestingScope scope;
+
+  SerialPortFilter* js_filter = SerialPortFilter::Create(scope.GetIsolate());
+  // If the filter has a product ID then it must also have a vendor ID.
+  js_filter->setUsbProductId(kTestProductId);
+
+  mojom::blink::SerialPortFilterPtr mojo_filter =
+      Serial::CreateMojoFilter(js_filter, scope.GetExceptionState());
+  EXPECT_FALSE(mojo_filter);
+  EXPECT_TRUE(scope.GetExceptionState().HadException());
+  EXPECT_EQ(ToExceptionCode(ESErrorType::kTypeError),
+            scope.GetExceptionState().Code());
+}
+
+TEST(SerialTest, CreateMojoFilter_BluetoothServiceClassAndVendorId) {
+  V8TestingScope scope;
+
+  SerialPortFilter* js_filter = SerialPortFilter::Create(scope.GetIsolate());
+  // Can't have both Bluetooth and USB filter parameters.
+  V8UnionStringOrUnsignedLong uuid(kTestServiceClassId);
+  js_filter->setUsbVendorId(kTestVendorId);
+  js_filter->setBluetoothServiceClassId(&uuid);
+
+  mojom::blink::SerialPortFilterPtr mojo_filter =
+      Serial::CreateMojoFilter(js_filter, scope.GetExceptionState());
+  EXPECT_FALSE(mojo_filter);
+  EXPECT_TRUE(scope.GetExceptionState().HadException());
+  EXPECT_EQ(ToExceptionCode(ESErrorType::kTypeError),
+            scope.GetExceptionState().Code());
+}
+
+TEST(SerialTest, CreateMojoFilter_BluetoothServiceClassAndProductId) {
+  V8TestingScope scope;
+
+  SerialPortFilter* js_filter = SerialPortFilter::Create(scope.GetIsolate());
+  // Can't have both Bluetooth and USB filter parameters.
+  js_filter->setUsbProductId(kTestProductId);
+  js_filter->setBluetoothServiceClassId(
+      MakeGarbageCollected<V8UnionStringOrUnsignedLong>(kTestServiceClassId));
+
+  mojom::blink::SerialPortFilterPtr mojo_filter =
+      Serial::CreateMojoFilter(js_filter, scope.GetExceptionState());
+  EXPECT_FALSE(mojo_filter);
+  EXPECT_TRUE(scope.GetExceptionState().HadException());
+  EXPECT_EQ(ToExceptionCode(ESErrorType::kTypeError),
+            scope.GetExceptionState().Code());
+}
+
+TEST(SerialTest, CreateMojoFilter_BluetoothServiceClass) {
+  V8TestingScope scope;
+
+  SerialPortFilter* js_filter = SerialPortFilter::Create(scope.GetIsolate());
+  js_filter->setBluetoothServiceClassId(
+      MakeGarbageCollected<V8UnionStringOrUnsignedLong>(kTestServiceClassId));
+
+  mojom::blink::SerialPortFilterPtr mojo_filter =
+      Serial::CreateMojoFilter(js_filter, scope.GetExceptionState());
+  ASSERT_TRUE(mojo_filter);
+  EXPECT_FALSE(scope.GetExceptionState().HadException());
+
+  EXPECT_FALSE(mojo_filter->has_vendor_id);
+  EXPECT_FALSE(mojo_filter->has_product_id);
+  ASSERT_TRUE(mojo_filter->bluetooth_service_class_id);
+  EXPECT_EQ(kTestServiceClassId, mojo_filter->bluetooth_service_class_id->uuid);
+}
+
+TEST(SerialTest, CreateMojoFilter_InvalidBluetoothServiceClass) {
+  V8TestingScope scope;
+
+  SerialPortFilter* js_filter = SerialPortFilter::Create(scope.GetIsolate());
+  js_filter->setBluetoothServiceClassId(
+      MakeGarbageCollected<V8UnionStringOrUnsignedLong>("invalid-uuid"));
+
+  mojom::blink::SerialPortFilterPtr mojo_filter =
+      Serial::CreateMojoFilter(js_filter, scope.GetExceptionState());
+  EXPECT_FALSE(mojo_filter);
+  EXPECT_TRUE(scope.GetExceptionState().HadException());
+  EXPECT_EQ(ToExceptionCode(ESErrorType::kTypeError),
+            scope.GetExceptionState().Code());
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/OWNERS b/third_party/blink/renderer/modules/webaudio/OWNERS
index a7db251..32f919a5 100644
--- a/third_party/blink/renderer/modules/webaudio/OWNERS
+++ b/third_party/blink/renderer/modules/webaudio/OWNERS
@@ -1,3 +1,4 @@
 hongchan@chromium.org
 mjwilson@chromium.org
-alvinji@chromium.org
\ No newline at end of file
+alvinji@chromium.org
+sinafirooz@chromium.org
\ No newline at end of file
diff --git a/third_party/blink/renderer/modules/webaudio/audio_listener.cc b/third_party/blink/renderer/modules/webaudio/audio_listener.cc
index f9c6540..81b1f7f 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_listener.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_listener.cc
@@ -131,38 +131,35 @@
   // Initialize the cached values with the current values.  Thus, we don't need
   // to notify any panners because we haved moved.
   last_position_ = GetPosition();
-  last_forward_ = Orientation();
-  last_up_ = UpVector();
+  last_forward_ = GetOrientation();
+  last_up_ = GetUpVector();
 }
 
-AudioListener::~AudioListener() = default;
-
 void AudioListener::Trace(Visitor* visitor) const {
   visitor->Trace(position_x_);
   visitor->Trace(position_y_);
   visitor->Trace(position_z_);
-
   visitor->Trace(forward_x_);
   visitor->Trace(forward_y_);
   visitor->Trace(forward_z_);
-
   visitor->Trace(up_x_);
   visitor->Trace(up_y_);
   visitor->Trace(up_z_);
-
   InspectorHelperMixin::Trace(visitor);
   ScriptWrappable::Trace(visitor);
 }
 
-void AudioListener::AddPanner(PannerHandler& panner) {
+void AudioListener::AddPannerHandler(PannerHandler& panner_handler) {
   DCHECK(IsMainThread());
-  panners_.insert(&panner);
+
+  panner_handlers_.insert(&panner_handler);
 }
 
-void AudioListener::RemovePanner(PannerHandler& panner) {
+void AudioListener::RemovePannerHandler(PannerHandler& panner_handler) {
   DCHECK(IsMainThread());
-  DCHECK(panners_.Contains(&panner));
-  panners_.erase(&panner);
+
+  DCHECK(panner_handlers_.Contains(&panner_handler));
+  panner_handlers_.erase(&panner_handler);
 }
 
 bool AudioListener::HasSampleAccurateValues() const {
@@ -184,7 +181,8 @@
          forwardX()->Handler().IsAudioRate() ||
          forwardY()->Handler().IsAudioRate() ||
          forwardZ()->Handler().IsAudioRate() ||
-         upX()->Handler().IsAudioRate() || upY()->Handler().IsAudioRate() ||
+         upX()->Handler().IsAudioRate() ||
+         upY()->Handler().IsAudioRate() ||
          upZ()->Handler().IsAudioRate();
 }
 
@@ -192,7 +190,7 @@
   double current_time =
       positionX()->Handler().DestinationHandler().CurrentTime();
   if (last_update_time_ != current_time) {
-    // Time has changed. Update all of the automation values now.
+    // The time has passed. Update all of the automation values.
     last_update_time_ = current_time;
 
     DCHECK_LE(frames_to_process, position_x_values_.size());
@@ -211,20 +209,18 @@
         position_y_values_.Data(), frames_to_process);
     positionZ()->Handler().CalculateSampleAccurateValues(
         position_z_values_.Data(), frames_to_process);
-
     forwardX()->Handler().CalculateSampleAccurateValues(
         forward_x_values_.Data(), frames_to_process);
     forwardY()->Handler().CalculateSampleAccurateValues(
         forward_y_values_.Data(), frames_to_process);
     forwardZ()->Handler().CalculateSampleAccurateValues(
         forward_z_values_.Data(), frames_to_process);
-
-    upX()->Handler().CalculateSampleAccurateValues(up_x_values_.Data(),
-                                                   frames_to_process);
-    upY()->Handler().CalculateSampleAccurateValues(up_y_values_.Data(),
-                                                   frames_to_process);
-    upZ()->Handler().CalculateSampleAccurateValues(up_z_values_.Data(),
-                                                   frames_to_process);
+    upX()->Handler().CalculateSampleAccurateValues(
+        up_x_values_.Data(), frames_to_process);
+    upY()->Handler().CalculateSampleAccurateValues(
+        up_y_values_.Data(), frames_to_process);
+    upZ()->Handler().CalculateSampleAccurateValues(
+        up_z_values_.Data(), frames_to_process);
   }
 }
 
@@ -282,8 +278,8 @@
   const base::AutoTryLock try_locker(listener_lock_);
   if (try_locker.is_acquired()) {
     const gfx::Point3F current_position = GetPosition();
-    const gfx::Vector3dF current_forward = Orientation();
-    const gfx::Vector3dF current_up = UpVector();
+    const gfx::Vector3dF current_forward = GetOrientation();
+    const gfx::Vector3dF current_up = GetUpVector();
 
     is_listener_dirty_ = current_position != last_position_ ||
                          current_forward != last_forward_ ||
@@ -295,9 +291,9 @@
       last_up_ = current_up;
     }
   } else {
-    // Main thread must be updating the position, forward, or up vector;
-    // just assume the listener is dirty.  At worst, we'll do a little more
-    // work than necessary for one rendering quantum.
+    // The main thread must be updating the position, the forward, or the up
+    // vector; assume the listener is dirty.  At worst, we'll do a little more
+    // work than necessary for one render quantum.
     is_listener_dirty_ = true;
   }
 }
@@ -311,10 +307,6 @@
   }
 }
 
-bool AudioListener::IsHRTFDatabaseLoaded() {
-  return hrtf_database_loader_ && hrtf_database_loader_->IsLoaded();
-}
-
 void AudioListener::WaitForHRTFDatabaseLoaderThreadCompletion() {
   if (hrtf_database_loader_) {
     hrtf_database_loader_->WaitForLoaderThreadCompletion();
@@ -323,12 +315,13 @@
 
 void AudioListener::MarkPannersAsDirty(unsigned type) {
   DCHECK(IsMainThread());
-  for (PannerHandler* panner : panners_) {
-    panner->MarkPannerAsDirty(type);
+
+  for (PannerHandler* panner_handler : panner_handlers_) {
+    panner_handler->MarkPannerAsDirty(type);
   }
 }
 
-void AudioListener::setPosition(const gfx::Point3F& position,
+void AudioListener::SetPosition(const gfx::Point3F& position,
                                 ExceptionState& exceptionState) {
   DCHECK(IsMainThread());
 
@@ -345,7 +338,7 @@
                      PannerHandler::kDistanceConeGainDirty);
 }
 
-void AudioListener::setOrientation(const gfx::Vector3dF& orientation,
+void AudioListener::SetOrientation(const gfx::Vector3dF& orientation,
                                    ExceptionState& exceptionState) {
   DCHECK(IsMainThread());
 
diff --git a/third_party/blink/renderer/modules/webaudio/audio_listener.h b/third_party/blink/renderer/modules/webaudio/audio_listener.h
index e6433880..d6a259f 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_listener.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_listener.h
@@ -41,96 +41,87 @@
 class HRTFDatabaseLoader;
 class PannerHandler;
 
-// AudioListener maintains the state of the listener in the audio scene as
-// defined in the OpenAL specification.
-
-class AudioListener : public ScriptWrappable, public InspectorHelperMixin {
+// This interface represents the position and orientation of the person
+// listening to the audio scene. All PannerNode objects spatialize in relation
+// to the BaseAudioContext's listener.
+//
+// Spec: https://www.w3.org/TR/webaudio/#AudioListener
+class AudioListener final : public ScriptWrappable,
+                            public InspectorHelperMixin {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
   explicit AudioListener(BaseAudioContext&);
-  ~AudioListener() override;
+  ~AudioListener() final = default;
 
-  // Location of the listener
+  // https://www.w3.org/TR/webaudio/#AudioListener-attributes
   AudioParam* positionX() const { return position_x_; }
   AudioParam* positionY() const { return position_y_; }
   AudioParam* positionZ() const { return position_z_; }
-
-  // Forward direction vector of the listener
   AudioParam* forwardX() const { return forward_x_; }
   AudioParam* forwardY() const { return forward_y_; }
   AudioParam* forwardZ() const { return forward_z_; }
-
-  // Up direction vector for the listener
   AudioParam* upX() const { return up_x_; }
   AudioParam* upY() const { return up_y_; }
   AudioParam* upZ() const { return up_z_; }
 
-  // True if any of AudioParams have automations.
-  bool HasSampleAccurateValues() const;
-
-  // True if any of the AudioParams are set for a-rate automations
-  // (the default).
-  bool IsAudioRate() const;
-
-  // Update the internal state of the listener, including updating the dirty
-  // state of all PannerNodes if necessary.
-  void UpdateState();
-
-  bool IsListenerDirty() const { return is_listener_dirty_; }
+  // https://www.w3.org/TR/webaudio/#AudioListener-methods
+  void setOrientation(float x, float y, float z,
+                      float up_x, float up_y, float up_z,
+                      ExceptionState& exceptionState) {
+    SetOrientation(gfx::Vector3dF(x, y, z), exceptionState);
+    SetUpVector(gfx::Vector3dF(up_x, up_y, up_z), exceptionState);
+  }
+  void setPosition(float x, float y, float z, ExceptionState& exceptionState) {
+    SetPosition(gfx::Point3F(x, y, z), exceptionState);
+  }
 
   const gfx::Point3F GetPosition() const {
-    return gfx::Point3F(position_x_->value(), position_y_->value(),
-                        position_z_->value());
+    return gfx::Point3F(
+        position_x_->value(), position_y_->value(), position_z_->value());
   }
-  const gfx::Vector3dF Orientation() const {
-    return gfx::Vector3dF(forward_x_->value(), forward_y_->value(),
-                          forward_z_->value());
+
+  const gfx::Vector3dF GetOrientation() const {
+    return gfx::Vector3dF(
+        forward_x_->value(), forward_y_->value(), forward_z_->value());
   }
-  const gfx::Vector3dF UpVector() const {
+
+  const gfx::Vector3dF GetUpVector() const {
     return gfx::Vector3dF(up_x_->value(), up_y_->value(), up_z_->value());
   }
 
   const float* GetPositionXValues(uint32_t frames_to_process);
   const float* GetPositionYValues(uint32_t frames_to_process);
   const float* GetPositionZValues(uint32_t frames_to_process);
-
   const float* GetForwardXValues(uint32_t frames_to_process);
   const float* GetForwardYValues(uint32_t frames_to_process);
   const float* GetForwardZValues(uint32_t frames_to_process);
-
   const float* GetUpXValues(uint32_t frames_to_process);
   const float* GetUpYValues(uint32_t frames_to_process);
   const float* GetUpZValues(uint32_t frames_to_process);
 
-  // Position
-  void setPosition(float x, float y, float z, ExceptionState& exceptionState) {
-    setPosition(gfx::Point3F(x, y, z), exceptionState);
-  }
+  // True if any of AudioParams have automations.
+  bool HasSampleAccurateValues() const;
 
-  // Orientation and Up-vector
-  void setOrientation(float x,
-                      float y,
-                      float z,
-                      float up_x,
-                      float up_y,
-                      float up_z,
-                      ExceptionState& exceptionState) {
-    setOrientation(gfx::Vector3dF(x, y, z), exceptionState);
-    SetUpVector(gfx::Vector3dF(up_x, up_y, up_z), exceptionState);
-  }
+  // True if any of AudioParams are set for a-rate automations (the default).
+  bool IsAudioRate() const;
+
+  // Updates the internal state of the listener, including updating the dirty
+  // state of all PannerNodes if necessary.
+  void UpdateState();
+
+  bool IsListenerDirty() const { return is_listener_dirty_; }
 
   base::Lock& ListenerLock() { return listener_lock_; }
-  void AddPanner(PannerHandler&);
-  void RemovePanner(PannerHandler&);
 
-  // HRTF DB loader
+  void AddPannerHandler(PannerHandler&);
+  void RemovePannerHandler(PannerHandler&);
+
+  void CreateAndLoadHRTFDatabaseLoader(float);
+  void WaitForHRTFDatabaseLoaderThreadCompletion();
   HRTFDatabaseLoader* HrtfDatabaseLoader() {
     return hrtf_database_loader_.get();
   }
-  void CreateAndLoadHRTFDatabaseLoader(float);
-  bool IsHRTFDatabaseLoaded();
-  void WaitForHRTFDatabaseLoaderThreadCompletion();
 
   // InspectorHelperMixin: Note that this object belongs to a BaseAudioContext,
   // so these methods get called by the parent context.
@@ -140,28 +131,34 @@
   void Trace(Visitor*) const override;
 
  private:
-  void setPosition(const gfx::Point3F&, ExceptionState&);
-  void setOrientation(const gfx::Vector3dF&, ExceptionState&);
-  void SetUpVector(const gfx::Vector3dF&, ExceptionState&);
-
+  void UpdateValuesIfNeeded(uint32_t frames_to_process);
   void MarkPannersAsDirty(unsigned) EXCLUSIVE_LOCKS_REQUIRED(listener_lock_);
 
-  // Location of the listener
+  void SetPosition(const gfx::Point3F&, ExceptionState&);
+  void SetOrientation(const gfx::Vector3dF&, ExceptionState&);
+  void SetUpVector(const gfx::Vector3dF&, ExceptionState&);
+
   Member<AudioParam> position_x_;
   Member<AudioParam> position_y_;
   Member<AudioParam> position_z_;
-
-  // Forward direction vector of the listener
   Member<AudioParam> forward_x_;
   Member<AudioParam> forward_y_;
   Member<AudioParam> forward_z_;
-
-  // Up direction vector for the listener
   Member<AudioParam> up_x_;
   Member<AudioParam> up_y_;
   Member<AudioParam> up_z_;
 
-  // The position, forward, and up vectors from the last rendering quantum.
+  AudioFloatArray position_x_values_;
+  AudioFloatArray position_y_values_;
+  AudioFloatArray position_z_values_;
+  AudioFloatArray forward_x_values_;
+  AudioFloatArray forward_y_values_;
+  AudioFloatArray forward_z_values_;
+  AudioFloatArray up_x_values_;
+  AudioFloatArray up_y_values_;
+  AudioFloatArray up_z_values_;
+
+  // Parameters from the last render quantum.
   gfx::Point3F last_position_ GUARDED_BY(listener_lock_);
   gfx::Vector3dF last_forward_ GUARDED_BY(listener_lock_);
   gfx::Vector3dF last_up_ GUARDED_BY(listener_lock_);
@@ -169,33 +166,21 @@
   // Last time that the automations were updated.
   double last_update_time_ = -1;
 
-  // Set every rendering quantum if the listener has moved in any way
-  // (position, forward, or up).  This should only be read or written to from
+  // Set at every render quantum if the listener has changed in any way
+  // (position, forward, or up). This should only be read or written to from
   // the audio thread.
   bool is_listener_dirty_ = false;
 
-  void UpdateValuesIfNeeded(uint32_t frames_to_process);
-
-  AudioFloatArray position_x_values_;
-  AudioFloatArray position_y_values_;
-  AudioFloatArray position_z_values_;
-
-  AudioFloatArray forward_x_values_;
-  AudioFloatArray forward_y_values_;
-  AudioFloatArray forward_z_values_;
-
-  AudioFloatArray up_x_values_;
-  AudioFloatArray up_y_values_;
-  AudioFloatArray up_z_values_;
-
-  // Synchronize a panner's process() with setting of the state of the listener.
+  // To synchronize settings of the state of the listener during
+  // `PannerHandler::Process()` and related functions.
   mutable base::Lock listener_lock_;
-  // List for pannerNodes in context. This is updated only in the main thread,
-  // and can be referred in audio thread.
-  // These raw pointers are safe because PannerHandler::uninitialize()
-  // unregisters it from m_panners.
-  HashSet<PannerHandler*> panners_;
-  // HRTF DB loader for panner node.
+
+  // A set of PannerHandlers. This is updated only in the main thread and is
+  // referred in the audio thread. These raw pointers are safe because
+  // `PannerHandler::uninitialize()` unregisters it from this set.
+  HashSet<PannerHandler*> panner_handlers_;
+
+  // HRTF database loader used by PannderNodes in the same context.
   scoped_refptr<HRTFDatabaseLoader> hrtf_database_loader_;
 };
 
diff --git a/third_party/blink/renderer/modules/webaudio/panner_handler.cc b/third_party/blink/renderer/modules/webaudio/panner_handler.cc
index 28d713b..9620483 100644
--- a/third_party/blink/renderer/modules/webaudio/panner_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/panner_handler.cc
@@ -320,7 +320,7 @@
   panner_ = Panner::Create(panning_model_, Context()->sampleRate(),
                            GetDeferredTaskHandler().RenderQuantumFrames(),
                            listener->HrtfDatabaseLoader());
-  listener->AddPanner(*this);
+  listener->AddPannerHandler(*this);
 
   // The panner is already marked as dirty, so `last_position_` and
   // `last_orientation_` will be updated on first use.  Don't need to
@@ -339,7 +339,7 @@
   if (listener) {
     // Listener may have gone in the same garbage collection cycle, which means
     // that the panner does not need to be removed.
-    listener->RemovePanner(*this);
+    listener->RemovePannerHandler(*this);
   }
 
   AudioHandler::Uninitialize();
@@ -637,9 +637,10 @@
   // Calculate new azimuth and elevation if the panner or the listener changed
   // position or orientation in any way.
   if (IsAzimuthElevationDirty() || listener->IsListenerDirty()) {
-    CalculateAzimuthElevation(&cached_azimuth_, &cached_elevation_,
-                              GetPosition(), listener->GetPosition(),
-                              listener->Orientation(), listener->UpVector());
+    CalculateAzimuthElevation(
+        &cached_azimuth_, &cached_elevation_, GetPosition(),
+        listener->GetPosition(), listener->GetOrientation(),
+        listener->GetUpVector());
     is_azimuth_elevation_dirty_ = false;
   }
 
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto b/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto
index 28e8c6a..158ddaf 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto
@@ -88,6 +88,29 @@
     DENY = 1;
     REQUIRE = 2;
   }
+
+  enum ScalabilityMode {
+    L1T1 = 0;
+    L1T2 = 1;
+    L1T3 = 2;
+  }
+
+  enum LatencyMode {
+    QUALITY = 0;
+    REALTIME = 1;
+  }
+
+  enum VideoEncoderBitrateMode {
+    CONSTANT = 0;
+    VARIABLE = 1;
+    QUANTIZER = 2;
+  }
+
+  enum AlphaOption {
+    KEEP = 0;
+    DISCARD = 1;
+  }
+
   optional EncoderAccelerationPreference acceleration = 2;
 
   optional uint64 bitrate = 3;
@@ -97,6 +120,18 @@
   optional uint32 width = 5;
 
   optional uint32 height = 6;
+
+  optional uint32 display_width = 7;
+
+  optional uint32 display_height = 8;
+
+  optional ScalabilityMode scalability_mode = 9;
+
+  optional VideoEncoderBitrateMode bitrate_mode = 10;
+
+  optional LatencyMode latency_mode = 11;
+
+  optional AlphaOption alpha = 12;
 }
 
 message ConfigureAudioDecoder {
@@ -193,7 +228,17 @@
 
 message EncodeVideo {
   optional VideoFrameBitmapInit frame = 1;
-  message EncodeOptions { optional bool key_frame = 1; }
+  message EncodeOptionsForAv1 {
+    optional uint32 quantizer = 1;
+  };
+  message EncodeOptionsForVp9 {
+    optional uint32 quantizer = 1;
+  };
+  message EncodeOptions {
+    optional bool key_frame = 1;
+    optional EncodeOptionsForAv1 av1 = 2;
+    optional EncodeOptionsForVp9 vp9 = 3;
+  }
   optional EncodeOptions options = 2;
 }
 
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_av1.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_av1.textproto
index 0043bf0..2c3f09d 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_av1.textproto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_av1.textproto
@@ -15,7 +15,13 @@
       bitrate: 1500000,
       framerate: 25,
       width: 200,
-      height: 50
+      height: 50,
+      display_width: 200,
+      display_height: 50,
+      bitrate_mode: CONSTANT,
+      scalability_mode: L1T2,
+      alpha: DISCARD,
+      latency_mode: REALTIME
     }
   },
   {
@@ -42,6 +48,9 @@
       },
       options {
         key_frame: true,
+        av1 {
+          quantizer: 30
+        }
       }
     }
   },
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_h264.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_h264.textproto
index 45bfc23f..2b6accdc 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_h264.textproto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_h264.textproto
@@ -15,7 +15,14 @@
       bitrate: 1500000,
       framerate: 25,
       width: 200,
-      height: 50
+      height: 50,
+      display_width: 200,
+      display_height: 50,
+      bitrate_mode: CONSTANT,
+      scalability_mode: L1T3,
+      alpha: DISCARD,
+      latency_mode: QUALITY
+
     }
   },
   {
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp8.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp8.textproto
index 7bfde87..0949923 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp8.textproto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp8.textproto
@@ -15,7 +15,13 @@
       bitrate: 1500000,
       framerate: 25,
       width: 200,
-      height: 50
+      height: 50,
+      display_width: 200,
+      display_height: 50,
+      bitrate_mode: VARIABLE,
+      scalability_mode: L1T3,
+      alpha: DISCARD,
+      latency_mode: QUALITY
     }
   },
   {
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp9.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp9.textproto
index 334d3f5..aa6158c 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp9.textproto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp9.textproto
@@ -15,7 +15,13 @@
       bitrate: 1500000,
       framerate: 25,
       width: 200,
-      height: 50
+      height: 50,
+      display_width: 200,
+      display_height: 50,
+      bitrate_mode: VARIABLE,
+      scalability_mode: L1T1,
+      alpha: KEEP,
+      latency_mode: QUALITY
     }
   },
   {
@@ -42,6 +48,9 @@
       },
       options {
         key_frame: true,
+        vp9 {
+          quantizer: 35
+        }
       }
     }
   },
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
index c269043..a48dfcc8 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
@@ -25,6 +25,8 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_config.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options_for_av_1.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options_for_vp_9.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_buffer_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_init.h"
 #include "third_party/blink/renderer/core/html/canvas/image_data.h"
@@ -109,6 +111,21 @@
   config->setFramerate(proto.framerate());
   config->setWidth(proto.width());
   config->setHeight(proto.height());
+  config->setDisplayWidth(proto.display_width());
+  config->setDisplayHeight(proto.display_height());
+
+  if (proto.has_alpha()) {
+    config->setAlpha(ToAlphaOption(proto.alpha()));
+  }
+  if (proto.has_bitrate_mode()) {
+    config->setBitrateMode(ToBitrateMode(proto.bitrate_mode()));
+  }
+  if (proto.has_scalability_mode()) {
+    config->setScalabilityMode(ToScalabilityMode(proto.scalability_mode()));
+  }
+  if (proto.has_latency_mode()) {
+    config->setLatencyMode(ToLatencyMode(proto.latency_mode()));
+  }
 
   // Bitrate is truly optional, so don't just take the proto default value.
   if (proto.has_bitrate())
@@ -148,6 +165,48 @@
   }
 }
 
+String ToBitrateMode(
+    wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode mode) {
+  switch (mode) {
+    case wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode_CONSTANT:
+      return "constant";
+    case wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode_VARIABLE:
+      return "variable";
+    case wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode_QUANTIZER:
+      return "quantizer";
+  }
+}
+
+String ToScalabilityMode(
+    wc_fuzzer::ConfigureVideoEncoder_ScalabilityMode mode) {
+  switch (mode) {
+    case wc_fuzzer::ConfigureVideoEncoder_ScalabilityMode_L1T1:
+      return "L1T1";
+    case wc_fuzzer::ConfigureVideoEncoder_ScalabilityMode_L1T2:
+      return "L1T2";
+    case wc_fuzzer::ConfigureVideoEncoder_ScalabilityMode_L1T3:
+      return "L1T3";
+  }
+}
+
+String ToLatencyMode(wc_fuzzer::ConfigureVideoEncoder_LatencyMode mode) {
+  switch (mode) {
+    case wc_fuzzer::ConfigureVideoEncoder_LatencyMode_QUALITY:
+      return "quality";
+    case wc_fuzzer::ConfigureVideoEncoder_LatencyMode_REALTIME:
+      return "realtime";
+  }
+}
+
+String ToAlphaOption(wc_fuzzer::ConfigureVideoEncoder_AlphaOption option) {
+  switch (option) {
+    case wc_fuzzer::ConfigureVideoEncoder_AlphaOption_KEEP:
+      return "keep";
+    case wc_fuzzer::ConfigureVideoEncoder_AlphaOption_DISCARD:
+      return "discard";
+  }
+}
+
 String ToAacFormat(wc_fuzzer::AacFormat format) {
   switch (format) {
     case wc_fuzzer::AAC:
@@ -247,6 +306,18 @@
   if (proto.has_key_frame())
     options->setKeyFrame(proto.key_frame());
 
+  if (proto.has_av1() && proto.av1().has_quantizer()) {
+    auto* av1 = VideoEncoderEncodeOptionsForAv1::Create();
+    av1->setQuantizer(proto.av1().quantizer());
+    options->setAv1(av1);
+  }
+
+  if (proto.has_vp9() && proto.vp9().has_quantizer()) {
+    auto* vp9 = VideoEncoderEncodeOptionsForVp9::Create();
+    vp9->setQuantizer(proto.vp9().quantizer());
+    options->setVp9(vp9);
+  }
+
   return options;
 }
 
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
index e53e5b0..a630bf4 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
@@ -85,6 +85,15 @@
 VideoEncoderEncodeOptions* MakeEncodeOptions(
     const wc_fuzzer::EncodeVideo_EncodeOptions& proto);
 
+String ToBitrateMode(
+    wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode mode);
+
+String ToScalabilityMode(wc_fuzzer::ConfigureVideoEncoder_ScalabilityMode mode);
+
+String ToLatencyMode(wc_fuzzer::ConfigureVideoEncoder_LatencyMode mode);
+
+String ToAlphaOption(wc_fuzzer::ConfigureVideoEncoder_AlphaOption option);
+
 String ToAacFormat(wc_fuzzer::AacFormat format);
 
 String ToAccelerationType(
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index a624fc22..d152d64 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -962,6 +962,11 @@
                      request->encodeOpts->keyFrameNonNull();
   switch (active_config_->codec) {
     case media::VideoCodec::kAV1: {
+      if (!active_config_->options.bitrate.has_value() ||
+          active_config_->options.bitrate->mode() !=
+              media::Bitrate::Mode::kExternal) {
+        break;
+      }
       if (!request->encodeOpts->hasAv1() ||
           !request->encodeOpts->av1()->hasQuantizer()) {
         break;
@@ -970,6 +975,11 @@
       break;
     }
     case media::VideoCodec::kVP9: {
+      if (!active_config_->options.bitrate.has_value() ||
+          active_config_->options.bitrate->mode() !=
+              media::Bitrate::Mode::kExternal) {
+        break;
+      }
       if (!request->encodeOpts->hasVp9() ||
           !request->encodeOpts->vp9()->hasQuantizer()) {
         break;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
index 5e39c676..15f19df5 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -17,6 +17,7 @@
 #include "third_party/blink/renderer/modules/webgpu/gpu.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_adapter_info.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_supported_features.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h"
 #include "third_party/blink/renderer/modules/webgpu/string_utils.h"
@@ -168,13 +169,16 @@
     case WGPURequestDeviceStatus_Success: {
       DCHECK(dawn_device);
 
+      GPUDeviceLostInfo* device_lost_info = nullptr;
       if (is_consumed_) {
-        resolver->Reject(MakeGarbageCollected<DOMException>(
-            DOMExceptionCode::kInvalidStateError,
-            "The adapter is invalid because it has already been used to create "
-            "a device. NOTE: The behavior in this error case may change in a "
-            "future release."));
-        break;
+        // Immediately force the device to be lost.
+        // TODO: Ideally this should be handled in Dawn, which can return an
+        // error device.
+        device_lost_info = MakeGarbageCollected<GPUDeviceLostInfo>(
+            WGPUDeviceLostReason_Undefined,
+            StringFromASCIIAndUTF8(
+                "The adapter is invalid because it has already been used to "
+                "create a device. A lost device has been returned."));
       }
       is_consumed_ = true;
 
@@ -182,7 +186,15 @@
           ExecutionContext::From(script_state);
       auto* device = MakeGarbageCollected<GPUDevice>(
           execution_context, GetDawnControlClient(), this, dawn_device,
-          descriptor);
+          descriptor, device_lost_info);
+
+      if (device_lost_info) {
+        // Ensure the Dawn device is marked as lost as well.
+        device->InjectError(
+            WGPUErrorType_DeviceLost,
+            "Device was marked as lost due to a stale adapter.");
+      }
+
       resolver->Resolve(device);
 
       ukm::builders::ClientRenderingAPI(execution_context->UkmSourceID())
@@ -193,10 +205,26 @@
 
     case WGPURequestDeviceStatus_Error:
     case WGPURequestDeviceStatus_Unknown:
-      DCHECK_EQ(dawn_device, nullptr);
-      resolver->Reject(MakeGarbageCollected<DOMException>(
-          DOMExceptionCode::kOperationError,
-          StringFromASCIIAndUTF8(error_message)));
+      if (dawn_device) {
+        // Immediately force the device to be lost.
+        auto* device_lost_info = MakeGarbageCollected<GPUDeviceLostInfo>(
+            WGPUDeviceLostReason_Undefined,
+            StringFromASCIIAndUTF8(error_message));
+        ExecutionContext* execution_context =
+            ExecutionContext::From(script_state);
+        auto* device = MakeGarbageCollected<GPUDevice>(
+            execution_context, GetDawnControlClient(), this, dawn_device,
+            descriptor, device_lost_info);
+        // Resolve with the lost device.
+        resolver->Resolve(device);
+      } else {
+        // If a device is not returned, that means that an error occurred while
+        // validating features or limits, and as a result the promise should be
+        // rejected with an OperationError.
+        resolver->Reject(MakeGarbageCollected<DOMException>(
+            DOMExceptionCode::kOperationError,
+            StringFromASCIIAndUTF8(error_message)));
+      }
       break;
     default:
       NOTREACHED();
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
index d71d68d..073728e 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -125,7 +125,8 @@
                      scoped_refptr<DawnControlClientHolder> dawn_control_client,
                      GPUAdapter* adapter,
                      WGPUDevice dawn_device,
-                     const GPUDeviceDescriptor* descriptor)
+                     const GPUDeviceDescriptor* descriptor,
+                     GPUDeviceLostInfo* lost_info)
     : ExecutionContextClient(execution_context),
       DawnObject(dawn_control_client, dawn_device),
       adapter_(adapter),
@@ -170,6 +171,12 @@
     queue_->setLabel(descriptor->defaultQueue()->label());
 
   external_texture_cache_ = MakeGarbageCollected<ExternalTextureCache>(this);
+
+  // If lost_info is supplied it means the device should be treated as being
+  // lost at creation time.
+  if (lost_info) {
+    lost_property_->Resolve(lost_info);
+  }
 }
 
 GPUDevice::~GPUDevice() {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.h b/third_party/blink/renderer/modules/webgpu/gpu_device.h
index 9c465b8..500ea2e8 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -79,7 +79,8 @@
                      scoped_refptr<DawnControlClientHolder> dawn_control_client,
                      GPUAdapter* adapter,
                      WGPUDevice dawn_device,
-                     const GPUDeviceDescriptor* descriptor);
+                     const GPUDeviceDescriptor* descriptor,
+                     GPUDeviceLostInfo* lost_info = nullptr);
 
   GPUDevice(const GPUDevice&) = delete;
   GPUDevice& operator=(const GPUDevice&) = delete;
diff --git a/third_party/blink/renderer/platform/audio/OWNERS b/third_party/blink/renderer/platform/audio/OWNERS
index a7db251..32f919a5 100644
--- a/third_party/blink/renderer/platform/audio/OWNERS
+++ b/third_party/blink/renderer/platform/audio/OWNERS
@@ -1,3 +1,4 @@
 hongchan@chromium.org
 mjwilson@chromium.org
-alvinji@chromium.org
\ No newline at end of file
+alvinji@chromium.org
+sinafirooz@chromium.org
\ No newline at end of file
diff --git a/third_party/blink/renderer/platform/blob/blob_data.cc b/third_party/blink/renderer/platform/blob/blob_data.cc
index 1734e47e..b917c313 100644
--- a/third_party/blink/renderer/platform/blob/blob_data.cc
+++ b/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -170,8 +170,10 @@
                           int64_t length) {
   DCHECK_EQ(file_composition_, FileCompositionStatus::kNoUnknownSizeFiles)
       << "Blobs with a unknown-size file cannot have other items.";
-  DCHECK(!data_handle->IsSingleUnknownSizeFile())
-      << "It is illegal to append an unknown size file blob.";
+  DCHECK(!data_handle->IsSingleUnknownSizeFile() ||
+         length != BlobData::kToEndOfFile)
+      << "It is illegal to append an unknown size file blob without specifying "
+         "a size.";
   // Skip zero-byte items, as they don't matter for the contents of the blob.
   if (length == 0)
     return;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
index 411b22f..22bb242 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -600,6 +600,14 @@
     attribution_reporting_runtime_features_ = runtime_features;
   }
 
+  bool SharedDictionaryWriterEnabled() const {
+    return shared_dictionary_writer_enabled_;
+  }
+
+  void SetSharedDictionaryWriterEnabled(bool shared_dictionary_writer_enabled) {
+    shared_dictionary_writer_enabled_ = shared_dictionary_writer_enabled;
+  }
+
  private:
   const CacheControlHeader& GetCacheControlHeader() const;
 
@@ -731,6 +739,12 @@
 
   network::AttributionReportingRuntimeFeatures
       attribution_reporting_runtime_features_;
+
+  // Indicate the state of CompressionDictionaryTransport feature. When it is
+  // true, `use-as-dictionary` response HTTP header may be processed.
+  // TODO(crbug.com/1413922): Remove this flag when we launch
+  // CompressionDictionaryTransport feature.
+  bool shared_dictionary_writer_enabled_ = false;
 };
 
 class PLATFORM_EXPORT ResourceRequestBody {
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
index 76a72d2..769197b 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
@@ -412,6 +412,8 @@
 
   dest->attribution_reporting_runtime_features =
       src.GetAttributionReportingRuntimeFeatures();
+
+  dest->shared_dictionary_writer_enabled = src.SharedDictionaryWriterEnabled();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.h b/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
index f68089af..e75b545 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
@@ -36,7 +36,7 @@
 // value anymore and blink is allowed to use webrtc classes directly.
 class PLATFORM_EXPORT RTCStatsReportPlatform {
  public:
-  RTCStatsReportPlatform(
+  explicit RTCStatsReportPlatform(
       const scoped_refptr<const webrtc::RTCStatsReport>& stats_report);
   virtual ~RTCStatsReportPlatform();
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 1cb8f167..767d1a42 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -2067,7 +2067,7 @@
     },
     {
       name: "LayoutFlexNewColumnAlgorithm",
-      status: "test",
+      status: "stable",
     },
     {
       name: "LayoutFlexNewRowAlgorithm",
@@ -2563,6 +2563,15 @@
     // As above. Do not change this flag to stable, as it exists solely to
     // generate code used by the origin trials sample API implementation.
     {
+      name: "OriginTrialsSampleAPIPersistentInvalidOS",
+      base_feature: "none",
+      origin_trial_feature_name: "FrobulatePersistentInvalidOS",
+      origin_trial_allows_third_party: true,
+      origin_trial_os: ["invalid"],
+    },
+    // As above. Do not change this flag to stable, as it exists solely to
+    // generate code used by the origin trials sample API implementation.
+    {
       name: "OriginTrialsSampleAPIPersistentThirdPartyDeprecationFeature",
       base_feature: "none",
       origin_trial_feature_name: "FrobulatePersistentThirdPartyDeprecation",
@@ -3073,6 +3082,10 @@
       base_feature: "none",
     },
     {
+      name: "ScrollbarColor",
+      status: "experimental",
+    },
+    {
       name: "ScrollbarWidth",
       status: "experimental",
       base_feature: "none",
diff --git a/third_party/blink/renderer/platform/widget/input/event_with_callback.cc b/third_party/blink/renderer/platform/widget/input/event_with_callback.cc
index cb1eee76..90cfec1 100644
--- a/third_party/blink/renderer/platform/widget/input/event_with_callback.cc
+++ b/third_party/blink/renderer/platform/widget/input/event_with_callback.cc
@@ -150,6 +150,12 @@
   return std::move(first->metrics_);
 }
 
+void EventWithCallback::SwapCallback(
+    InputHandlerProxy::EventDispositionCallback& new_callback) {
+  DCHECK(original_events_.size());
+  std::swap(original_events_.front().callback_, new_callback);
+}
+
 void EventWithCallback::WillStartProcessingForMetrics() {
   DCHECK(metrics());
   for (auto& original_event : original_events_) {
diff --git a/third_party/blink/renderer/platform/widget/input/event_with_callback.h b/third_party/blink/renderer/platform/widget/input/event_with_callback.h
index fe706ccd..3a5e6fb 100644
--- a/third_party/blink/renderer/platform/widget/input/event_with_callback.h
+++ b/third_party/blink/renderer/platform/widget/input/event_with_callback.h
@@ -89,6 +89,8 @@
   // for latency reporting purposes.
   std::unique_ptr<cc::EventMetrics> TakeMetrics();
 
+  void SwapCallback(InputHandlerProxy::EventDispositionCallback& new_callback);
+
   // Called when the compositor thread starts/finishes processing the event so
   // that the metrics can be updated with the appropriate timestamp. These are
   // only called if the event has metrics.
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
index e819e15..79db1caa 100644
--- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
+++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
@@ -209,6 +209,61 @@
   }
 }
 
+// The net effect of this class is to postpone invoking the callback for an
+// event until a subsequent generated event is finished processing. The callback
+// will be invoked with the disposition of the original event.
+class DelayedCallback {
+ public:
+  // base::Unretained because the callback will be invoked during processing of
+  // the original input event, which will happen before the synthetic gesture
+  // event (which owns this object) is processed.
+  explicit DelayedCallback(EventWithCallback* event_with_callback)
+      : callback_(base::BindOnce(&DelayedCallback::RecordEventDisposition,
+                                 base::Unretained(this))) {
+    event_with_callback->SwapCallback(callback_);
+  }
+
+  ~DelayedCallback() = default;
+
+  // base::Owned because the synthetic gesture event owns this object until it
+  // runs its callback, after which time this object should be freed.
+  InputHandlerProxy::EventDispositionCallback DerivedCallback() {
+    return base::BindOnce(&DelayedCallback::Invoke, base::Owned(this));
+  }
+
+ private:
+  // Will be called when the original input event is finished processing.
+  void RecordEventDisposition(
+      InputHandlerProxy::EventDisposition disposition,
+      std::unique_ptr<blink::WebCoalescedInputEvent> event,
+      std::unique_ptr<InputHandlerProxy::DidOverscrollParams> overscroll_params,
+      const blink::WebInputEventAttribution& attribution,
+      std::unique_ptr<cc::EventMetrics> metrics,
+      mojom::blink::ScrollResultDataPtr scroll_result) {
+    DCHECK(!callback_.is_null());
+    DCHECK(closure_.is_null());
+    closure_ =
+        base::BindOnce(std::move(callback_), disposition, std::move(event),
+                       std::move(overscroll_params), attribution,
+                       std::move(metrics), std::move(scroll_result));
+  }
+
+  // Will be called when the synthetic gesture event is finished processing.
+  void Invoke(InputHandlerProxy::EventDisposition,
+              std::unique_ptr<blink::WebCoalescedInputEvent>,
+              std::unique_ptr<InputHandlerProxy::DidOverscrollParams>,
+              const blink::WebInputEventAttribution&,
+              std::unique_ptr<cc::EventMetrics>,
+              mojom::blink::ScrollResultDataPtr) {
+    DCHECK(callback_.is_null());
+    DCHECK(!closure_.is_null());
+    std::move(closure_).Run();
+  }
+
+  InputHandlerProxy::EventDispositionCallback callback_;
+  base::OnceClosure closure_;
+};
+
 }  // namespace
 
 InputHandlerProxy::InputHandlerProxy(cc::InputHandler& input_handler,
@@ -572,7 +627,8 @@
     const cc::InputHandlerPointerResult& pointer_result,
     const ui::LatencyInfo& latency_info,
     const base::TimeTicks original_timestamp,
-    const cc::EventMetrics* original_metrics) {
+    const cc::EventMetrics* original_metrics,
+    InputHandlerProxy::EventDispositionCallback callback) {
   gfx::Vector2dF scroll_delta = pointer_result.scroll_delta;
 
   std::unique_ptr<WebGestureEvent> synthetic_gesture_event =
@@ -641,7 +697,7 @@
   auto gesture_event_with_callback_update = std::make_unique<EventWithCallback>(
       std::make_unique<WebCoalescedInputEvent>(
           std::move(synthetic_gesture_event), scrollbar_latency_info),
-      original_timestamp, base::DoNothing(), std::move(metrics));
+      original_timestamp, std::move(callback), std::move(metrics));
 
   bool needs_animate_input = compositor_event_queue_->empty();
   compositor_event_queue_->Queue(std::move(gesture_event_with_callback_update),
@@ -1664,16 +1720,18 @@
   InjectScrollbarGestureScroll(
       WebInputEvent::Type::kGestureScrollBegin, position, pointer_result,
       event_with_callback->latency_info(),
-      event_with_callback->event().TimeStamp(), event_with_callback->metrics());
+      event_with_callback->event().TimeStamp(), event_with_callback->metrics(),
+      base::DoNothing());
 
   // Don't need to inject GSU if the scroll offset is zero (this can be the case
   // where mouse down occurs on the thumb).
   if (!pointer_result.scroll_delta.IsZero()) {
-    InjectScrollbarGestureScroll(WebInputEvent::Type::kGestureScrollUpdate,
-                                 position, pointer_result,
-                                 event_with_callback->latency_info(),
-                                 event_with_callback->event().TimeStamp(),
-                                 event_with_callback->metrics());
+    auto* delayed_callback = new DelayedCallback(event_with_callback);
+    InjectScrollbarGestureScroll(
+        WebInputEvent::Type::kGestureScrollUpdate, position, pointer_result,
+        event_with_callback->latency_info(),
+        event_with_callback->event().TimeStamp(),
+        event_with_callback->metrics(), delayed_callback->DerivedCallback());
   }
 
   if (event_with_callback) {
@@ -1695,11 +1753,11 @@
     // right-click context menu).
     auto mouseup_result = input_handler_->MouseUp(position);
     if (mouseup_result.type == cc::PointerResultType::kScrollbarScroll) {
-      InjectScrollbarGestureScroll(WebInputEvent::Type::kGestureScrollEnd,
-                                   position, mouseup_result,
-                                   event_with_callback->latency_info(),
-                                   event_with_callback->event().TimeStamp(),
-                                   event_with_callback->metrics());
+      InjectScrollbarGestureScroll(
+          WebInputEvent::Type::kGestureScrollEnd, position, mouseup_result,
+          event_with_callback->latency_info(),
+          event_with_callback->event().TimeStamp(),
+          event_with_callback->metrics(), base::DoNothing());
     }
   }
 
@@ -1709,11 +1767,12 @@
     // Generate a GSU event and add it to the CompositorThreadEventQueue if
     // delta is non zero.
     if (!pointer_result.scroll_delta.IsZero()) {
-      InjectScrollbarGestureScroll(WebInputEvent::Type::kGestureScrollUpdate,
-                                   position, pointer_result,
-                                   event_with_callback->latency_info(),
-                                   event_with_callback->event().TimeStamp(),
-                                   event_with_callback->metrics());
+      auto* delayed_callback = new DelayedCallback(event_with_callback);
+      InjectScrollbarGestureScroll(
+          WebInputEvent::Type::kGestureScrollUpdate, position, pointer_result,
+          event_with_callback->latency_info(),
+          event_with_callback->event().TimeStamp(),
+          event_with_callback->metrics(), delayed_callback->DerivedCallback());
     }
     if (event_with_callback) {
       event_with_callback->SetScrollbarManipulationHandledOnCompositorThread();
@@ -1729,11 +1788,11 @@
       input_handler_->MouseUp(position);
   if (pointer_result.type == cc::PointerResultType::kScrollbarScroll) {
     // Generate a GSE and add it to the CompositorThreadEventQueue.
-    InjectScrollbarGestureScroll(WebInputEvent::Type::kGestureScrollEnd,
-                                 position, pointer_result,
-                                 event_with_callback->latency_info(),
-                                 event_with_callback->event().TimeStamp(),
-                                 event_with_callback->metrics());
+    InjectScrollbarGestureScroll(
+        WebInputEvent::Type::kGestureScrollEnd, position, pointer_result,
+        event_with_callback->latency_info(),
+        event_with_callback->event().TimeStamp(),
+        event_with_callback->metrics(), base::DoNothing());
     if (event_with_callback) {
       event_with_callback->SetScrollbarManipulationHandledOnCompositorThread();
     }
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h
index 4143ea1..a020ddb 100644
--- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h
+++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h
@@ -170,18 +170,6 @@
       EventDispositionCallback callback,
       cc::ElementId hit_tests_result);
 
-  // Handles creating synthetic gesture events. It is currently used for
-  // creating gesture event equivalents for mouse events on a composited
-  // scrollbar. `original_metrics` contains metrics for the original mouse event
-  // and is used to generated metrics for the new gesture event.
-  void InjectScrollbarGestureScroll(
-      const blink::WebInputEvent::Type type,
-      const gfx::PointF& position_in_widget,
-      const cc::InputHandlerPointerResult& pointer_result,
-      const ui::LatencyInfo& latency_info,
-      const base::TimeTicks now,
-      const cc::EventMetrics* original_metrics);
-
   // Attempts to perform attribution of the given WebInputEvent to a target
   // frame. Intended for simple impl-side hit testing.
   blink::WebInputEventAttribution PerformEventAttribution(
@@ -259,6 +247,19 @@
   void DispatchQueuedInputEvents(bool frame_aligned);
   void UpdateElasticOverscroll();
 
+  // Handles creating synthetic gesture events. It is currently used for
+  // creating gesture event equivalents for mouse events on a composited
+  // scrollbar. `original_metrics` contains metrics for the original mouse event
+  // and is used to generated metrics for the new gesture event.
+  void InjectScrollbarGestureScroll(
+      const blink::WebInputEvent::Type type,
+      const gfx::PointF& position_in_widget,
+      const cc::InputHandlerPointerResult& pointer_result,
+      const ui::LatencyInfo& latency_info,
+      const base::TimeTicks now,
+      const cc::EventMetrics* original_metrics,
+      InputHandlerProxy::EventDispositionCallback callback);
+
   // Helper functions for handling more complicated input events.
   EventDisposition HandleMouseWheel(const blink::WebMouseWheelEvent& event);
   EventDisposition HandleGestureScrollBegin(
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
index b06eab2f..191b161 100644
--- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
+++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
@@ -563,13 +563,23 @@
             weak_ptr_factory_.GetWeakPtr()));
   }
 
-  void HandleMouseEvent(WebInputEvent::Type type, int x = 0, int y = 0) {
+  void HandleMouseEvent(WebInputEvent::Type type,
+                        InputHandlerProxy::EventDispositionCallback callback,
+                        int x = 0,
+                        int y = 0) {
     WebMouseEvent mouse_event(type, WebInputEvent::kNoModifiers,
                               WebInputEvent::GetStaticTimeStampForTests());
-
     mouse_event.SetPositionInWidget(gfx::PointF(x, y));
     mouse_event.button = WebMouseEvent::Button::kLeft;
-    HandleInputEventWithLatencyInfo(&input_handler_proxy_, mouse_event);
+    std::unique_ptr<WebCoalescedInputEvent> scoped_input_event =
+        std::make_unique<WebCoalescedInputEvent>(mouse_event,
+                                                 ui::LatencyInfo());
+    input_handler_proxy_.HandleInputEventWithLatencyInfo(
+        std::move(scoped_input_event), nullptr, std::move(callback));
+  }
+
+  void HandleMouseEvent(WebInputEvent::Type type, int x = 0, int y = 0) {
+    HandleMouseEvent(type, base::DoNothing(), x, y);
   }
 
   void DidHandleInputEventAndOverscroll(
@@ -2575,9 +2585,9 @@
 
 TEST_F(InputHandlerProxyEventQueueTest,
        MouseEventOnScrollbarInitiatesGestureScroll) {
-  EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1);
+  EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(2);
   EXPECT_CALL(mock_input_handler_, FindFrameElementIdAtPoint(_))
-      .Times(2)
+      .Times(4)
       .WillRepeatedly(testing::Return(cc::ElementId()));
 
   // Test mousedown on the scrollbar. Expect to get GSB and GSU.
@@ -2588,7 +2598,28 @@
       .WillOnce(testing::Return(pointer_down_result.type));
   EXPECT_CALL(mock_input_handler_, MouseDown(_, _))
       .WillOnce(testing::Return(pointer_down_result));
-  HandleMouseEvent(WebInputEvent::Type::kMouseDown);
+  EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+      .WillOnce(testing::Return(kImplThreadScrollState));
+  EXPECT_CALL(mock_input_handler_, RecordScrollBegin(_, _)).Times(1);
+  EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(1);
+  bool pointer_down_callback_ran = false;
+  HandleMouseEvent(
+      WebInputEvent::Type::kMouseDown,
+      base::BindLambdaForTesting(
+          [&pointer_down_callback_ran](
+              InputHandlerProxy::EventDisposition disposition,
+              std::unique_ptr<blink::WebCoalescedInputEvent> event,
+              std::unique_ptr<InputHandlerProxy::DidOverscrollParams>
+                  overscroll,
+              const WebInputEventAttribution& attribution,
+              std::unique_ptr<cc::EventMetrics> metrics,
+              mojom::blink::ScrollResultDataPtr scroll_result_data) {
+            pointer_down_callback_ran = true;
+          }));
+
+  // The callback should not be called until GSB and GSU have been handled.
+  EXPECT_FALSE(pointer_down_callback_ran);
+
   EXPECT_EQ(2ul, event_queue().size());
   EXPECT_EQ(event_queue()[0]->event().GetType(),
             WebInputEvent::Type::kGestureScrollBegin);
@@ -2596,14 +2627,21 @@
                   .data.scroll_begin.synthetic);
   EXPECT_EQ(event_queue()[1]->event().GetType(),
             WebInputEvent::Type::kGestureScrollUpdate);
+
+  DeliverInputForBeginFrame();
+
+  // The callback should have been called after the GSU was processed.
+  EXPECT_EQ(0ul, event_queue().size());
+  EXPECT_TRUE(pointer_down_callback_ran);
+
   cc::InputHandlerPointerResult pointer_up_result;
   pointer_up_result.type = cc::PointerResultType::kScrollbarScroll;
   EXPECT_CALL(mock_input_handler_, MouseUp(_))
       .WillOnce(testing::Return(pointer_up_result));
   // Test mouseup on the scrollbar. Expect to get GSE.
   HandleMouseEvent(WebInputEvent::Type::kMouseUp);
-  EXPECT_EQ(3ul, event_queue().size());
-  EXPECT_EQ(event_queue()[2]->event().GetType(),
+  EXPECT_EQ(1ul, event_queue().size());
+  EXPECT_EQ(event_queue()[0]->event().GetType(),
             WebInputEvent::Type::kGestureScrollEnd);
 }
 
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index f05804d..e7ee308a 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -1867,6 +1867,16 @@
             'shared_highlighting::kFragmentTextBackgroundColorARGB',
         ]
     },
+    {
+        'paths': [
+            'third_party/blink/renderer/core/events/keyboard_event.h',
+            'third_party/blink/renderer/core/events/keyboard_event.cc',
+        ],
+        'allowed': [
+            'base::StringPiece16',
+            'base::i18n::UTF16CharIterator',
+        ]
+    }
 ]
 
 
diff --git a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py
index c54aa01..e2c927a 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py
@@ -164,8 +164,9 @@
         'PRECONDITION_FAILED',
         'TIMEOUT',
         'CRASH',
+        'ERROR',
     }
-    harness_statuses = common_test_statuses | {'OK', 'ERROR'}
+    harness_statuses = common_test_statuses | {'OK'}
     # Statuses for tests without subtests.
     test_statuses = common_test_statuses | {'PASS', 'FAIL'}
     implementation_statuses = {'implementing', 'not-implementing', 'default'}
diff --git a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py
index 55475b3..28fe604 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py
@@ -195,6 +195,16 @@
             """, 'variant.html.ini')
         self.assertEqual(errors, [])
 
+    def test_allow_reftest_error(self):
+        errors = self._check_metadata(
+            """\
+            [reftest.html]
+              # ERROR indicates a failure mode in the harness, whereas FAIL
+              # indicates a product issue.
+              expected: [FAIL, ERROR]
+            """, 'reftest.html.ini')
+        self.assertEqual(errors, [])
+
     def test_valid_dir_metadata(self):
         errors = self._check_metadata(
             """\
@@ -361,7 +371,7 @@
     def test_reftest_metadata_bad_values(self):
         errors = self._check_metadata("""\
             [reftest.html]
-              expected: ERROR
+              expected: OK
               fuzzy: [0-1:0-2, reftest-ref.html:20;200-300, @False]
               implementation-status: [implementing]
             """)
@@ -370,7 +380,7 @@
         self.assertEqual(name, 'META-BAD-VALUE')
         self.assertEqual(path, 'reftest.html.ini')
         self.assertEqual(description,
-                         "Test key 'expected' has invalid value 'ERROR'")
+                         "Test key 'expected' has invalid value 'OK'")
         name, description, path, _ = fuzzy_error1
         self.assertEqual(name, 'META-BAD-VALUE')
         self.assertEqual(path, 'reftest.html.ini')
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
index ac4f54f..30530425 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
@@ -18,6 +18,7 @@
     NamedTuple,
     Optional,
     Set,
+    Tuple,
     TypedDict,
 )
 from urllib.parse import urlsplit
@@ -85,14 +86,13 @@
         super().__init__(*args, **kwargs)
         self.messages = []
         self._test_section = wptnode.DataNode(_test_basename(self.name))
-        self.has_expected_fail = False
 
     def _add_expected_status(self, section: wptnode.DataNode, status: str):
         expectation = wptnode.KeyValueNode('expected')
         expectation.append(wptnode.ValueNode(status))
         section.append(expectation)
 
-    def _maybe_set_statuses(self, actual: str, unexpected: bool):
+    def _maybe_set_statuses(self, status: str, expected: Set[str]):
         """Set this result's actual/expected statuses.
 
         A `testharness.js` test may have subtests with their own statuses and
@@ -105,12 +105,29 @@
         latest status. The order tiebreaker ensures a test-level status
         overrides a subtest-level status when they have the same priority.
         """
-        priority = (self._status_priority.index(actual), unexpected)
+        unexpected = status not in expected
+        actual = self._wptrunner_to_chromium_statuses[status]
+        expected = {
+            self._wptrunner_to_chromium_statuses[status]
+            for status in expected
+        }
+        # Converting wptrunner to ResultDB statuses is lossy, so it's possible
+        # for the wptrunner result to be unexpected, but ResultDB status
+        # `actual` maps to a member of `expected`. Removing the common status
+        # forces `typ` to report this test result as unexpected.
+        if unexpected:
+            expected.discard(actual)
         # pylint: disable=access-member-before-definition
         # `actual` and `unexpected` are set in `Result`'s constructor.
-        if priority > (self._status_priority.index(
-                self.actual), self.unexpected):
-            self.actual, self.unexpected = actual, unexpected
+        priority = self._result_priority(actual, unexpected)
+        if priority >= self._result_priority(self.actual, self.unexpected):
+            self.actual, self.expected = actual, expected
+            self.unexpected = unexpected
+
+    def _result_priority(self, status: str,
+                         unexpected: bool) -> Tuple[bool, bool, int]:
+        incomplete = status in {ResultType.Timeout, ResultType.Crash}
+        return (incomplete, unexpected, self._status_priority.index(status))
 
     def update_from_subtest(self,
                             subtest: str,
@@ -123,21 +140,12 @@
         self._add_expected_status(subtest_section, status)
         self._test_section.append(subtest_section)
 
+        # Any result against a subtest not expected to run is considered an
+        # unexpected pass (and therefore won't cause a build failure).
+        if status != 'NOTRUN' and 'NOTRUN' in expected:
+            status = 'PASS'
         # Tentatively promote "interesting" statuses to the test level.
-        # Rules for promoting subtest status to test level:
-        #     Any result against 'NOTRUN' is an unexpected pass.
-        #     'NOTRUN' against other expected results is an unexpected failure.
-        #     Expected results only come from test level expectations
-        #     Only promote subtest status when run unexpected.
-        #     Exception: report expected failure if all subtest failures are expected.
-        unexpected = status not in expected
-        actual = (ResultType.Pass if 'NOTRUN' in expected else
-                  self._wptrunner_to_chromium_statuses[status])
-        self.has_expected_fail = (self.has_expected_fail
-                                  or actual == ResultType.Failure
-                                  and not unexpected)
-        if unexpected:
-            self._maybe_set_statuses(actual, unexpected)
+        self._maybe_set_statuses(status, expected)
 
     def update_from_test(self,
                          status: str,
@@ -146,21 +154,7 @@
         if message:
             self.messages.insert(0, 'Harness: %s\n' % message)
         self._add_expected_status(self._test_section, status)
-
-        unexpected = status not in expected
-        actual = self._wptrunner_to_chromium_statuses[status]
-        self.expected = {
-            self._wptrunner_to_chromium_statuses[status]
-            for status in expected
-        }
-        self._maybe_set_statuses(actual, unexpected)
-
-        # Report expected failure instead of expected pass when there are
-        # expected subtest failures.
-        if (self.actual == ResultType.Pass and not self.unexpected
-                and self.has_expected_fail):
-            self.actual = ResultType.Failure
-            self.expected = {ResultType.Failure}
+        self._maybe_set_statuses(status, expected)
 
     @property
     def actual_metadata(self):
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py
index b1a3a7b0..e90050c 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py
@@ -305,7 +305,7 @@
             'result']
         self.assertEqual(result.name, 'test.html')
         self.assertEqual(result.actual, 'PASS')
-        self.assertEqual(result.expected, {'PASS'})
+        self.assertEqual(result.expected, {'FAIL'})
         self.assertTrue(result.unexpected)
 
     def test_report_unexpected_subtest_fail(self):
@@ -328,7 +328,7 @@
                     subtest='unexpected pass after',
                     status='PASS',
                     expected='FAIL')
-        self._event(action='test_end', test='/test.html', status='OK')
+        self._event(action='test_end', test='/test.html', status='ERROR')
 
         result = self.processor.sink.report_individual_test_result.call_args.kwargs[
             'result']
@@ -351,7 +351,7 @@
             'result']
         self.assertEqual(result.name, 'test.html')
         self.assertEqual(result.actual, 'PASS')
-        self.assertEqual(result.expected, {'PASS'})
+        self.assertEqual(result.expected, {'FAIL'})
         self.assertTrue(result.unexpected)
 
     def test_report_unexpected_fail_for_notrun(self):
@@ -361,11 +361,8 @@
                     test='/test.html',
                     subtest='notrun',
                     status='NOTRUN',
-                    expected='FAIL')
-        self._event(action='test_end',
-                    test='/test.html',
-                    status='ERROR',
-                    expected='OK')
+                    expected='PASS')
+        self._event(action='test_end', test='/test.html', status='OK')
 
         result = self.processor.sink.report_individual_test_result.call_args.kwargs[
             'result']
@@ -374,6 +371,22 @@
         self.assertEqual(result.expected, {'PASS'})
         self.assertTrue(result.unexpected)
 
+    def test_report_unexpected_fail_for_different_types(self):
+        self._event(action='test_start', test='/reftest.html')
+        self._event(action='test_end',
+                    test='/reftest.html',
+                    status='ERROR',
+                    expected='FAIL')
+
+        result = self.processor.sink.report_individual_test_result.call_args.kwargs[
+            'result']
+        self.assertEqual(result.name, 'reftest.html')
+        # The unexpected flag is still set because the failures are of different
+        # types.
+        self.assertEqual(result.actual, 'FAIL')
+        self.assertEqual(result.expected, set())
+        self.assertTrue(result.unexpected)
+
     def test_report_unexpected_timeout(self):
         """NOTRUN should not be promoted to the test level."""
         self._event(action='test_start', test='/timeout.html')
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/factory.py b/third_party/blink/tools/blinkpy/web_tests/port/factory.py
index 05e637c4..871dce79 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/factory.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/factory.py
@@ -27,6 +27,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Factory method to retrieve the appropriate port implementation."""
 
+import argparse
 import fnmatch
 import optparse
 import re
@@ -183,6 +184,49 @@
     ]
 
 
+# TODO(crbug.com/1431070): Remove the `*_options` methods above once all tools
+# use `argparse`.
+
+
+def add_platform_options_group(parser: argparse.ArgumentParser):
+    group = parser.add_argument_group('Platform Options')
+    group.add_argument('--platform', help='Platform to use (e.g., "mac-lion")')
+    return group
+
+
+def add_configuration_options_group(parser: argparse.ArgumentParser):
+    group = parser.add_argument_group('Configuration Options')
+    group.add_argument(
+        '-t',
+        '--target',
+        help='Specify the target build subdirectory under //out')
+    group.add_argument('--debug',
+                       action='store_const',
+                       const='Debug',
+                       dest='configuration',
+                       help='Set the configuration to Debug')
+    group.add_argument('--release',
+                       action='store_const',
+                       const='Release',
+                       dest='configuration',
+                       help='Set the configuration to Release')
+    group.add_argument('--no-xvfb',
+                       action='store_false',
+                       dest='use_xvfb',
+                       help='Do not run tests with Xvfb')
+    return group
+
+
+def add_wpt_options_group(parser: argparse.ArgumentParser):
+    group = parser.add_argument_group('web-platform-tests (WPT) Options')
+    group.add_argument('--no-manifest-update',
+                       dest='manifest_update',
+                       action='store_false',
+                       help=('Do not update the web-platform-tests '
+                             'MANIFEST.json unless it does not exist.'))
+    return group
+
+
 def _builder_options(builder_name):
     return optparse.Values({
         'builder_name':
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
index 1a3d4be..8c65f67e 100644
--- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
+++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -28,6 +28,7 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+import argparse
 import logging
 import optparse
 import traceback
@@ -36,9 +37,7 @@
 from blinkpy.common.host import Host
 from blinkpy.web_tests.controllers.manager import Manager
 from blinkpy.web_tests.models import test_run_results
-from blinkpy.web_tests.port.factory import configuration_options
-from blinkpy.web_tests.port.factory import platform_options
-from blinkpy.web_tests.port.factory import wpt_options
+from blinkpy.web_tests.port import factory
 from blinkpy.web_tests.views import printing
 
 _log = logging.getLogger(__name__)
@@ -85,547 +84,445 @@
         printer.cleanup()
 
 
-def deprecate(option, opt_str, _, parser):
-    """
-    Prints a error message for a deprecated option.
-    Usage:
-        optparse.make_option(
-            '--some-option',
-            action='callback',
-            callback=deprecate,
-            help='....')
-    """
-    parser.error('%s: %s' % (opt_str, option.help))
-
-
 def parse_args(args):
-    option_group_definitions = []
+    parser = argparse.ArgumentParser(
+        usage='%(prog)s [options] [tests]',
+        description=('Runs Blink web tests as described in '
+                     '//docs/testing/web_tests.md'))
 
-    option_group_definitions.append(('Platform options', platform_options()))
+    factory.add_platform_options_group(parser)
+    factory.add_configuration_options_group(parser)
+    printing.add_print_options_group(parser)
+    factory.add_wpt_options_group(parser)
 
-    option_group_definitions.append(('Configuration options',
-                                     configuration_options()))
+    fuchsia_group = parser.add_argument_group('Fuchsia-specific Options')
+    fuchsia_group.add_argument(
+        '--zircon-logging',
+        action='store_true',
+        default=True,
+        help='Log Zircon debug messages (enabled by default).')
+    fuchsia_group.add_argument('--no-zircon-logging',
+                               dest='zircon_logging',
+                               action='store_false',
+                               default=True,
+                               help='Do not log Zircon debug messages.')
+    fuchsia_group.add_argument(
+        '--device',
+        choices=['qemu', 'device', 'fvdl'],
+        default='fvdl',
+        help='Choose device to launch Fuchsia with. Defaults to fvdl.')
+    fuchsia_group.add_argument(
+        '--fuchsia-target-cpu',
+        choices=['x64', 'arm64'],
+        default='x64',
+        help='cpu architecture of the device. Defaults to x64.')
+    fuchsia_group.add_argument('--fuchsia-out-dir',
+                               help='Path to Fuchsia build output directory.')
+    fuchsia_group.add_argument(
+        '--custom-image',
+        help='Specify an image used for booting up the emulator.')
+    fuchsia_group.add_argument(
+        '--fuchsia-ssh-config',
+        help=('The path to the SSH configuration used for '
+              'connecting to the target device.'))
+    fuchsia_group.add_argument(
+        '--fuchsia-target-id',
+        help='The node-name of the device to boot or deploy to.')
+    fuchsia_group.add_argument(
+        '--fuchsia-host-ip',
+        help=('The IP address of the test host observed by the Fuchsia '
+              'device. Required if running on hardware devices.'))
+    fuchsia_group.add_argument('--logs-dir',
+                               help='Location of diagnostics logs')
 
-    option_group_definitions.append(('Printing Options',
-                                     printing.print_options()))
+    results_group = parser.add_argument_group('Results Options')
+    results_group.add_argument(
+        '--flag-specific',
+        help=('Name of a flag-specific configuration defined in '
+              'FlagSpecificConfig. It is like a shortcut of '
+              '--additional-driver-flag, --additional-expectations and '
+              '--additional-platform-directory. When setting up flag-specific '
+              'testing on bots, we should use this option instead of the '
+              'discrete options. See crbug.com/1238155 for details.'))
+    results_group.add_argument(
+        '--additional-driver-flag',
+        '--additional-drt-flag',
+        dest='additional_driver_flag',
+        action='append',
+        default=[],
+        help=('Additional command line flag to pass to the driver. '
+              'Specify multiple times to add multiple flags.'))
+    results_group.add_argument(
+        '--additional-expectations',
+        action='append',
+        default=[],
+        help=('Path to a test_expectations file that will override previous '
+              'expectations. Specify multiple times for multiple sets of '
+              'overrides.'))
+    results_group.add_argument(
+        '--ignore-default-expectations',
+        action='store_true',
+        help='Do not use the default set of TestExpectations files.')
+    results_group.add_argument(
+        '--no-expectations',
+        action='store_true',
+        help=('Do not use TestExpectations, only run the tests without '
+              'reporting any results. Useful for generating code '
+              'coverage reports.'))
+    results_group.add_argument(
+        '--additional-platform-directory',
+        action='append',
+        default=[],
+        help=('Additional directory where to look for test baselines (will '
+              'take precedence over platform baselines). Specify multiple '
+              'times to add multiple search path entries.'))
+    results_group.add_argument(
+        '--build-directory',
+        default='out',
+        help=(
+            'Path to the directory where build files are kept, not including '
+            'configuration. In general this will be "out".'))
+    results_group.add_argument(
+        '--clobber-old-results',
+        action='store_true',
+        help='Clobbers test results from previous runs.')
+    results_group.add_argument('--compare-port',
+                               help="Use the specified port's baselines first")
+    results_group.add_argument(
+        '--copy-baselines',
+        action='store_true',
+        help=('If the actual result is different from the current baseline, '
+              'copy the current baseline into the *most-specific-platform* '
+              'directory, or the flag-specific generic-platform directory if '
+              '--additional-driver-flag is specified. See --reset-results.'))
+    results_group.add_argument('--driver-name',
+                               help='Alternative driver binary to use')
+    results_group.add_argument(
+        '--json-test-results',  # New name from json_results_generator
+        '--write-full-results-to',  # Old argument name
+        '--isolated-script-test-output',  # Isolated API
+        help='Path to write the JSON test results for *all* tests.')
+    results_group.add_argument(
+        '--write-run-histories-to',
+        help='Path to write the JSON test run histories.')
+    results_group.add_argument(
+        '--no-show-results',
+        dest='show_results',
+        action='store_false',
+        help="Don't launch a browser with results after the tests are done")
+    results_group.add_argument(
+        '--reset-results',
+        action='store_true',
+        help=('Reset baselines to the generated results in their existing '
+              'location or the default location if no baseline exists. For '
+              'virtual tests, reset the virtual baselines. If '
+              '--additional-driver-flag is specified, reset the flag-specific '
+              'baselines. If --copy-baselines is specified, the copied '
+              'baselines will be reset.'))
+    results_group.add_argument('--results-directory',
+                               help='Location of test results')
+    results_group.add_argument('--smoke',
+                               action='store_true',
+                               default=None,
+                               help='Run just the SmokeTests')
+    results_group.add_argument('--no-smoke',
+                               dest='smoke',
+                               action='store_false',
+                               default=None,
+                               help='Do not run just the SmokeTests')
 
-    option_group_definitions.append(('web-platform-tests (WPT) Options',
-                                     wpt_options()))
-
-    option_group_definitions.append(('Fuchsia-specific Options', [
-        optparse.make_option(
-            '--zircon-logging',
-            dest='zircon_logging',
-            action='store_true',
-            default=True,
-            help=('Log Zircon debug messages (enabled by default).')),
-        optparse.make_option('--no-zircon-logging',
-                             dest='zircon_logging',
-                             action='store_false',
-                             default=True,
-                             help=('Do not log Zircon debug messages.')),
-        optparse.make_option('--device',
-                             choices=['qemu', 'device', 'fvdl'],
-                             default='fvdl',
-                             help=('Choose device to launch Fuchsia with. '
-                                   'Defaults to fvdl.')),
-        optparse.make_option('--fuchsia-target-cpu',
-                             choices=['x64', 'arm64'],
-                             default='x64',
-                             help=('cpu architecture of the device. Defaults '
-                                   'to x64.')),
-        optparse.make_option('--fuchsia-out-dir',
-                             help=('Path to Fuchsia build output directory.')),
-        optparse.make_option('--custom-image',
-                             help=('Specify an image used for booting up the '
-                                   'emulator.')),
-        optparse.make_option(
-            '--fuchsia-ssh-config',
-            help=('The path to the SSH configuration used for '
-                  'connecting to the target device.')),
-        optparse.make_option('--fuchsia-target-id',
-                             help=('The node-name of the device to boot or '
-                                   'deploy to.')),
-        optparse.make_option(
-            '--fuchsia-host-ip',
-            help=('The IP address of the test host observed by the Fuchsia '
-                  'device. Required if running on hardware devices.')),
-        optparse.make_option('--logs-dir',
-                             help='Location of diagnostics logs'),
-    ]))
-
-    option_group_definitions.append((
-        'Results Options',
-        [
-            optparse.make_option(
-                '--flag-specific',
-                dest='flag_specific',
-                action='store',
-                default=None,
-                help=
-                ('Name of a flag-specific configuration defined in FlagSpecificConfig. '
-                 'It is like a shortcut of --additional-driver-flag, '
-                 '--additional-expectations and --additional-platform-directory. '
-                 'When setting up flag-specific testing on bots, we should use '
-                 'this option instead of the discrete options. '
-                 'See crbug.com/1238155 for details.')),
-            optparse.make_option(
-                '--additional-driver-flag',
-                '--additional-drt-flag',
-                dest='additional_driver_flag',
-                action='append',
-                default=[],
-                help=
-                ('Additional command line flag to pass to the driver. Specify multiple '
-                 'times to add multiple flags.')),
-            optparse.make_option(
-                '--additional-expectations',
-                action='append',
-                default=[],
-                help=
-                ('Path to a test_expectations file that will override previous '
-                 'expectations. Specify multiple times for multiple sets of overrides.'
-                 )),
-            optparse.make_option(
-                '--ignore-default-expectations',
-                action='store_true',
-                help=(
-                    'Do not use the default set of TestExpectations files.')),
-            optparse.make_option(
-                '--no-expectations',
-                action='store_true',
-                help=(
-                    'Do not use TestExpectations, only run the tests without '
-                    'reporting any results. Useful for generating code '
-                    'coverage reports.')),
-            optparse.make_option(
-                '--additional-platform-directory',
-                action='append',
-                default=[],
-                help=
-                ('Additional directory where to look for test baselines (will take '
-                 'precedence over platform baselines). Specify multiple times to add '
-                 'multiple search path entries.')),
-            optparse.make_option(
-                '--build-directory',
-                default='out',
-                help=
-                ('Path to the directory where build files are kept, not including '
-                 'configuration. In general this will be "out".')),
-            optparse.make_option(
-                '--clobber-old-results',
-                action='store_true',
-                default=False,
-                help='Clobbers test results from previous runs.'),
-            optparse.make_option(
-                '--compare-port',
-                action='store',
-                default=None,
-                help="Use the specified port's baselines first"),
-            optparse.make_option(
-                '--copy-baselines',
-                action='store_true',
-                default=False,
-                help=
-                ('If the actual result is different from the current baseline, '
-                 'copy the current baseline into the *most-specific-platform* '
-                 'directory, or the flag-specific generic-platform directory if '
-                 '--additional-driver-flag is specified. See --reset-results.'
-                 )),
-            optparse.make_option('--driver-name',
-                                 type='string',
-                                 help='Alternative driver binary to use'),
-            optparse.make_option(
-                '--json-test-results',  # New name from json_results_generator
-                '--write-full-results-to',  # Old argument name
-                '--isolated-script-test-output',  # Isolated API
-                help='Path to write the JSON test results for *all* tests.'),
-            optparse.make_option(
-                '--write-run-histories-to',
-                help='Path to write the JSON test run histories.'),
-            optparse.make_option(
-                '--no-show-results',
-                dest='show_results',
-                action='store_false',
-                default=True,
-                help=
-                "Don't launch a browser with results after the tests are done"
-            ),
-            optparse.make_option(
-                '--reset-results',
-                action='store_true',
-                default=False,
-                help=
-                ('Reset baselines to the generated results in their existing location or the default '
-                 'location if no baseline exists. For virtual tests, reset the virtual baselines. '
-                 'If --additional-driver-flag is specified, reset the flag-specific baselines. '
-                 'If --copy-baselines is specified, the copied baselines will be reset.'
-                 )),
-            optparse.make_option('--results-directory',
-                                 help='Location of test results'),
-            optparse.make_option('--smoke',
-                                 action='store_true',
-                                 help='Run just the SmokeTests'),
-            optparse.make_option('--no-smoke',
-                                 dest='smoke',
-                                 action='store_false',
-                                 help='Do not run just the SmokeTests'),
-        ]))
-
-    option_group_definitions.append((
-        'Testing Options',
-        [
-            optparse.make_option(
-                '--additional-env-var',
-                type='string',
-                action='append',
-                default=[],
-                help=('Passes that environment variable to the tests '
-                      '(--additional-env-var=NAME=VALUE)')),
-            optparse.make_option(
-                '--build',
-                dest='build',
-                action='store_true',
-                default=True,
-                help=('Check to ensure the build is up to date (default).')),
-            optparse.make_option(
-                '--no-build',
-                dest='build',
-                action='store_false',
-                help="Don't check to see if the build is up to date."),
-            optparse.make_option('--wpt-only',
-                                 action='store_true',
-                                 default=False,
-                                 help=('Run web platform tests only.')),
-            optparse.make_option('--child-processes',
-                                 '--jobs',
-                                 '-j',
-                                 help='Number of drivers to run in parallel.'),
-            optparse.make_option(
-                '--disable-breakpad',
-                action='store_true',
-                help="Don't use breakpad to symbolize unexpected crashes."),
-            optparse.make_option(
-                '--driver-logging',
-                action='store_true',
-                help='Print detailed logging of the driver/content_shell'),
-            optparse.make_option(
-                '--enable-leak-detection',
-                action='store_true',
-                help='Enable the leak detection of DOM objects.'),
-            optparse.make_option(
-                '--enable-sanitizer',
-                action='store_true',
-                help='Only alert on sanitizer-related errors and crashes'),
-            optparse.make_option(
-                '--enable-tracing',
-                type='string',
-                help='Capture and write a trace file with the specified '
-                'categories for each test. Passes appropriate --trace-startup '
-                'flags to the driver. If in doubt, use "*".'),
-            optparse.make_option(
-                '--exit-after-n-crashes-or-timeouts',
-                type='int',
-                default=None,
-                help=
-                'Exit after the first N crashes instead of running all tests'),
-            optparse.make_option(
-                '--exit-after-n-failures',
-                type='int',
-                default=None,
-                help=
-                'Exit after the first N failures instead of running all tests'
-            ),
-            optparse.make_option(
-                '--fuzzy-diff',
-                action='store_true',
-                default=False,
-                help=
-                ('When running tests on an actual GPU, variance in pixel '
-                 'output can leads image differences causing failed expectations. '
-                 'Instead a fuzzy diff is used to account for this variance. '
-                 'See tools/imagediff/image_diff.cc')),
-            optparse.make_option(
-                '--ignore-builder-category',
-                action='store',
-                help=
-                ('The category of builders to use with the --ignore-flaky-tests option '
-                 "('layout' or 'deps').")),
-            optparse.make_option(
-                '--ignore-flaky-tests',
-                action='store',
-                help=
-                ('Control whether tests that are flaky on the bots get ignored. '
-                 "'very-flaky' == Ignore any tests that flaked more than once on the bot. "
-                 "'maybe-flaky' == Ignore any tests that flaked once on the bot. "
-                 "'unexpected' == Ignore any tests that had unexpected results on the bot."
-                 )),
-            optparse.make_option(
-                '--iterations',
-                '--isolated-script-test-repeat',
-                # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it.
-                '--gtest_repeat',
-                type='int',
-                default=1,
-                help='Number of times to run the set of tests (e.g. ABCABCABC)'
-            ),
-            optparse.make_option(
-                '--layout-tests-directory',
-                help=('Path to a custom web tests directory')),
-            optparse.make_option(
-                '--max-locked-shards',
-                type='int',
-                default=0,
-                help='Set the maximum number of locked shards'),
-            optparse.make_option(
-                '--nocheck-sys-deps',
-                action='store_true',
-                default=False,
-                help="Don't check the system dependencies (themes)"),
-            optparse.make_option(
-                '--order',
-                action='store',
-                default='random',
-                help=
-                ('Determine the order in which the test cases will be run. '
-                 "'none' == use the order in which the tests were listed "
-                 'either in arguments or test list, '
-                 "'random' == pseudo-random order (default). Seed can be specified "
-                 'via --seed, otherwise it will default to the current unix timestamp. '
-                 "'natural' == use the natural order")),
-            optparse.make_option('--profile',
-                                 action='store_true',
-                                 help='Output per-test profile information.'),
-            optparse.make_option(
-                '--profiler',
-                action='store',
-                help=
-                'Output per-test profile information, using the specified profiler.'
-            ),
-            optparse.make_option(
-                '--restart-shell-between-tests',
-                type='choice',
-                action='store',
-                choices=[
-                    'always',
-                    'never',
-                    'on_retry',
-                ],
-                default='on_retry',
-                help=
-                ('Restarting the shell between tests produces more '
-                 'consistent results, as it prevents state from carrying over '
-                 'from previous tests. It also increases test run time by at '
-                 'least 2X. By default, the shell is restarted when tests get '
-                 'retried, since leaking state between retries can sometimes '
-                 'mask underlying flakiness, and the whole point of retries is '
-                 'to look for flakiness.')),
-            optparse.make_option(
-                '--repeat-each',
-                type='int',
-                default=1,
-                help='Number of times to run each test (e.g. AAABBBCCC)'),
-            optparse.make_option(
-                '--num-retries',
-                '--test-launcher-retry-limit',
-                '--isolated-script-test-launcher-retry-limit',
-                type='int',
-                default=None,
-                help=('Number of times to retry failures. Default (when this '
-                      'flag is not specified) is to retry 3 times, unless an '
-                      'explicit list of tests is passed to run_web_tests.py. '
-                      'If a non-zero value is given explicitly, failures are '
-                      'retried regardless.')),
-            optparse.make_option(
-                '--no-retry-failures',
-                dest='num_retries',
-                action='store_const',
-                const=0,
-                help="Don't retry any failures (equivalent to --num-retries=0)."
-            ),
-            optparse.make_option(
-                '--total-shards',
-                type=int,
-                help=('Total number of shards being used for this test run. '
-                      'Must be used with --shard-index. '
-                      '(The user of this script is responsible for spawning '
-                      'all of the shards.)')),
-            optparse.make_option(
-                '--shard-index',
-                type=int,
-                help=('Shard index [0..total_shards) of this test run. '
-                      'Must be used with --total-shards.')),
-            optparse.make_option(
-                '--seed',
-                type='int',
-                help=('Seed to use for random test order (default: %default). '
-                      'Only applicable in combination with --order=random.')),
-            optparse.make_option(
-                '--skipped',
-                action='store',
-                default=None,
-                help=
-                ('Control how tests marked SKIP are run. '
-                 '"default" == Skip tests unless explicitly listed on the command line, '
-                 '"ignore" == Run them anyway, '
-                 '"only" == only run the SKIP tests, '
-                 '"always" == always skip, even if listed on the command line.'
-                 )),
-            optparse.make_option(
-                '--isolated-script-test-also-run-disabled-tests',
-                # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it.
-                '--gtest_also_run_disabled_tests',
-                action='store_const',
-                const='ignore',
-                dest='skipped',
-                help=('Equivalent to --skipped=ignore.')),
-            optparse.make_option(
-                '--skip-failing-tests',
-                action='store_true',
-                default=False,
-                help=
-                ('Skip tests that are expected to fail. Note: When using this option, '
-                 'you might miss new crashes in these tests.')),
-            optparse.make_option(
-                '--skip-timeouts',
-                action='store_true',
-                default=False,
-                help=
-                ('Skip tests marked TIMEOUT. Use it to speed up running the entire '
-                 'test suite.')),
-            optparse.make_option(
-                '--fastest',
-                action='store',
-                type='float',
-                help=
-                'Run the N% fastest tests as well as any tests listed on the command line'
-            ),
-            optparse.make_option('--test-list',
-                                 action='append',
-                                 metavar='FILE',
-                                 help='read filters for tests to run'),
-            optparse.make_option(
-                '--isolated-script-test-filter-file',
-                '--test-launcher-filter-file',
-                action='append',
-                metavar='FILE',
-                help=
-                'read filters for tests to not run as if they were specified on the command line'
-            ),
-            optparse.make_option(
-                '--isolated-script-test-filter',
-                action='append',
-                type='string',
-                help=
-                'A list of test globs to run or skip, separated by TWO colons, e.g. fast::css/test.html; '
-                'prefix the glob with "-" to skip it'),
-            # TODO(crbug.com/893235): Remove gtest_filter when FindIt no longer uses it.
-            optparse.make_option(
-                '--gtest_filter',
-                type='string',
-                help='A colon-separated list of tests to run. Wildcards are '
-                'NOT supported. It is the same as listing the tests as '
-                'positional arguments.'),
-            optparse.make_option('--timeout-ms',
-                                 help='Set the timeout for each test'),
-            optparse.make_option(
-                '--initialize-webgpu-adapter-at-startup-timeout-ms',
-                type='float',
-                help='Initialize WebGPU adapter before running any tests.'),
-            optparse.make_option(
-                '--wrapper',
-                help=
-                ('wrapper command to insert before invocations of the driver; option '
-                 'is split on whitespace before running. (Example: --wrapper="valgrind '
-                 '--smc-check=all")')),
-            # FIXME: Display the default number of child processes that will run.
-            optparse.make_option('-f',
-                                 '--fully-parallel',
-                                 action='store_true',
-                                 help='run all tests in parallel'),
-            optparse.make_option(
-                '--virtual-parallel',
-                action='store_true',
-                help=
-                'When running in parallel, include virtual tests. Useful for running a single '
-                'virtual test suite, but will be slower in other cases.'),
-            optparse.make_option(
-                '-i',
-                '--ignore-tests',
-                action='append',
-                default=[],
-                help=
-                'directories or test to ignore (may specify multiple times)'),
-            optparse.make_option(
-                '-n',
-                '--dry-run',
-                action='store_true',
-                default=False,
-                help=
-                'Do everything but actually run the tests or upload results.'),
-            optparse.make_option(
-                '-w',
-                '--watch',
-                action='store_true',
-                help='Re-run tests quickly (e.g. avoid restarting the server)'
-            ),
-            optparse.make_option(
-                '--zero-tests-executed-ok',
-                action='store_true',
-                help='If set, exit with a success code when no tests are run.'
-                ' Used on trybots when web tests are retried without patch.'),
-            optparse.make_option(
-                '--driver-kill-timeout-secs',
-                type=float,
-                default=1.0,
-                help=
-                ('Number of seconds to wait before killing a driver, and the main '
-                 'use case is to leave enough time to allow the process to '
-                 'finish post-run hooks, such as dumping code coverage data. '
-                 'Default is 1 second, can be overriden for specific use cases.'
-                 )),
-            optparse.make_option(
-                '--ignore-testharness-expected-txt',
-                action='store_true',
-                help=('Ignore *-expected.txt for all testharness tests. All '
-                      'testharness test failures will be shown, even if the '
-                      'failures are expected in *-expected.txt.')),
-        ]))
+    testing_group = parser.add_argument_group('Testing Options')
+    testing_group.add_argument(
+        '--additional-env-var',
+        action='append',
+        default=[],
+        help=('Passes that environment variable to the tests '
+              '(--additional-env-var=NAME=VALUE)'))
+    testing_group.add_argument(
+        '--build',
+        action='store_true',
+        default=True,
+        help=('Check to ensure the build is up to date (default).'))
+    testing_group.add_argument(
+        '--no-build',
+        dest='build',
+        action='store_false',
+        help="Don't check to see if the build is up to date.")
+    testing_group.add_argument('--wpt-only',
+                               action='store_true',
+                               help='Run web platform tests only.')
+    testing_group.add_argument('--child-processes',
+                               '--jobs',
+                               '-j',
+                               help='Number of drivers to run in parallel.')
+    testing_group.add_argument(
+        '--disable-breakpad',
+        action='store_true',
+        help="Don't use breakpad to symbolize unexpected crashes.")
+    testing_group.add_argument(
+        '--driver-logging',
+        action='store_true',
+        help='Print detailed logging of the driver/content_shell')
+    testing_group.add_argument(
+        '--enable-leak-detection',
+        action='store_true',
+        help='Enable the leak detection of DOM objects.')
+    testing_group.add_argument(
+        '--enable-sanitizer',
+        action='store_true',
+        help='Only alert on sanitizer-related errors and crashes')
+    testing_group.add_argument(
+        '--enable-tracing',
+        help=('Capture and write a trace file with the specified '
+              'categories for each test. Passes appropriate --trace-startup '
+              'flags to the driver. If in doubt, use "*".'))
+    testing_group.add_argument(
+        '--exit-after-n-crashes-or-timeouts',
+        type=int,
+        default=None,
+        help='Exit after the first N crashes instead of running all tests')
+    testing_group.add_argument(
+        '--exit-after-n-failures',
+        type=int,
+        default=None,
+        help='Exit after the first N failures instead of running all tests')
+    testing_group.add_argument(
+        '--fuzzy-diff',
+        action='store_true',
+        help=('When running tests on an actual GPU, variance in pixel output '
+              'can lead to image differences causing failed expectations. '
+              'Using a fuzzy diff instead accounts for this variance. '
+              'See //tools/imagediff/image_diff.cc'))
+    testing_group.add_argument(
+        '--ignore-builder-category',
+        help=('The category of builders to use with the --ignore-flaky-tests '
+              "option ('layout' or 'deps')."))
+    testing_group.add_argument(
+        '--ignore-flaky-tests',
+        help=('Control whether tests that are flaky on the bots get ignored. '
+              "'very-flaky' == Ignore any tests that flaked more than once on "
+              "the bot. 'maybe-flaky' == Ignore any tests that flaked once on "
+              "the bot. 'unexpected' == Ignore any tests that had unexpected "
+              'results on the bot.'))
+    testing_group.add_argument(
+        '--iterations',
+        '--isolated-script-test-repeat',
+        # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it.
+        '--gtest_repeat',
+        type=int,
+        default=1,
+        help='Number of times to run the set of tests (e.g. ABCABCABC)')
+    testing_group.add_argument('--layout-tests-directory',
+                               help='Path to a custom web tests directory')
+    testing_group.add_argument('--max-locked-shards',
+                               type=int,
+                               default=0,
+                               help='Set the maximum number of locked shards')
+    testing_group.add_argument(
+        '--nocheck-sys-deps',
+        action='store_true',
+        help="Don't check the system dependencies (themes)")
+    testing_group.add_argument(
+        '--order',
+        choices=['none', 'random', 'natural'],
+        default='random',
+        help=('Determine the order in which the test cases will be run. '
+              "'none' == use the order in which the tests were listed "
+              'either in arguments or test list, '
+              "'random' == pseudo-random order (default). Seed can be "
+              "specified via --seed, otherwise it will default to the current "
+              "unix timestamp. 'natural' == use the natural order"))
+    testing_group.add_argument('--profile',
+                               action='store_true',
+                               help='Output per-test profile information.')
+    testing_group.add_argument('--profiler',
+                               help=('Output per-test profile information, '
+                                     'using the specified profiler.'))
+    testing_group.add_argument(
+        '--restart-shell-between-tests',
+        choices=['always', 'never', 'on_retry'],
+        default='on_retry',
+        help=('Restarting the shell between tests produces more '
+              'consistent results, as it prevents state from carrying over '
+              'from previous tests. It also increases test run time by at '
+              'least 2X. By default, the shell is restarted when tests get '
+              'retried, since leaking state between retries can sometimes '
+              'mask underlying flakiness, and the whole point of retries is '
+              'to look for flakiness.'))
+    testing_group.add_argument(
+        '--repeat-each',
+        type=int,
+        default=1,
+        help='Number of times to run each test (e.g. AAABBBCCC)')
+    testing_group.add_argument(
+        '--num-retries',
+        '--test-launcher-retry-limit',
+        '--isolated-script-test-launcher-retry-limit',
+        type=int,
+        default=None,
+        help=('Number of times to retry failures. Default (when this '
+              'flag is not specified) is to retry 3 times, unless an '
+              'explicit list of tests is passed to run_web_tests.py. '
+              'If a non-zero value is given explicitly, failures are '
+              'retried regardless.'))
+    testing_group.add_argument(
+        '--no-retry-failures',
+        dest='num_retries',
+        action='store_const',
+        const=0,
+        help="Don't retry any failures (equivalent to --num-retries=0).")
+    testing_group.add_argument(
+        '--total-shards',
+        type=int,
+        help=('Total number of shards being used for this test run. '
+              'Must be used with --shard-index. '
+              '(The user of this script is responsible for spawning '
+              'all of the shards.)'))
+    testing_group.add_argument(
+        '--shard-index',
+        type=int,
+        help=('Shard index [0..total_shards) of this test run. '
+              'Must be used with --total-shards.'))
+    testing_group.add_argument(
+        '--seed',
+        type=int,
+        help=('Seed to use for random test order (default: %(default)s). '
+              'Only applicable in combination with --order=random.'))
+    testing_group.add_argument(
+        '--skipped',
+        help=(
+            'Control how tests marked SKIP are run. '
+            '"default" == Skip tests unless explicitly listed on the command '
+            'line, "ignore" == Run them anyway, '
+            '"only" == only run the SKIP tests, '
+            '"always" == always skip, even if listed on the command line.'))
+    testing_group.add_argument(
+        '--isolated-script-test-also-run-disabled-tests',
+        # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it.
+        '--gtest_also_run_disabled_tests',
+        action='store_const',
+        const='ignore',
+        dest='skipped',
+        help=('Equivalent to --skipped=ignore.'))
+    testing_group.add_argument(
+        '--skip-failing-tests',
+        action='store_true',
+        help=('Skip tests that are expected to fail. Note: When using this '
+              'option, you might miss new crashes in these tests.'))
+    testing_group.add_argument(
+        '--skip-timeouts',
+        action='store_true',
+        help=('Skip tests marked TIMEOUT. Use it to speed up running the '
+              'entire test suite.'))
+    testing_group.add_argument(
+        '--fastest',
+        type=float,
+        help=('Run the N%% fastest tests as well as any tests listed '
+              'on the command line'))
+    testing_group.add_argument('--test-list',
+                               action='append',
+                               metavar='FILE',
+                               help='read filters for tests to run')
+    testing_group.add_argument(
+        '--isolated-script-test-filter-file',
+        '--test-launcher-filter-file',
+        action='append',
+        metavar='FILE',
+        help=('read filters for tests to not run as if '
+              'they were specified on the command line'))
+    testing_group.add_argument(
+        '--isolated-script-test-filter',
+        action='append',
+        help=('A list of test globs to run or skip, separated by TWO colons, '
+              'e.g. fast::css/test.html; prefix the glob with "-" to skip it'))
+    # TODO(crbug.com/893235): Remove gtest_filter when FindIt no longer uses it.
+    testing_group.add_argument(
+        '--gtest_filter',
+        help=('A colon-separated list of tests to run. Wildcards are '
+              'NOT supported. It is the same as listing the tests as '
+              'positional arguments.'))
+    testing_group.add_argument('--timeout-ms',
+                               help='Set the timeout for each test')
+    testing_group.add_argument(
+        '--initialize-webgpu-adapter-at-startup-timeout-ms',
+        type=float,
+        help='Initialize WebGPU adapter before running any tests.')
+    testing_group.add_argument(
+        '--wrapper',
+        help=('wrapper command to insert before invocations of the driver; '
+              'option is split on whitespace before running. (Example: '
+              '--wrapper="valgrind --smc-check=all")'))
+    # FIXME: Display the default number of child processes that will run.
+    testing_group.add_argument('-f',
+                               '--fully-parallel',
+                               action='store_true',
+                               help='run all tests in parallel')
+    testing_group.add_argument(
+        '--virtual-parallel',
+        action='store_true',
+        help=('When running in parallel, include virtual tests. Useful for '
+              'running a single virtual test suite, but will be slower '
+              'in other cases.'))
+    testing_group.add_argument(
+        '-i',
+        '--ignore-tests',
+        action='append',
+        default=[],
+        help='directories or test to ignore (may specify multiple times)')
+    testing_group.add_argument(
+        '-n',
+        '--dry-run',
+        action='store_true',
+        help='Do everything but actually run the tests or upload results.')
+    testing_group.add_argument(
+        '-w',
+        '--watch',
+        action='store_true',
+        help='Re-run tests quickly (e.g. avoid restarting the server)')
+    testing_group.add_argument(
+        '--zero-tests-executed-ok',
+        action='store_true',
+        help=('If set, exit with a success code when no tests are run. '
+              'Used on trybots when web tests are retried without patch.'))
+    testing_group.add_argument(
+        '--driver-kill-timeout-secs',
+        type=float,
+        default=1.0,
+        help=('Number of seconds to wait before killing a driver, and the '
+              'main use case is to leave enough time to allow the process to '
+              'finish post-run hooks, such as dumping code coverage data. '
+              'Default is 1 second, can be overriden for specific use cases.'))
+    testing_group.add_argument(
+        '--ignore-testharness-expected-txt',
+        action='store_true',
+        help=('Ignore *-expected.txt for all testharness tests. All '
+              'testharness test failures will be shown, even if the '
+              'failures are expected in *-expected.txt.'))
 
     # FIXME: Move these into json_results_generator.py.
-    option_group_definitions.append((
-        'Result JSON Options',
-        [
-            # TODO(qyearsley): --build-name is unused and should be removed.
-            optparse.make_option('--build-name', help=optparse.SUPPRESS_HELP),
-            optparse.make_option(
-                '--step-name',
-                default='blink_web_tests',
-                help='The name of the step in a build running this script.'),
-            optparse.make_option(
-                '--build-number',
-                default='DUMMY_BUILD_NUMBER',
-                help='The build number of the builder running this script.'),
-            optparse.make_option(
-                '--builder-name',
-                default='',
-                help='The name of the builder shown on the waterfall running '
-                'this script, e.g. "Mac10.13 Tests".'),
-        ]))
+    json_group = parser.add_argument_group('Result JSON Options')
+    # TODO(qyearsley): --build-name is unused and should be removed.
+    json_group.add_argument('--build-name', help=argparse.SUPPRESS)
+    json_group.add_argument(
+        '--step-name',
+        default='blink_web_tests',
+        help='The name of the step in a build running this script.')
+    json_group.add_argument(
+        '--build-number',
+        default='DUMMY_BUILD_NUMBER',
+        help='The build number of the builder running this script.')
+    json_group.add_argument(
+        '--builder-name',
+        default='',
+        help=('The name of the builder shown on the waterfall running '
+              'this script, e.g. "Mac10.13 Tests".'))
 
-    option_parser = optparse.OptionParser(
-        prog='run_web_tests.py',
-        usage='%prog [options] [tests]',
-        description=
-        'Runs Blink web tests as described in docs/testing/web_tests.md')
-
-    for group_name, group_options in option_group_definitions:
-        option_group = optparse.OptionGroup(option_parser, group_name)
-        option_group.add_options(group_options)
-        option_parser.add_option_group(option_group)
-
-    (options, args) = option_parser.parse_args(args)
-
+    parser.add_argument('tests',
+                        nargs='*',
+                        help='Paths to test files or directories to run')
+    params = vars(parser.parse_args(args))
+    args = params.pop('tests')
+    options = optparse.Values(params)
     return (options, args)
 
 
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests_unittest.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests_unittest.py
index dcd939d..b11a8b34 100644
--- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests_unittest.py
@@ -56,7 +56,7 @@
         args.extend(['--platform', 'test'])
 
     if not {'--jobs', '-j', '--child-processes'}.intersection(set(args)):
-        args.extend(['--jobs', 1])
+        args.extend(['--jobs', '1'])
     args.extend(extra_args)
     if not tests_included:
         # We use the glob to test that globbing works.
diff --git a/third_party/blink/tools/blinkpy/web_tests/views/printing.py b/third_party/blink/tools/blinkpy/web_tests/views/printing.py
index 2f0b0e96..54ca2bf3 100644
--- a/third_party/blink/tools/blinkpy/web_tests/views/printing.py
+++ b/third_party/blink/tools/blinkpy/web_tests/views/printing.py
@@ -27,6 +27,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Package that handles non-debug, non-file output for run_web_tests.py."""
 
+import argparse
 import logging
 import math
 import optparse
@@ -39,39 +40,30 @@
 NUM_SLOW_TESTS_TO_LOG = 10
 
 
-def print_options():
-    return [
-        optparse.make_option(
-            '--debug-rwt-logging',
-            action='store_true',
-            default=False,
-            help=
-            'print timestamps and debug information for run_web_tests.py itself'
-        ),
-        optparse.make_option(
-            '--details',
-            action='store_true',
-            default=False,
-            help='print detailed results for every test'),
-        optparse.make_option(
-            '-q',
-            '--quiet',
-            action='store_true',
-            default=False,
-            help='run quietly (errors, warnings, and progress only)'),
-        optparse.make_option(
-            '--timing',
-            action='store_true',
-            default=False,
-            help='display test times (summary plus per-test w/ --verbose)'),
-        optparse.make_option(
-            '-v',
-            '--verbose',
-            action='store_true',
-            default=False,
-            help='print a summarized result for every test (one line per test)'
-        ),
-    ]
+def add_print_options_group(parser: argparse.ArgumentParser):
+    group = parser.add_argument_group('Printing Options')
+    group.add_argument('--debug-rwt-logging',
+                       action='store_true',
+                       help=('print timestamps and debug information '
+                             'for run_web_tests.py itself'))
+    group.add_argument('--details',
+                       action='store_true',
+                       help='print detailed results for every test')
+    group.add_argument(
+        '-q',
+        '--quiet',
+        action='store_true',
+        help='run quietly (errors, warnings, and progress only)')
+    group.add_argument(
+        '--timing',
+        action='store_true',
+        help='display test times (summary plus per-test w/ --verbose)')
+    group.add_argument(
+        '-v',
+        '--verbose',
+        action='store_true',
+        help='print a summarized result for every test (one line per test)')
+    return group
 
 
 class Printer(object):
diff --git a/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py b/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py
index 901277ca..c34cf88e 100644
--- a/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py
@@ -27,6 +27,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Unit tests for printing.py."""
 
+import argparse
 import optparse
 import sys
 import unittest
@@ -41,14 +42,14 @@
 
 
 def get_options(args):
-    print_options = printing.print_options()
-    option_parser = optparse.OptionParser(option_list=print_options)
-    return option_parser.parse_args(args)
+    parser = argparse.ArgumentParser()
+    printing.add_print_options_group(parser)
+    return optparse.Values(vars(parser.parse_args(args)))
 
 
 class TestUtilityFunctions(unittest.TestCase):
     def test_print_options(self):
-        options, _ = get_options([])
+        options = get_options([])
         self.assertIsNotNone(options)
 
 
@@ -90,9 +91,7 @@
 
     def get_printer(self, args=None):
         args = args or []
-        printing_options = printing.print_options()
-        option_parser = optparse.OptionParser(option_list=printing_options)
-        options, args = option_parser.parse_args(args)
+        options = get_options(args)
         host = MockHost()
         self._port = host.port_factory.get('test', options)
 
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index bf89c777..631e5763 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -197,9 +197,6 @@
 [ Linux ] external/wpt/css/CSS2/linebox/inline-formatting-context-007.xht [ Skip ]
 [ Win ] external/wpt/css/CSS2/linebox/inline-formatting-context-007.xht [ Skip ]
 
-# CSS allows justification (text-align: justify) to hang trailing preserved spaces.
-external/wpt/css/CSS2/text/text-align-white-space-003.xht [ Skip ]
-
 # CSS2 tests that require files in different directories.
 external/wpt/css/CSS2/normal-flow/blocks-017.xht [ Skip ]
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index df8a201..e86d52c 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -261,9 +261,6 @@
 crbug.com/1430357 [ Mac ] virtual/view-transition-wide-gamut/external/wpt/css/css-view-transitions/massive-element-* [ Failure Pass ]
 
 # View transition SPA failures with MPA serialization.
-crbug.com/1443559 virtual/view-transition-mpa-serialization/inspector-protocol/css/css-get-styles-for-view-transition.js [ Failure ]
-crbug.com/1443559 virtual/view-transition-mpa-serialization/view-transition/capture-callback-exception.html [ Failure ]
-crbug.com/1443559 virtual/view-transition-mpa-serialization/external/wpt/css/css-view-transitions/old-content-captures-clip-path.html [ Failure ]
 crbug.com/1443559 [ Mac ] virtual/view-transition-mpa-serialization/external/wpt/css/css-view-transitions/fractional-translation-from-transform.html [ Failure ]
 
 ########## Ref tests can't be rebaselined ##########
@@ -1332,9 +1329,6 @@
 crbug.com/641861 [ Mac ] external/wpt/css/css-fonts/font-family-name-025.html [ Failure Timeout ]
 crbug.com/443467 external/wpt/css/css-fonts/font-feature-settings-descriptor-01.html [ Failure ]
 crbug.com/819816 external/wpt/css/css-fonts/font-kerning-03.html [ Failure ]
-crbug.com/451346 [ Win ] external/wpt/css/css-fonts/font-size-adjust-009.html [ Failure ]
-crbug.com/451346 [ Linux ] external/wpt/css/css-fonts/font-size-adjust-010.html [ Failure ]
-crbug.com/451346 [ Win ] external/wpt/css/css-fonts/font-size-adjust-010.html [ Failure ]
 crbug.com/451346 external/wpt/css/css-fonts/font-size-adjust-012.html [ Failure ]
 crbug.com/1240236 [ Mac ] external/wpt/css/css-fonts/system-ui-ar.html [ Failure ]
 crbug.com/1240236 [ Mac ] external/wpt/css/css-fonts/system-ui-ur.html [ Failure ]
@@ -2888,10 +2882,12 @@
 crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/css/css-backgrounds/box-shadow-border-radius-001.html [ Failure ]
+crbug.com/626703 virtual/threaded/external/wpt/css/css-backgrounds/box-shadow-border-radius-001.html [ Failure ]
 crbug.com/626703 [ Mac12 ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/scroll-timelines/effect-updateTiming.html [ Timeout ]
 crbug.com/626703 [ Mac12 ] virtual/threaded/external/wpt/scroll-animations/scroll-timelines/effect-updateTiming.html [ Timeout ]
 crbug.com/626703 [ Mac12 ] virtual/threaded/external/wpt/scroll-animations/view-timelines/view-timeline-range.html [ Timeout ]
-crbug.com/626703 [ Win10.20h2 ] external/wpt/video-rvfc/request-video-frame-callback-webrtc.https.html [ Timeout ]
+crbug.com/626703 [ Win ] external/wpt/video-rvfc/request-video-frame-callback-webrtc.https.html [ Timeout ]
 crbug.com/626703 [ Mac13 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ]
 crbug.com/626703 [ Mac13 ] external/wpt/html/semantics/links/hyperlink-auditing/headers.optional.html [ Timeout ]
 crbug.com/626703 [ Mac13 ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/scroll-timelines/effect-updateTiming.html [ Timeout ]
@@ -2899,7 +2895,7 @@
 crbug.com/626703 [ Mac13 ] virtual/threaded/external/wpt/scroll-animations/scroll-timelines/effect-updateTiming.html [ Timeout ]
 crbug.com/626703 [ Mac13 ] virtual/threaded/external/wpt/scroll-animations/view-timelines/view-timeline-inset.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-images/image-set/image-set-negative-resolution-rendering-3.html [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/video-rvfc/request-video-frame-callback-webrtc.https.html [ Timeout ]
+crbug.com/626703 [ Linux ] external/wpt/video-rvfc/request-video-frame-callback-webrtc.https.html [ Failure Timeout ]
 crbug.com/626703 [ Mac13-arm64 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Timeout ]
 crbug.com/626703 [ Mac12 ] virtual/threaded/external/wpt/scroll-animations/css/animation-timeline-view-functional-notation.tentative.html [ Timeout ]
@@ -6831,3 +6827,9 @@
 crbug.com/1447101 media/video-source-none-supported.html [ Failure Pass Timeout ]
 crbug.com/1430215 external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll.html [ Failure Pass ]
 crbug.com/1434378 virtual/fenced-frame-mparch/http/tests/inspector-protocol/fenced-frame/permissions-policy-fenced-frame.https.js [ Pass Timeout ]
+
+crbug.com/1448011 http/tests/devtools/application-panel/resources-panel-on-navigation.js [ Failure Pass ]
+crbug.com/1448011 http/tests/devtools/application-panel/resources-panel-selection-on-reload.js [ Failure Pass ]
+crbug.com/1448011 http/tests/devtools/indexeddb/delete-entry.js [ Failure Pass ]
+crbug.com/1448011 http/tests/devtools/indexeddb/live-update-indexeddb-content.js [ Failure Pass ]
+crbug.com/1448011 http/tests/devtools/indexeddb/resources-panel.js [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 1da6595e..f32763e 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1748,7 +1748,7 @@
     "exclusive_tests": "ALL",
     "args": [
       "--enable-blink-features=SpeculationRulesPrefetchProxy,SpeculationRulesFetchFromHeader,SpeculationRulesDocumentRules,NoVarySearchPrefetch,SpeculationRulesNoVarySearchHint,SpeculationRulesEagerness,SpeculationRulesDocumentRulesSelectorMatches",
-      "--enable-features=SpeculationRulesPrefetchProxy,PrefetchUseContentRefactor",
+      "--enable-features=SpeculationRulesPrefetchProxy,PrefetchUseContentRefactor:block_until_head_eager_prefetch/true",
       "--bypass-prefetch-proxy-for-host=not-web-platform.test"
     ],
     "expires": "Jul 1, 2023"
@@ -1762,7 +1762,7 @@
     "exclusive_tests": "ALL",
     "args": [
       "--enable-blink-features=NoVarySearchPrefetch,SpeculationRulesNoVarySearchHint",
-      "--enable-features=PrefetchUseContentRefactor"
+      "--enable-features=PrefetchUseContentRefactor:block_until_head_eager_prefetch/true"
     ],
     "expires": "Jul 1, 2023"
   },
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations
index 5db127c..6642fd3 100644
--- a/third_party/blink/web_tests/WebDriverExpectations
+++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -6,79 +6,79 @@
 # WPT WebDriver tests are a part of layout tests, but are run by a
 # separate runner, run_webdriver_tests.py. Thus this is a separate
 # expectation file from TestExpectations.
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/add_cookie/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_default[alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/delete_cookie/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/delete_cookie/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_clear/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_send_keys/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_send_keys/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/add_cookie/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/back/user_prompts.py>>test_default[alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/close_window/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/delete_cookie/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/delete_cookie/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
 crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/find_element/find.py>>test_no_browsing_context [ Failure Pass ]
-crbug.com/1342590 [ Linux ] external/wpt/webdriver/tests/find_elements_from_element/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
-crbug.com/1342590 [ Linux ] external/wpt/webdriver/tests/find_elements_from_element/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure Pass ]
-crbug.com/1342590 [ Linux ] external/wpt/webdriver/tests/find_elements_from_element/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_accept[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/user_prompts.py>>test_default[alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_element_rect/user_prompts.py>>test_default[alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_element_text/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_named_cookie/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_page_source/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_title/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_window_handles/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_window_handle/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/get_window_rect/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_default[alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/is_element_selected/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/is_element_selected/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/maximize_window/maximize.py>>test_fully_exit_fullscreen [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/maximize_window/maximize.py>>test_restore_the_window [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/minimize.py>>test_minimize [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/minimize.py>>test_minimize_twice_is_idempotent [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/minimize.py>>test_payload [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/stress.py>>test_stress[0] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/stress.py>>test_stress[1] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/stress.py>>test_stress[2] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/stress.py>>test_stress[3] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/stress.py>>test_stress[4] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/minimize_window/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure Pass ]
+crbug.com/1342590 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_element/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
+crbug.com/1342590 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_element/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure Pass ]
+crbug.com/1342590 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_element/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/forward/user_prompts.py>>test_accept[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_element_attribute/user_prompts.py>>test_default[alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/user_prompts.py>>test_default[alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_element_tag_name/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_named_cookie/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_page_source/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_title/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_window_handles/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_window_handle/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/get_window_rect/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_default[alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/maximize.py>>test_fully_exit_fullscreen [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/maximize.py>>test_restore_the_window [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/minimize.py>>test_minimize [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/minimize.py>>test_minimize_twice_is_idempotent [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/minimize.py>>test_payload [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/stress.py>>test_stress[0] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/stress.py>>test_stress[1] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/stress.py>>test_stress[2] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/stress.py>>test_stress[3] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/stress.py>>test_stress[4] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure Pass ]
 crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[pageLoadStrategy-normal] [ Failure Pass ]
 crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[test:extension-None] [ Failure Pass ]
 crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[timeouts-value14] [ Failure Pass ]
 crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[unhandledPromptBehavior-accept] [ Failure Pass ]
 crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/new_session/create_firstMatch.py>>test_valid[pageLoadStrategy-normal] [ Failure Pass ]
 crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/new_session/create_firstMatch.py>>test_valid[proxy-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/new_session/timeouts.py>>test_default_values [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/set_timeouts/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/set_window_rect/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_no_browsing_context [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_null_response_value [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/navigate.py>>test_link_closes_window [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/navigate.py>>test_link_hash [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/navigate.py>>test_link_unload_event [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/navigate.py>>test_multi_line_link [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/navigate.py>>test_numbers_link [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[1] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[2] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[3] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[4] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[5] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[6] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[7] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[8] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[9] [ Failure Pass ]
-crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/element_click/scroll_into_view.py>>test_scroll_into_view [ Failure Pass ]
-crbug.com/1020018 [ Linux ] external/wpt/webdriver/tests/get_active_element/get.py>>test_sucess_input [ Failure ]
-crbug.com/1020018 [ Linux ] external/wpt/webdriver/tests/get_active_element/get.py>>test_sucess_input_non_interactable [ Failure ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/new_session/timeouts.py>>test_default_values [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/set_timeouts/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/set_window_rect/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/click.py>>test_no_browsing_context [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/click.py>>test_null_response_value [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/navigate.py>>test_link_closes_window [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/navigate.py>>test_link_hash [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/navigate.py>>test_link_unload_event [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/navigate.py>>test_multi_line_link [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/navigate.py>>test_numbers_link [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[1] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[2] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[3] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[4] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[5] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[6] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[7] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[8] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_partially_visible_does_not_scroll[9] [ Failure Pass ]
+crbug.com/977228 [ Linux ] external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py>>test_scroll_into_view [ Failure Pass ]
+crbug.com/1020018 [ Linux ] external/wpt/webdriver/tests/classic/get_active_element/get.py>>test_sucess_input [ Failure ]
+crbug.com/1020018 [ Linux ] external/wpt/webdriver/tests/classic/get_active_element/get.py>>test_sucess_input_non_interactable [ Failure ]
 
 crbug.com/1167321 [ Linux ] external/wpt/webdriver/tests/find_elements_from_shadow_root/find.py>>test_no_browsing_context [ Failure ]
 crbug.com/1167321 [ Linux ] external/wpt/webdriver/tests/find_elements_from_shadow_root/find.py>>test_find_elements[tag-name-a] [ Failure ]
@@ -87,322 +87,391 @@
 crbug.com/1167321 [ Linux ] external/wpt/webdriver/tests/find_element_from_shadow_root/find.py>>test_find_element[tag-name-a] [ Failure ]
 crbug.com/1167321 [ Linux ] external/wpt/webdriver/tests/find_element_from_shadow_root/find.py>>test_find_element[xpath-//a] [ Failure ]
 
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_element_reference[frame] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_element_reference[window] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/execute_async.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/execute_async.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/execute_async.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/execute_async.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_non_element_nodes[attribute] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_non_element_nodes[comment] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_non_element_nodes[doctype] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_non_element_nodes[document] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_non_element_nodes[processing_instruction] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_non_element_nodes[text] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_element_reference[frame] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_element_reference[window] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/node.py>>test_non_element_nodes[attribute] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/node.py>>test_non_element_nodes[comment] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/node.py>>test_non_element_nodes[doctype] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/node.py>>test_non_element_nodes[document] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/node.py>>test_non_element_nodes[processing_instruction] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/node.py>>test_non_element_nodes[text] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_shadow_root/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_shadow_root/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_shadow_root/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_shadow_root/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/screenshot.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/screenshot.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/screenshot.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/screenshot.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/click.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/click.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/click.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/click.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_element_reference[frame] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_element_reference[window] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_non_element_nodes[attribute] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_non_element_nodes[comment] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_non_element_nodes[doctype] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_non_element_nodes[document] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_non_element_nodes[processing_instruction] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_non_element_nodes[text] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_element_reference[frame] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_element_reference[window] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/node.py>>test_non_element_nodes[attribute] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/node.py>>test_non_element_nodes[comment] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/node.py>>test_non_element_nodes[doctype] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/node.py>>test_non_element_nodes[document] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/node.py>>test_non_element_nodes[processing_instruction] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/node.py>>test_non_element_nodes[text] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_attribute/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_attribute/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_attribute/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_attribute/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_css_value/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_css_value/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_css_value/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_css_value/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_shadow_root/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_shadow_root/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_shadow_root/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_shadow_root/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_tag_name/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_tag_name/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_tag_name/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_tag_name/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/screenshot.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/screenshot.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/screenshot.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/screenshot.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
 
-crbug.com/1430078 [ Linux ] external/wpt/webdriver/tests/maximize_window/maximize.py>>test_no_top_browsing_context [ Failure Pass ]
-crbug.com/1430083 [ Linux ] external/wpt/webdriver/tests/get_element_property/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/1430078 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/maximize.py>>test_no_top_browsing_context [ Failure Pass ]
+crbug.com/1430083 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure Pass ]
 
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/orientation.py>>test_orientation[default] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/orientation.py>>test_orientation[landscape] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/orientation.py>>test_orientation[portrait] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/stress.py>>test_stress[0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/background.py>>test_background[False-iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P4DwQACfsD/Z8fLAAAAAAASUVORK5CYII=] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/background.py>>test_background[None-iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P4DwQACfsD/Z8fLAAAAAAASUVORK5CYII=] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/background.py>>test_background[True-iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgYGD4DwABBAEAwS2OUAAAAABJRU5ErkJggg==] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_element_with_invalid_value [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_shadow_root_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_shadow_root_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_shadow_root_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_shadow_root_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/arguments.py>>test_no_such_shadow_root_with_unknown_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_element_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_element_with_invalid_value [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_shadow_root_from_other_frame[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_shadow_root_from_other_frame[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_shadow_root_from_other_window_handle[closed] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_shadow_root_from_other_window_handle[open] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/arguments.py>>test_no_such_shadow_root_with_unknown_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/screenshot.py>>test_no_such_element_with_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/execute_async.py>>test_no_such_element_with_invalid_value [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_such_element_with_invalid_value [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_pretty_print_xml [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_document_as_object [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_element_reference[frame] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/node.py>>test_element_reference[window] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/node.py>>test_element_reference[frame] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/node.py>>test_element_reference[window] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/form_controls.py>>test_date [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_contenteditable [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[color-#ff0000-#000000] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[date-2017-12-26-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[datetime-2017-12-26T19:48-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[datetime-local-2017-12-26T19:48-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[email-foo@example.com-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[month-2017-11-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[number-42-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[password-password-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[range-42-50] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[search-search-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[tel-999-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[text-text-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[time-19:48-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[url-https://example.com/-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_input[week-2017-W52-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_resettable_element_does_not_satisfy_validation_constraints[month-foo] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_clear/clear.py>>test_textarea [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element/find.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_element/find.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_element/find.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_element/find.py>>test_no_such_element_with_startnode_from_other_frame [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_element/find.py>>test_no_such_element_with_startnode_from_other_window_handle [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_find_element[closed-css* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_find_element[closed-link* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_find_element[closed-partial* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_find_element[closed-tag* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_find_element[closed-xpath-//a] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_find_element[open-tag* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_find_element[open-xpath-//a] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[1] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[shadow_root_id3] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[shadow_root_id4] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_no_such_shadow_root_with_element [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_no_such_shadow_root_with_shadow_root_from_other_frame [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_no_such_shadow_root_with_shadow_root_from_other_window_handle [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py>>test_no_such_shadow_root_with_unknown_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements/find.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_element/find.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_element/find.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_element/find.py>>test_no_such_element_with_startnode_from_other_frame [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_element/find.py>>test_no_such_element_with_startnode_from_other_window_handle [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_find_elements[closed-css* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_find_elements[closed-link* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_find_elements[closed-partial* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_find_elements[closed-tag* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_find_elements[closed-xpath-//a] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_find_elements[open-tag* [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_find_elements[open-xpath-//a] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[1] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[shadow_root_id3] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_invalid_shadow_root_id_argument[shadow_root_id4] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_no_such_shadow_root_with_element [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_no_such_shadow_root_with_shadow_root_from_other_frame [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_no_such_shadow_root_with_shadow_root_from_other_window_handle [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py>>test_no_such_shadow_root_with_unknown_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/orientation.py>>test_orientation[default] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/orientation.py>>test_orientation[landscape] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/orientation.py>>test_orientation[portrait] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/stress.py>>test_stress[0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/background.py>>test_background[False-iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P4DwQACfsD/Z8fLAAAAAAASUVORK5CYII=] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/background.py>>test_background[None-iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P4DwQACfsD/Z8fLAAAAAAASUVORK5CYII=] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/background.py>>test_background[True-iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgYGD4DwABBAEAwS2OUAAAAABJRU5ErkJggg==] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/click.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_element_with_invalid_value [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_shadow_root_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_shadow_root_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_shadow_root_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_shadow_root_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/arguments.py>>test_no_such_shadow_root_with_unknown_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_element_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_element_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_element_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_element_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_element_with_invalid_value [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_shadow_root_from_other_frame[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_shadow_root_from_other_frame[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_shadow_root_from_other_window_handle[closed] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_shadow_root_from_other_window_handle[open] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/arguments.py>>test_no_such_shadow_root_with_unknown_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_attribute/get.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_css_value/get.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_tag_name/get.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/screenshot.py>>test_no_such_element_with_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py>>test_no_such_element_with_invalid_value [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_no_such_element_with_invalid_value [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_pretty_print_xml [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_document_as_object [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_element_reference[frame] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/node.py>>test_element_reference[window] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/node.py>>test_element_reference[frame] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/node.py>>test_element_reference[window] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/form_controls.py>>test_date [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_firstMatch.py>>test_valid[browserVersion-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_mouse.py>>test_drag_and_drop_with_draggable_element[0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_mouse.py>>test_drag_and_drop_with_draggable_element[300] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_mouse.py>>test_drag_and_drop_with_draggable_element[800] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_mouse.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_pen.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_pen.py>>test_pen_pointer_properties [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_touch.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_web_reference[frame-Frame] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_web_reference[window-Window] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_stale_element_reference[child_context] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_stale_element_reference[top_context] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_stale_element_reference[child_context] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_stale_element_reference[top_context] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_current_url/file.py>>test_get_current_url_file_protocol [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/navigate_to/file.py>>test_file_protocol [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_data_urls [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_dismissed_beforeunload [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_fragments [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_history_pushstate [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_no_browsing_history [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_removed_iframe [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_display_none [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_empty_text [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_hidden [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_multiple_files [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_multiple_files_last_path_not_found [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_multiple_files_reset_with_element_clear [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_multiple_files_send_twice [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_multiple_files_without_multiple_attribute [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_obscured [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_outside_viewport [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_single_file [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_single_file_appends_with_multiple_attribute [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_single_file_replaces_without_multiple_attribute [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_strict_display_none[capabilities0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_strict_hidden[capabilities0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/file_upload.py>>test_transparent [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_body_is_interactable [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_disabled [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_display_none [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_hidden [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_iframe_is_interactable [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_not_a_focusable_element [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_obscured_element [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_readonly_element [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_transparent_element [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_visibility_hidden [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_arguments [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_array [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_file_list [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_html_all_collection [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_html_collection [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_html_form_controls_collection [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_html_options_collection [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_node_list [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/collections.py>>test_shadow_root [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/cyclic.py>>test_array [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/cyclic.py>>test_array_in_object [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/cyclic.py>>test_element_in_collection [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/cyclic.py>>test_element_in_object [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/cyclic.py>>test_object [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/cyclic.py>>test_object_in_array [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt[alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt[confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt[prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt_twice[alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt_twice[confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt_twice[prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_ending_comment [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_null_parameter_value [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_opening_new_window_keeps_current_window_handle [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_override_listeners [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_await_promise_reject [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_await_promise_resolve [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_all_reject [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_all_resolve [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_reject [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_reject_delayed [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_reject_timeout [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_resolve [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_resolve_delayed [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/promise.py>>test_promise_resolve_timeout [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_default[alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_default[confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_default[prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress[0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress[1] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_basic [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_element_not_found [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_element_stale [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/interface/interface.py>>test_navigator_webdriver_active [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_element_stale [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant[button] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant[input] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant[select] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant[textarea] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant_legend[button] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant_legend[input] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant_legend[select] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant_legend[textarea] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant[button] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant[input] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant[select] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant[textarea] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant_legend[button] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant_legend[input] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant_legend[select] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant_legend[textarea] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_form_control_disabled[button] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_form_control_disabled[input] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_form_control_disabled[select] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_form_control_disabled[textarea] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_form_control_enabled[button] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_form_control_enabled[input] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_form_control_enabled[select] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_form_control_enabled[textarea] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xhtml_form_control_disabled[button] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xhtml_form_control_disabled[input] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xhtml_form_control_disabled[select] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xhtml_form_control_disabled[textarea] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xhtml_form_control_enabled[button] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xhtml_form_control_enabled[input] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xhtml_form_control_enabled[select] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xhtml_form_control_enabled[textarea] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_xml_always_not_enabled [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_default[confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_default[prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_checkbox_not_selected [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_element_checked [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_element_not_selected [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_element_selected [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_element_stale [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_default[alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_default[confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_default[prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_mouse.py>>test_drag_and_drop_with_draggable_element[0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_mouse.py>>test_drag_and_drop_with_draggable_element[300] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_mouse.py>>test_drag_and_drop_with_draggable_element[800] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_mouse.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_pen.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_pen.py>>test_pen_pointer_properties [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_touch.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_web_reference[frame-Frame] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_web_reference[window-Window] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_stale_element_reference[child_context] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_stale_element_reference[top_context] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_stale_element_reference[child_context] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_stale_element_reference[top_context] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_current_url/file.py>>test_get_current_url_file_protocol [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/navigate_to/file.py>>test_file_protocol [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/back/back.py>>test_data_urls [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/back/back.py>>test_dismissed_beforeunload [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/back/back.py>>test_fragments [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/back/back.py>>test_history_pushstate [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/back/back.py>>test_no_browsing_history [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/back/back.py>>test_removed_iframe [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_display_none [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_empty_text [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_hidden [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_multiple_files [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_multiple_files_last_path_not_found [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_multiple_files_reset_with_element_clear [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_multiple_files_send_twice [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_multiple_files_without_multiple_attribute [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_obscured [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_outside_viewport [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_single_file [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_single_file_appends_with_multiple_attribute [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_single_file_replaces_without_multiple_attribute [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_strict_display_none[capabilities0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_strict_hidden[capabilities0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py>>test_transparent [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_body_is_interactable [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_disabled [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_display_none [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_hidden [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_iframe_is_interactable [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_not_a_focusable_element [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_obscured_element [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_readonly_element [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_transparent_element [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_visibility_hidden [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_arguments [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_array [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_file_list [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_html_all_collection [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_html_collection [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_html_form_controls_collection [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_html_options_collection [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_node_list [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/collections.py>>test_shadow_root [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/cyclic.py>>test_array [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/cyclic.py>>test_array_in_object [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/cyclic.py>>test_element_in_collection [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/cyclic.py>>test_element_in_object [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/cyclic.py>>test_object [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/cyclic.py>>test_object_in_array [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_abort_by_user_prompt[alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_abort_by_user_prompt[confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_abort_by_user_prompt[prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_abort_by_user_prompt_twice[alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_abort_by_user_prompt_twice[confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_abort_by_user_prompt_twice[prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_ending_comment [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_null_parameter_value [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_opening_new_window_keeps_current_window_handle [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_override_listeners [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_await_promise_reject [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_await_promise_resolve [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_promise_all_reject [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_promise_all_resolve [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_promise_reject [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_promise_reject_delayed [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_promise_reject_timeout [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_promise_resolve [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_promise_resolve_delayed [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/promise.py>>test_promise_resolve_timeout [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_default[alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_default[confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_default[prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/fullscreen_window/stress.py>>test_stress[0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/fullscreen_window/stress.py>>test_stress[1] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_basic [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_element_not_found [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_element_stale [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/interface/interface.py>>test_navigator_webdriver_active [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_element_stale [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant[button] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant[input] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant[select] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant[textarea] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant_legend[button] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant_legend[input] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant_legend[select] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_disabled_descendant_legend[textarea] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant[button] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant[input] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant[select] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant[textarea] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant_legend[button] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant_legend[input] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant_legend[select] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_fieldset_enabled_descendant_legend[textarea] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_form_control_disabled[button] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_form_control_disabled[input] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_form_control_disabled[select] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_form_control_disabled[textarea] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_form_control_enabled[button] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_form_control_enabled[input] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_form_control_enabled[select] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_form_control_enabled[textarea] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xhtml_form_control_disabled[button] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xhtml_form_control_disabled[input] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xhtml_form_control_disabled[select] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xhtml_form_control_disabled[textarea] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xhtml_form_control_enabled[button] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xhtml_form_control_enabled[input] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xhtml_form_control_enabled[select] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xhtml_form_control_enabled[textarea] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_xml_always_not_enabled [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_default[confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_default[prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_checkbox_not_selected [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_element_checked [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_element_not_selected [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_element_selected [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_element_stale [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_default[alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_default[confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_default[prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[acceptInsecureCerts-False] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[acceptInsecureCerts-None] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[browserName-None] [ Failure ]
@@ -424,267 +493,267 @@
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[timeouts-value13] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[unhandledPromptBehavior-None] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[unhandledPromptBehavior-dismiss] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/platform_name.py>>test_corresponds_to_local_system [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/websocket_url.py>>test_websocket_url [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_keeps_current_window_handle [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_opens_about_blank_in_new_window [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_payload [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_sets_no_opener [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_sets_no_window_name [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_events.py>>test_special_key_sends_keydown[META-expected30] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_events.py>>test_special_key_sends_keydown[R_META-expected58] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_shortcuts.py>>test_mod_a_and_backspace_deletes_all_text [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_shortcuts.py>>test_mod_a_mod_x_deletes_all_text [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_default[alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_default[confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_default[prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/release_actions/release.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/release_actions/release.py>>test_null_response_value [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/release_actions/sequence.py>>test_release_char_sequence_sends_keyup_events_in_reverse [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/release_actions/sequence.py>>test_release_mouse_sequence_resets_dblclick_state [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/release_actions/sequence.py>>test_release_no_actions_sends_no_events [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/iframe.py>>test_always_captures_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/iframe.py>>test_source_origin[same_origin] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_get_computed_label[<button%20aria-label=foo>bar</button>-button-foo] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_get_computed_label[<button%20aria-labelledby="one%20two"></button><div%20id=one>ok</div><div%20id=two>go</div>-button-ok%20go] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_get_computed_label[<button>ok</button>-button-ok] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_get_computed_label[<label%20for=b>foo<label><input%20id=b>-input-foo] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_get_computed_label[<label><input>%20foo</label>-input-foo] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_label/get.py>>test_no_user_prompt [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_computed_roles[<img%20role=presentation>-img-presentation] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_computed_roles[<li%20role=menuitem>foo-li-menu] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_computed_role/get.py>>test_no_user_prompt [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges0-expected0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges1-expected1] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges2-expected2] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges3-expected3] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges4-expected4] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges5-expected5] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges6-expected6] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges7-expected7] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_document[ranges8-expected8] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_invalid[options10] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_invalid[options11] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_invalid[options12] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_page_ranges_invalid[options9] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_large_html_document [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/platform_name.py>>test_corresponds_to_local_system [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/websocket_url.py>>test_websocket_url [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_window/new_window.py>>test_keeps_current_window_handle [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_window/new_window.py>>test_opens_about_blank_in_new_window [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_window/new_window.py>>test_payload [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_window/new_window.py>>test_sets_no_opener [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_window/new_window.py>>test_sets_no_window_name [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_events.py>>test_special_key_sends_keydown[META-expected30] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_events.py>>test_special_key_sends_keydown[R_META-expected58] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_shortcuts.py>>test_mod_a_and_backspace_deletes_all_text [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_shortcuts.py>>test_mod_a_mod_x_deletes_all_text [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_default[alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_default[confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_default[prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/release_actions/release.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/release_actions/release.py>>test_null_response_value [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/release_actions/sequence.py>>test_release_char_sequence_sends_keyup_events_in_reverse [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/release_actions/sequence.py>>test_release_mouse_sequence_resets_dblclick_state [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/release_actions/sequence.py>>test_release_no_actions_sends_no_events [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/iframe.py>>test_always_captures_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/iframe.py>>test_source_origin[same_origin] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_get_computed_label[<button%20aria-label=foo>bar</button>-button-foo] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_get_computed_label[<button%20aria-labelledby="one%20two"></button><div%20id=one>ok</div><div%20id=two>go</div>-button-ok%20go] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_get_computed_label[<button>ok</button>-button-ok] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_get_computed_label[<label%20for=b>foo<label><input%20id=b>-input-foo] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_get_computed_label[<label><input>%20foo</label>-input-foo] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_label/get.py>>test_no_user_prompt [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_computed_roles[<img%20role=presentation>-img-presentation] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_computed_roles[<li%20role=menuitem>foo-li-menu] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_computed_role/get.py>>test_no_user_prompt [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges0-expected0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges1-expected1] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges2-expected2] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges3-expected3] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges4-expected4] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges5-expected5] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges6-expected6] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges7-expected7] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_document[ranges8-expected8] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_invalid[options10] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_invalid[options11] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_invalid[options12] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_page_ranges_invalid[options9] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_large_html_document [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/bidi/new_session/connect.py>>test_bidi_session_with_different_capability[capabilities0] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/bidi/new_session/connect.py>>test_bidi_session_send [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_window_handle/get.py>>test_navigation_with_coop_headers[capabilities0] [ Failure ]
-crbug.com/626703 [ Mac10.14 ] external/wpt/webdriver/tests/get_window_handle/get.py>>test_navigation_with_coop_headers[capabilities0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_cross_origin[capabilities0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/navigate_to/navigate.py>>test_cross_origin[capabilities0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_cross_origin[capabilities0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/navigate.py>>test_link_cross_origin[capabilities0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_window_handle/get.py>>test_navigation_with_coop_headers[capabilities0] [ Failure ]
+crbug.com/626703 [ Mac10.14 ] external/wpt/webdriver/tests/classic/get_window_handle/get.py>>test_navigation_with_coop_headers[capabilities0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/back/back.py>>test_cross_origin[capabilities0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/navigate_to/navigate.py>>test_cross_origin[capabilities0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/forward/forward.py>>test_cross_origin[capabilities0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/navigate.py>>test_link_cross_origin[capabilities0] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[timeouts-value12] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_shadow_root/get.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_shadow_root/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_frame/switch.py>>test_frame_id_null [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_parent_frame/switch.py>>test_switch_from_iframe [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_window/switch.py>>test_element_not_found_after_tab_switch [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_shadow_root/get.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_shadow_root/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_frame/switch.py>>test_frame_id_null [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_parent_frame/switch.py>>test_switch_from_iframe [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_window/switch.py>>test_element_not_found_after_tab_switch [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/click.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_attribute/get.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_tag_name/get.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_css_value/get.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_no_top_browsing_context [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_touch_pointer_properties [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_pen_pointer_properties [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/release_actions/release.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/wheel.py>>test_wheel_scroll_iframe [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/wheel.py>>test_wheel_scroll_overflow [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/wheel.py>>test_wheel_scroll [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/wheel.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/wheel.py>>test_null_response_value [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/wheel.py>>test_no_top_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_active_element/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_active_element/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_page_source/source.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_page_source/source.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_frame/switch.py>>test_no_browsing_context[id2] [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/switch_to_frame/switch.py>>test_no_browsing_context[id2] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_named_cookie/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_named_cookie/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/add_cookie/add.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/add_cookie/add.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_parent_frame/switch.py>>test_no_parent_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/switch_to_parent_frame/switch.py>>test_no_parent_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/perform_actions/key.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/none.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/perform_actions/none.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/delete_all_cookies/delete.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/delete_all_cookies/delete.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/print/printcmd.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/release_actions/release.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/wheel.py>>test_wheel_scroll_iframe [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/wheel.py>>test_wheel_scroll_overflow [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/wheel.py>>test_wheel_scroll [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/wheel.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/wheel.py>>test_null_response_value [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/wheel.py>>test_no_top_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_active_element/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_active_element/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_page_source/source.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_page_source/source.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_css_value/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_element_css_value/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_frame/switch.py>>test_no_browsing_context[id2] [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/switch_to_frame/switch.py>>test_no_browsing_context[id2] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_named_cookie/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_named_cookie/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/add_cookie/add.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/add_cookie/add.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_element_rect/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/is_element_selected/selected.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_parent_frame/switch.py>>test_no_parent_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/switch_to_parent_frame/switch.py>>test_no_parent_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_element_property/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/perform_actions/key.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/none.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/perform_actions/none.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_tag_name/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_element_tag_name/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_element_text/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/delete_all_cookies/delete.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/delete_all_cookies/delete.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_no_browsing_context [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_no_browsing_context [ Failure ]
 crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/delete_cookie/delete.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/delete_cookie/delete.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_frame/switch.py>>test_no_browsing_context[0] [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/switch_to_frame/switch.py>>test_no_browsing_context[0] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/execute_async.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/execute_async_script/execute_async.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_browsing_context [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_title/iframe.py>>test_origin[cross_origin] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_current_url/iframe.py>>test_origin[cross_origin] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_tripleclick.py>>test_tripleclick_at_coordinates [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/minimize_window/minimize.py>>test_fully_exit_fullscreen [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_named_cookie/get.py>>test_duplicated_cookie [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/add_cookie/add.py>>test_add_cookie_with_valid_samesite_flag[None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_named_cookie/get.py>>test_get_named_session_cookie [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_named_cookie/get.py>>test_get_named_cookie [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_html_document [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/iframe.py>>test_source_origin[cross_origin] [ Failure ]
-crbug.com/1023255 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/iframe.py>>test_source_origin[same_origin] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/iframe.py>>test_source_origin[cross_origin] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_frame/cross_origin.py>>test_nested_cross_origin_iframe [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_frame/cross_origin.py>>test_cross_origin_iframe [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_window/alerts.py>>test_retain_tab_modal_status [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_contextmenu.py>>test_control_click[\ue009-ctrlKey] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/interactability.py>>test_document_element_is_interactable [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/bubbling.py>>test_spin_event_loop [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/content_editable.py>>test_sets_insertion_point_to_after_last_text_node [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/delete_cookie/delete.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/delete_cookie/delete.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/execute_script/execute.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_frame/switch.py>>test_no_browsing_context[0] [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/switch_to_frame/switch.py>>test_no_browsing_context[0] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_element_attribute/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Mac10.13 ] external/wpt/webdriver/tests/classic/get_element_attribute/get.py>>test_no_browsing_context [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_title/iframe.py>>test_origin[cross_origin] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_current_url/iframe.py>>test_origin[cross_origin] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_tripleclick.py>>test_tripleclick_at_coordinates [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/minimize_window/minimize.py>>test_fully_exit_fullscreen [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_named_cookie/get.py>>test_duplicated_cookie [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/add_cookie/add.py>>test_add_cookie_with_valid_samesite_flag[None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_named_cookie/get.py>>test_get_named_session_cookie [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_named_cookie/get.py>>test_get_named_cookie [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/printcmd.py>>test_html_document [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/print/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/iframe.py>>test_source_origin[cross_origin] [ Failure ]
+crbug.com/1023255 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/iframe.py>>test_source_origin[same_origin] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/iframe.py>>test_source_origin[cross_origin] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_frame/cross_origin.py>>test_nested_cross_origin_iframe [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_frame/cross_origin.py>>test_cross_origin_iframe [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/switch_to_window/alerts.py>>test_retain_tab_modal_status [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_contextmenu.py>>test_control_click[\ue009-ctrlKey] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/interactability.py>>test_document_element_is_interactable [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/bubbling.py>>test_spin_event_loop [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/content_editable.py>>test_sets_insertion_point_to_after_last_text_node [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[pageLoadStrategy-eager] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/json_serialize_windowproxy.py>>test_window_open [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/file_upload.py>>test_file_upload_state [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/set_window_rect/set.py>>test_width_height_floats [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/merge.py>>test_merge_platformName [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_default[confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/set_window_rect/set.py>>test_restore_from_minimized [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/scroll_into_view.py>>test_option_stays_outside_of_scrollable_viewport [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_events.py>>test_special_key_sends_keydown[META-expected11] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/content_editable.py>>test_sets_insertion_point_to_end [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\u1100\u1161\u11a8] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/status/status.py>>test_status_with_session_running_on_endpoint_node [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/scroll_into_view.py>>test_option_select_container_outside_of_scrollable_viewport [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/maximize.py>>test_maximize_when_resized_to_max_size [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_default[alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_default[prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_events.py>>test_modifier_key_sends_correct_events[\ue03d-META] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/merge.py>>test_merge_browserName [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/default_values.py>>test_no_capabilites [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_events.py>>test_special_key_sends_keydown[R_META-expected19] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\U0001f60d] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/set_window_rect/set.py>>test_restore_from_maximized [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_default[prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/default_values.py>>test_repeat_new_session [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_events.py>>test_modifier_key_sends_correct_events[\ue053-R_META] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_default[confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/json_serialize_windowproxy.py>>test_frame [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_default[alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_contextmenu.py>>test_control_click[\ue051-ctrlKey] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py>>test_window_open [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_click/file_upload.py>>test_file_upload_state [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/set_window_rect/set.py>>test_width_height_floats [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/merge.py>>test_merge_platformName [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_default[confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/set_window_rect/set.py>>test_restore_from_minimized [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/scroll_into_view.py>>test_option_stays_outside_of_scrollable_viewport [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_events.py>>test_special_key_sends_keydown[META-expected11] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/content_editable.py>>test_sets_insertion_point_to_end [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\u1100\u1161\u11a8] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/status/status.py>>test_status_with_session_running_on_endpoint_node [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/scroll_into_view.py>>test_option_select_container_outside_of_scrollable_viewport [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/maximize_window/maximize.py>>test_maximize_when_resized_to_max_size [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_default[alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_default[prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_events.py>>test_modifier_key_sends_correct_events[\ue03d-META] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/merge.py>>test_merge_browserName [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/default_values.py>>test_no_capabilites [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_events.py>>test_special_key_sends_keydown[R_META-expected19] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\U0001f60d] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/set_window_rect/set.py>>test_restore_from_maximized [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_default[prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/default_values.py>>test_repeat_new_session [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_events.py>>test_modifier_key_sends_correct_events[\ue053-R_META] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_default[confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py>>test_frame [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_default[alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_contextmenu.py>>test_control_click[\ue051-ctrlKey] [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_firstMatch.py>>test_valid[pageLoadStrategy-eager] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/page_load_strategy.py>>test_pageLoadStrategy [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\u0ba8\u0bbf] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-prompt] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/navigate_to/navigate.py>>test_file_protocol [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_current_url/get.py>>test_get_current_url_file_protocol [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/json_serialize_windowproxy.py>>test_initial_window [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/set_timeouts/set.py>>test_parameters_unknown_fields[value1] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/default_values.py>>test_valid_but_unmatchable_key [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/scroll_into_view.py>>test_element_outside_of_not_scrollable_viewport [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\U0001f604] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/default_values.py>>test_desired [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert] [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
-crbug.com/1023255 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/iframe.py>>test_frame_element [ Failure Pass ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/page_load_strategy.py>>test_pageLoadStrategy [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\u0ba8\u0bbf] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-prompt] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/navigate_to/navigate.py>>test_file_protocol [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/get_current_url/get.py>>test_get_current_url_file_protocol [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py>>test_initial_window [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/set_timeouts/set.py>>test_parameters_unknown_fields[value1] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/default_values.py>>test_valid_but_unmatchable_key [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/element_send_keys/scroll_into_view.py>>test_element_outside_of_not_scrollable_viewport [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\U0001f604] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/new_session/default_values.py>>test_desired [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert] [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ]
+crbug.com/1023255 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/iframe.py>>test_frame_element [ Failure Pass ]
 crbug.com/1065297 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_drag_and_drop_with_draggable_element[800] [ Failure ]
 crbug.com/1065297 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_drag_and_drop_with_draggable_element[0] [ Failure ]
 crbug.com/1065297 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_drag_and_drop_with_draggable_element[300] [ Failure ]
-crbug.com/1065297 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_shortcuts.py>>test_mod_a_mod_c_right_mod_v_pastes_text [ Failure ]
-crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress[2] [ Failure Pass ]
-crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress[3] [ Failure Pass ]
-crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress[4] [ Failure Pass ]
-crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress [ Failure Pass ]
-crbug.com/1128104 [ Linux ] external/wpt/webdriver/tests/release_actions/sequence.py>>test_no_release_mouse_sequence_keeps_dblclick_state [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_origin.py>>test_element_larger_than_viewport [ Failure ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure Pass ]
-crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure Pass ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_touch.py>>test_touch_pointer_properties [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_touch.py>>test_touch_pointer_properties_tilt_twist [ Failure ]
-crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_dismissed_beforeunload [ Failure ]
-crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_dismissed_beforeunload [ Failure ]
-crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_history_pushstate [ Failure ]
-crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_refresh_switches_to_parent_browsing_context [ Failure ]
+crbug.com/1065297 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/key_shortcuts.py>>test_mod_a_mod_c_right_mod_v_pastes_text [ Failure ]
+crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/classic/fullscreen_window/stress.py>>test_stress[2] [ Failure Pass ]
+crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/classic/fullscreen_window/stress.py>>test_stress[3] [ Failure Pass ]
+crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/classic/fullscreen_window/stress.py>>test_stress[4] [ Failure Pass ]
+crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/classic/fullscreen_window/stress.py>>test_stress [ Failure Pass ]
+crbug.com/1128104 [ Linux ] external/wpt/webdriver/tests/classic/release_actions/sequence.py>>test_no_release_mouse_sequence_keeps_dblclick_state [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_origin.py>>test_element_larger_than_viewport [ Failure ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure Pass ]
+crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure Pass ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_touch.py>>test_touch_pointer_properties [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_touch.py>>test_touch_pointer_properties_tilt_twist [ Failure ]
+crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/classic/forward/forward.py>>test_dismissed_beforeunload [ Failure ]
+crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/classic/refresh/refresh.py>>test_dismissed_beforeunload [ Failure ]
+crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/classic/refresh/refresh.py>>test_history_pushstate [ Failure ]
+crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/classic/refresh/refresh.py>>test_refresh_switches_to_parent_browsing_context [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 45d585c..773d17b5 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -5339,6 +5339,13 @@
          {}
         ]
        ],
+       "input-type-change-empty-crash.html": [
+        "6e44250ccb79f3a2a06b6ef639914cad656a4bb6",
+        [
+         null,
+         {}
+        ]
+       ],
        "invalid-datalist-options-crash.html": [
         "7cdd55196cecaae8cc64fe7fc86b4f7305e7525d",
         [
@@ -69596,19 +69603,6 @@
         {}
        ]
       ],
-      "text-align-white-space-003.xht": [
-       "947e869223e3c8154197a000d50f0c7e7f0a13a0",
-       [
-        null,
-        [
-         [
-          "/css/CSS2/text/text-align-white-space-002-ref.xht",
-          "=="
-         ]
-        ],
-        {}
-       ]
-      ],
       "text-align-white-space-004.xht": [
        "4d8f6b6f2646cda6d47eff7511f740944951369f",
        [
@@ -84060,6 +84054,23 @@
        {}
       ]
      ],
+     "box-shadow-border-radius-001.html": [
+      "6f81ca81fac13b590c2538970caaee80c27badcf",
+      [
+       null,
+       [
+        [
+         "/css/css-backgrounds/reference/box-shadow-border-radius-001-ref.html",
+         "=="
+        ],
+        [
+         "/css/css-backgrounds/reference/box-shadow-border-radius-001-notref.html",
+         "!="
+        ]
+       ],
+       {}
+      ]
+     ],
      "box-shadow-calc.html": [
       "14011859851b1234674bbdf6374670c674b56968",
       [
@@ -84086,52 +84097,52 @@
        {}
       ]
      ],
-     "box-shadow-inset-spread-without-border-radius.html": [
-      "0e74fbf5b64581d3940bd6c374a7972b9a6e7b76",
-      [
-       null,
-       [
-        [
-         "/css/css-backgrounds/reference/box-shadow-inset-spread-without-border-radius.html",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
      "box-shadow-inset-without-border-radius.html": [
-      "a6ad9440f3ce858f4b6aa5cdcde9da50ca6dec3b",
+      "8b2c691ebc8fbd318416a1c4f13461fb2576b702",
       [
        null,
        [
         [
-         "/css/css-backgrounds/reference/box-shadow-inset-without-border-radius.html",
+         "/css/css-backgrounds/reference/box-shadow-inset-without-border-radius-ref.html",
          "=="
         ]
        ],
        {}
       ]
      ],
-     "box-shadow-outset-spread-without-border-radius.html": [
-      "5ebde5519ca445732fef5f3f28a60ecd102ed676",
+     "box-shadow-invalid-001.html": [
+      "acd0bdf41bd7899c45bd424e64127f5e30464ef1",
       [
        null,
        [
         [
-         "/css/css-backgrounds/reference/box-shadow-outset-spread-without-border-radius.html",
+         "/css/css-backgrounds/reference/ref-filled-green-100px-square.xht",
          "=="
         ]
        ],
        {}
       ]
      ],
-     "box-shadow-outset-without-border-radius.html": [
-      "9f2135417278f6d0528eb3f66d255508a62571a9",
+     "box-shadow-multiple-001.html": [
+      "e95fb6841ad1c9b21aebf2c51f7690f917e0dd1c",
       [
        null,
        [
         [
-         "/css/css-backgrounds/reference/box-shadow-outset-without-border-radius.html",
+         "/css/css-backgrounds/reference/box-shadow-multiple-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "box-shadow-outset-without-border-radius-001.html": [
+      "71735a98ce7ae9d2df7ca7eed7dd7b4020cd72ba",
+      [
+       null,
+       [
+        [
+         "/css/css-backgrounds/reference/box-shadow-outset-without-border-radius-001-ref.html",
          "=="
         ]
        ],
@@ -124856,7 +124867,7 @@
       ]
      ],
      "font-size-adjust-009.html": [
-      "765447b22f040b8015789d0a6df532e801e67459",
+      "133f96f450cd9a45cf0822a7ffc082976371dac4",
       [
        null,
        [
@@ -124869,7 +124880,7 @@
       ]
      ],
      "font-size-adjust-010.html": [
-      "6ee3ab7d8742b8f5d6bd3f16319ef57911183e67",
+      "c3b2bc195ec1c3ed067cac3bea60fd4bf446690b",
       [
        null,
        [
@@ -124882,7 +124893,7 @@
       ]
      ],
      "font-size-adjust-011.html": [
-      "f4ac39c257471a81114f5f32019c65fc24187595",
+      "3f6afd8a3708aa86d94443b8a1d8bbffe2ffef5d",
       [
        null,
        [
@@ -146855,7 +146866,7 @@
         ]
        ],
        "two-clip-path-animation-diff-length2.html": [
-        "0d86120ef35db999dd91b3c2cdd709429e907746",
+        "5a8e22832a7e077a1a3b6235f9598fe346c72446",
         [
          null,
          [
@@ -227832,7 +227843,7 @@
       ]
      ],
      "old-content-captures-clip-path.html": [
-      "a2faa7f1575af4c6ac3f65b3fb303f6dbab875d3",
+      "467b19d928d62492dbb33a54edebdc9f92f8bcf9",
       [
        null,
        [
@@ -227841,7 +227852,27 @@
          "=="
         ]
        ],
-       {}
+       {
+        "fuzzy": [
+         [
+          [
+           "/css/css-view-transitions/old-content-captures-clip-path.html",
+           "/css/css-view-transitions/old-content-captures-clip-path-ref.html",
+           "=="
+          ],
+          [
+           [
+            0,
+            1
+           ],
+           [
+            0,
+            500
+           ]
+          ]
+         ]
+        ]
+       }
       ]
      ],
      "old-content-captures-different-size.html": [
@@ -248399,6 +248430,19 @@
        {}
       ]
      ],
+     "nth-child-of-pseudo.html": [
+      "7113af901042966053b5484a5a9e3d09139e006d",
+      [
+       null,
+       [
+        [
+         "/css/selectors/nth-child-of-pseudo-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "nth-child-of-tagname.html": [
       "cc92ad6df99c532d69e788710a756b4533a52cc4",
       [
@@ -272696,11 +272740,11 @@
   "support": {
    ".cache": {
     "gitignore2.json": [
-     "377d1e35ab5c0643000fd0964dc0e3b6b4092089",
+     "625733667b0120bef37e4d0cb9f3698c4422d0bb",
      []
     ],
     "mtime.json": [
-     "b38d05a1cf921220c7509b061a382af513c477ff",
+     "42e54ceb0a6807f849953814c0cbb5b7427479b6",
      []
     ]
    },
@@ -287253,10 +287297,6 @@
        "7ff7515baabad81366d3573482094fe0cfd5634e",
        []
       ],
-      "text-align-white-space-003.xht.ini": [
-       "629be9fcc3a4951b5081526f91b2397dd881809a",
-       []
-      ],
       "text-align-white-space-004-ref.xht": [
        "0a8fea56cc682e4bd064a89b5eb1fc4a2bd5dc91",
        []
@@ -289860,6 +289900,10 @@
        ]
       }
      },
+     "box-shadow-border-radius-001.html.ini": [
+      "c4286b08e318ebb98ff965d3c8cd484ad3009a75",
+      []
+     ],
      "box-shadow-calc-ref.html": [
       "3a1c1366d6d18310e8ab86034e62d706f69005ed",
       []
@@ -290337,20 +290381,24 @@
        "d2ae1ebd84b7ed80bcee9e0b457a41c0b8f17cf9",
        []
       ],
-      "box-shadow-inset-spread-without-border-radius.html": [
-       "5e9cf0d34ec1510d8f8c879baf88720b861a75a5",
+      "box-shadow-border-radius-001-notref.html": [
+       "fd0c1eb803613e6eaa78da174b2a5fd1122068d6",
        []
       ],
-      "box-shadow-inset-without-border-radius.html": [
-       "5e9cf0d34ec1510d8f8c879baf88720b861a75a5",
+      "box-shadow-border-radius-001-ref.html": [
+       "ff99f43feec9f2929d381e4682058c36115a293b",
        []
       ],
-      "box-shadow-outset-spread-without-border-radius.html": [
-       "f62399abce0f0c2f745ef63849bc54fcf952cce9",
+      "box-shadow-inset-without-border-radius-ref.html": [
+       "dca329fafe54c0fb5d93887ee29bb80dd0670464",
        []
       ],
-      "box-shadow-outset-without-border-radius.html": [
-       "2bca4c6961b88faaafb8d621ca222faee48256ef",
+      "box-shadow-multiple-001-ref.html": [
+       "ada9dbac1f3587be917f26772b52904885a0277e",
+       []
+      ],
+      "box-shadow-outset-without-border-radius-001-ref.html": [
+       "7dfef37a704d8a8d334da69a61e363137124ae90",
        []
       ],
       "box-shadow-overlapping-001-ref.html": [
@@ -292689,10 +292737,6 @@
        "9f2446cc0e3668b8d01feaf7fe1f4db0c2ce2c0b",
        []
       ],
-      "color-valid-color-mix-function-expected.txt": [
-       "7749c322d17be1529402df805dc108da5e0d0c7d",
-       []
-      ],
       "color-valid-color-mix-function.html.ini": [
        "ed79ae167f43a189efc9c55b3147ade5d7259f78",
        []
@@ -299051,19 +299095,7 @@
       []
      ],
      "font-size-adjust-009-ref.html": [
-      "b0d269a49aec2440878aac4f33aa35eed018e4dc",
-      []
-     ],
-     "font-size-adjust-009.html.ini": [
-      "2396ffafe5922a72d25ef577e4c1c95be59a5e29",
-      []
-     ],
-     "font-size-adjust-010.html.ini": [
-      "0d99bb39aeb445002d1c28f03936e38bd36a53ce",
-      []
-     ],
-     "font-size-adjust-011.html.ini": [
-      "74ab82660d0fad888b654aff65e233919df1dfb9",
+      "2ee9d0a0c8b71353293795c03a57c987e025d857",
       []
      ],
      "font-size-adjust-012-ref.html": [
@@ -309514,6 +309546,10 @@
       "f10e1c18d4989f05c3211463248be2b9619cd724",
       []
      ],
+     "object-view-box-fit-none-video.html.ini": [
+      "2dab034f07a47672161c9c8b920fd386dbdf05ca",
+      []
+     ],
      "object-view-box-iframe-ref.html": [
       "e014e1038154ce09343423166c017a7d090f774d",
       []
@@ -311904,7 +311940,7 @@
        []
       ],
       "clip-path-svg-text-backdrop-filter.html.ini": [
-       "f181a1c6b467fe537f5a8ef866679f16bf4ff355",
+       "3bb4375ab7230eb45c547d7e5932a55a4520e93d",
        []
       ],
       "clip-path-viewBox-1a.html.ini": [
@@ -317736,14 +317772,6 @@
       "f7c0439e202113c9611405ae967b33c2b12cfcee",
       []
      ],
-     "inheritance-expected.txt": [
-      "754ac3af8850d344194fb8b459b17ad2985d8811",
-      []
-     ],
-     "inheritance.html.ini": [
-      "21f956e64d35bf6a21658fbb10d2b0c0aa4e9d42",
-      []
-     ],
      "scrollbar-width-paint-001-ref.html": [
       "42295b1fb9d7d7ef8622c729265e344117c65cc2",
       []
@@ -326826,6 +326854,10 @@
       "e4c1f37541ba79a41f13f80671d8ab4ad2c1644a",
       []
      ],
+     "3d-rendering-context-and-z-ordering-002.html.ini": [
+      "e636573f0c626681e65c626787986f5a07be3c11",
+      []
+     ],
      "3d-scene-with-iframe-001-ref.html": [
       "d984f8a6e9d6f9c221affc07628f8b353dccb010",
       []
@@ -327235,13 +327267,17 @@
       []
      ],
      "preserve3d-and-flattening-003.html.ini": [
-      "2c5b9a6d44e3d5a91bfcaa417ef97f79a66533cd",
+      "b3762732c979988eeee0b1cacbd2932a952a925c",
       []
      ],
      "preserve3d-and-flattening-z-order-001.html.ini": [
       "fbc808b976cbe91346ec7dce66345476d9f41a20",
       []
      ],
+     "preserve3d-and-flattening-z-order-002.html.ini": [
+      "d3268dc41068aa9243c5256b36975e2c3d1173f0",
+      []
+     ],
      "preserve3d-and-flattening-z-order-003.html.ini": [
       "3d7677e07b4db7b35dd0fc2969edae2a8260ce55",
       []
@@ -328318,6 +328354,10 @@
       "9971995a2fddeb0aa4daad1aa8664e19453aa8c2",
       []
      ],
+     "transform3d-backface-visibility-001.html.ini": [
+      "7f82adb90e90bc6ed648754a71ac08f49d3b6fda",
+      []
+     ],
      "transform3d-matrix3d-001-ref.html": [
       "a2d5dc890c00e43ae48c0d53f11ca91b9c398bfc",
       []
@@ -328342,6 +328382,10 @@
       "0585fcd3acddc5a6a669d5c3b73e351caa025c44",
       []
      ],
+     "transform3d-perspective-004.html.ini": [
+      "217679653da39c5666e81ed55af76a3fd97911ed",
+      []
+     ],
      "transform3d-perspective-009-ref.html": [
       "63cdd04d231438551c36d2737b1221372e487181",
       []
@@ -328386,6 +328430,10 @@
       "b719044a5695c1f500144a3423d10a9fa8ba2c3d",
       []
      ],
+     "transform3d-sorting-004.html.ini": [
+      "4a1d7c3f5a8c55beb0457372fa2ce71dbe475102",
+      []
+     ],
      "transform3d-sorting-006-ref.html": [
       "8ed7f552827dad020ed0a943ea4e899a0070cee7",
       []
@@ -330015,6 +330063,10 @@
        "08861083c05fd6e1fb2d809a3e5e8dddb53b63a6",
        []
       ],
+      "kind-of-widget-fallback-color-input-border-right-color-001.html.ini": [
+       "dd18d837cc088805160449c39a60bddf5d5ab1a5",
+       []
+      ],
       "kind-of-widget-fallback-color-input-border-right-width-001.html.ini": [
        "3bc7206ff029796da08852980f2e65ceb93e446f",
        []
@@ -330224,7 +330276,7 @@
        []
       ],
       "kind-of-widget-fallback-input-search-border-block-end-width-001.html.ini": [
-       "01b12488a5a9b1a3900b8a88af5aa28f09582a51",
+       "72865fafceb0da5e06fcccdf8915adca90c13ad2",
        []
       ],
       "kind-of-widget-fallback-input-search-border-block-start-style-001.html.ini": [
@@ -330252,7 +330304,7 @@
        []
       ],
       "kind-of-widget-fallback-input-search-border-image-outset-001.html.ini": [
-       "0094530e1da6fe026786ed868c197c09b4a5d272",
+       "a8737159dd49bc496e550b8297b15829e9d19943",
        []
       ],
       "kind-of-widget-fallback-input-search-border-image-source-001.html.ini": [
@@ -330643,6 +330695,10 @@
        "c74cbe49a808579cbec22c016b1e5e9c9ee0252c",
        []
       ],
+      "kind-of-widget-fallback-input-text-border-bottom-width-001.html.ini": [
+       "ef5ce442a79055f95373365f32372beef5177984",
+       []
+      ],
       "kind-of-widget-fallback-input-text-border-end-start-radius-001.html.ini": [
        "92451e0381a8fd11bb79f27ece56db71b6df57e3",
        []
@@ -330720,7 +330776,7 @@
        []
       ],
       "kind-of-widget-fallback-input-text-border-top-width-001.html.ini": [
-       "e03dc2c460a13ba9d811de331d317028ab346ece",
+       "88c3007a7e34ade785deb8554bf2432ced54789b",
        []
       ],
       "kind-of-widget-fallback-meter-background-attachment-001.html.ini": [
@@ -337776,6 +337832,10 @@
       "572ae31a1cae82377ba0682303da1cb8aa349784",
       []
      ],
+     "css-backdrop-filters-animation-saturate.html.ini": [
+      "0564545e96455f6124541104b5abf6242234a6c5",
+      []
+     ],
      "css-backdrop-filters-animation-sepia-ref.html": [
       "4161d90cc015aadd03956f8ff4724c10139267e0",
       []
@@ -339341,6 +339401,10 @@
        "07617c53ad183adbd4d3f6633b3178d16f820536",
        []
       ],
+      "nth-child-of-attr-largedom.html.ini": [
+       "28f97008ac52ec56f3fe80edf9b3171ad115b26f",
+       []
+      ],
       "nth-child-of-attr-ref.html": [
        "5207cc987d10203bbc7ef282e519462abf0a15fc",
        []
@@ -339492,6 +339556,10 @@
       "94dbc67a851f40879c78735960fece8cba10e820",
       []
      ],
+     "nth-child-of-pseudo-ref.html": [
+      "7e816b5f18875bb18a625ee65ee5b91ee39f4da3",
+      []
+     ],
      "nth-child-of-tagname-ref.html": [
       "99c8262b4f36dd60e9bf6ee1afa5229579eb22a1",
       []
@@ -340466,7 +340534,7 @@
    },
    "docs": {
     "Dockerfile": [
-     "bf5b7088a58b4339980e4c50042501c5e10720a9",
+     "757552686661f8a28d99a1befc7ea1b6626396b8",
      []
     ],
     "META.yml": [
@@ -340613,7 +340681,7 @@
       []
      ],
      "chrome.md": [
-      "45293af65ef3bb0e57cd59ee4f3f44961266df07",
+      "aca93ea2e590c6dbfe6f56618364fbb42cba636e",
       []
      ],
      "chrome_android.md": [
@@ -356454,27 +356522,9 @@
         "2c48d688b6af35ef3c65da7c8cda127b80716571",
         []
        ],
-       "2d.drawImage.svg.html.ini": [
-        "c66b96999799d78e66aa016ffb9ce8fe3445a67e",
-        []
-       ],
        "2d.drawImage.transform.html.ini": [
         "1f76e3507603b3deff7a598af11fe90c7d0ff199",
         []
-       ],
-       "2d.drawImage.zerosource.image.html.ini": [
-        "3f7b04de87c75b45767acb4ad0485be0927ba887",
-        []
-       ]
-      },
-      "fill-and-stroke-styles": {
-       "2d.pattern.paint.repeat.basic.html.ini": [
-        "9fdafd3e170c0fda1e88efc31bd10df6405fa381",
-        []
-       ],
-       "2d.pattern.paint.repeat.outside.html.ini": [
-        "d423abdce00e4b0db64e4dbb737635ac38ea9a4f",
-        []
        ]
       },
       "filters": {
@@ -357038,7 +357088,7 @@
        []
       ],
       "gentestutilsunion.py": [
-       "73c28e30b8182c276123922cd439db2d383aaf8d",
+       "2ffd37461656bc76c49323bee38436d92fc935e1",
        []
       ],
       "name2dir-canvas.yaml": [
@@ -357151,7 +357201,7 @@
         []
        ],
        "compositing.yaml": [
-        "0051f07db23132b0c2ad174dd1ae5918bf9110d6",
+        "bd7fae1d62911835a74cb3315b708bff89ff9562",
         []
        ],
        "conformance_requirements.yaml": [
@@ -357159,7 +357209,7 @@
         []
        ],
        "drawing-images-to-the-canvas.yaml": [
-        "e1837342e6a54d8a88b82af2982edb962d805575",
+        "75eed14ee63c8452a26cbc780fd05e5e907325e5",
         []
        ],
        "drawing-rectangles-to-the-canvas.yaml": [
@@ -357167,11 +357217,11 @@
         []
        ],
        "filters.yaml": [
-        "dd84f913f9ba04480759b9f2010006e97902f13d",
+        "9a90bed24820b7f3aad7f214641f441c2ed78ea1",
         []
        ],
        "layers.yaml": [
-        "fe1902c61b7548a33e8b6d39c35c0c4ce270e85c",
+        "e0d2b3d793b80d70eb31973820ab1564f99e83e3",
         []
        ],
        "line-styles.yaml": [
@@ -357183,7 +357233,7 @@
         []
        ],
        "pixel-manipulation.yaml": [
-        "b9bdf3d2bdb5ca065b7bf58e35c30c09e8ac9405",
+        "0643b047b173f1ea31b87af2c11496618a070380",
         []
        ],
        "reset.yaml": [
@@ -364822,7 +364872,7 @@
          []
         ],
         "resource-selection-invoke-remove-src.html.ini": [
-         "734deff78b64435bc108c71c78264fa800dca4e7",
+         "234eb932ca59c0957d86387054c4abfd3ea6b6d5",
          []
         ],
         "resource-selection-invoke-set-src-not-in-document.html.ini": [
@@ -366692,6 +366742,14 @@
         "62c141d960d27dc59666538b2ec0f185f59c9468",
         []
        ],
+       "input-type-change-value-expected.txt": [
+        "147bdb41027bef210fecb0ea39482d579d760168",
+        []
+       ],
+       "input-type-change-value.html.ini": [
+        "3043141022054dc0f0776776fead982dca04ae8d",
+        []
+       ],
        "input-types.js": [
         "44567510523622ff06f3ffccdd26cd44f864f372",
         []
@@ -371851,6 +371909,10 @@
      "f4c01cfa0f6964b867ddace2c6b4a1c80b081053",
      []
     ],
+    "README.md": [
+     "6491564709fb35a82ab0e2d10592db28b19ebf25",
+     []
+    ],
     "anim-gr.gif": [
      "45263e0afba7b708417510df24cadf70d82d9116",
      []
@@ -371989,6 +372051,38 @@
      "b8c7189d628b7bf761f884bb747ae617595bf235",
      []
     ],
+    "lcp-100x50-alt.png": [
+     "2fdd47cb6d1fafde8ee7ed66cb9b9646b7628d87",
+     []
+    ],
+    "lcp-100x50.png": [
+     "0e4722139e365b5cf31ba2e854bceabd3ea270f5",
+     []
+    ],
+    "lcp-133x106.png": [
+     "fb61e8db851e3e41d57efb57cc0c5c6c0fe16efc",
+     []
+    ],
+    "lcp-16x16.png": [
+     "f8ca4fae684a81b1677e354fa98720c6e0b24c86",
+     []
+    ],
+    "lcp-1x1.png": [
+     "82863b859ac841c8886dabdc92d957e7e2fd5290",
+     []
+    ],
+    "lcp-256x256.png": [
+     "944f10f87611dbc623691a304a32f630da426486",
+     []
+    ],
+    "lcp-2x2.png": [
+     "5b628e0734c1e7a3a9b414850237e658aafdb9c1",
+     []
+    ],
+    "lcp-96x96.png": [
+     "66464b77575e882aaf79edba88c3e6fc507e3625",
+     []
+    ],
     "movie_300_frame_0.png": [
      "b712825093805d1052b01047b1dbb102f0af8f0f",
      []
@@ -374385,7 +374479,7 @@
       []
      ],
      "mouseover-utils.js": [
-      "1836f2e4ad2ae3b169ffc59abc1b7955f91fb255",
+      "60a29ed04e5d3c67909f8154f4fe08829f9548c9",
       []
      ],
      "slow-style-change.py": [
@@ -374495,7 +374589,7 @@
     ]
    },
    "lint.ignore": [
-    "1672f3b52e7a09b0e98ff6bd14c1ca6a9a5ab160",
+    "4e52e323fd9e43652b3a1547857801de3fe6b5f6",
     []
    ],
    "loading": {
@@ -376445,7 +376539,7 @@
       []
      ],
      "mediasource-worker-play-terminate-worker.html.ini": [
-      "2c24a1f5577efe79802d1318ddb4337287a57956",
+      "391c16b580089c638ce0ea12e9cb14812932d80d",
       []
      ],
      "mediasource-worker-play-terminate-worker.js": [
@@ -380642,7 +380736,7 @@
      []
     ],
     "modulepreload-as.html.ini": [
-     "134da6c83de85fe85c900b0bfbb70c0cd29ffbe1",
+     "6657dedfacc2444a0f84587f235c508209d882f8",
      []
     ],
     "modulepreload-expected.txt": [
@@ -392834,11 +392928,11 @@
      []
     ],
     "a-element-origin-xhtml.xhtml.ini": [
-     "a84d07fe94890abb32fde586da2b0cca9d805514",
+     "3661cc2bb8968b7401bb84501eb01f3780783f34",
      []
     ],
     "a-element-origin.html.ini": [
-     "e0447aac473a845a905d89564bedf854bdbd38d5",
+     "845c5c54aa21b48d306b27dac92a8f0b464c27ab",
      []
     ],
     "a-element-xhtml.xhtml.ini": [
@@ -392927,7 +393021,7 @@
       []
      ],
      "urltestdata.json": [
-      "58f6b87a8624bf024bef48fa16b21cbbb755aa5c",
+      "680d2b9434c7f720da4f2d7e9ddc4d688b09dade",
       []
      ]
     },
@@ -392966,7 +393060,7 @@
      []
     ],
     "url-origin.any.js.ini": [
-     "837c7c2b264f0a8d2bdbda8ff05aee3ee6f9ec2d",
+     "ed88ccce01c6f9e8b112fa180473be8928f253c9",
      []
     ],
     "url-setters-a-area.window.js.ini": [
@@ -394848,7 +394942,7 @@
      []
     ],
     "OWNERS": [
-     "a7db251a2d396b1de2de484e6fe2888e2f927068",
+     "32f919a5312cdacd356c3e59b4fbaa170a84e7f0",
      []
     ],
     "README.md": [
@@ -395536,420 +395630,454 @@
       "0ba172ff2e2734e5cbf324e816867be0a26b278e",
       []
      ],
-     "accept_alert": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "add_cookie": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "back": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ],
-      "conftest.py": [
-       "bd5db0cfeba7bbc8aaf23c3151109cf48094ff09",
-       []
-      ]
-     },
-     "close_window": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
+     "classic": {
+      "accept_alert": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "add_cookie": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "back": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ],
+       "conftest.py": [
+        "bd5db0cfeba7bbc8aaf23c3151109cf48094ff09",
+        []
+       ]
+      },
+      "close_window": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "delete_all_cookies": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "delete_cookie": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "delete_session": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "dismiss_alert": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "element_clear": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "element_click": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ],
+       "support": {
+        "input.html": [
+         "e2c6dadd1218e0a7d8b7d243a1c49b7f47092d77",
+         []
+        ],
+        "test_click_wdspec.html": [
+         "a9451ec82bec97654896f697704218bb6068d14e",
+         []
+        ]
+       }
+      },
+      "element_send_keys": {
+       "__init__.py": [
+        "a7facf6fcf70309251757e3fb90b89255e13133f",
+        []
+       ],
+       "conftest.py": [
+        "17bdd162a772bb0a5a4d14a2c2627a25ded9eca3",
+        []
+       ]
+      },
+      "execute_async_script": {
+       "__init__.py": [
+        "9cd37ecdca13921d71b70c9ce335e93fc0e0d799",
+        []
+       ]
+      },
+      "execute_script": {
+       "__init__.py": [
+        "1ab36eb054143df81bd41140f844916d9e2949c1",
+        []
+       ]
+      },
+      "find_element": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "find_element_from_element": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "find_element_from_shadow_root": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "find_elements": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "find_elements_from_element": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "find_elements_from_shadow_root": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "forward": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ],
+       "conftest.py": [
+        "bd5db0cfeba7bbc8aaf23c3151109cf48094ff09",
+        []
+       ]
+      },
+      "fullscreen_window": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_active_element": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_alert_text": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_computed_label": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_computed_role": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_current_url": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_element_attribute": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_element_css_value": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_element_property": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_element_rect": {
+       "__init__.py": [
+        "8b137891791fe96927ad78e64b0aad7bded08bdc",
+        []
+       ]
+      },
+      "get_element_shadow_root": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_element_tag_name": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_element_text": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_named_cookie": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_page_source": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_timeouts": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_title": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_window_handle": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_window_handles": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "get_window_rect": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "is_element_enabled": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "is_element_selected": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "maximize_window": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "minimize_window": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "navigate_to": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "new_session": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ],
+       "conftest.py": [
+        "d67fdba449dea79fb5113b39f795d874a53ffc40",
+        []
+       ],
+       "support": {
+        "__init__.py": [
+         "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+         []
+        ],
+        "create.py": [
+         "a0d0ce37b57d396621729c2966748514039e84ad",
+         []
+        ]
+       }
+      },
+      "new_window": {
+       "__init__.py": [
+        "e16014597cf88f465e910358c27f72381292bd6d",
+        []
+       ]
+      },
+      "perform_actions": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ],
+       "conftest.py": [
+        "0694cce494f25df68c4def8aec170586adb0f7d4",
+        []
+       ],
+       "support": {
+        "__init__.py": [
+         "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+         []
+        ],
+        "mouse.py": [
+         "b3672eb213af68a9e4d9f931ca6499723a1a5019",
+         []
+        ],
+        "refine.py": [
+         "35c962b9ecbfa21c61535683c094e17884770e9f",
+         []
+        ]
+       }
+      },
+      "permissions": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "print": {
+       "__init__.py": [
+        "eb9a890cc45592c0566b0004440225d162332687",
+        []
+       ]
+      },
+      "refresh": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "release_actions": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ],
+       "conftest.py": [
+        "8275efc23b70de3f06eb9d081d4fa2d3c13d7fc5",
+        []
+       ],
+       "support": {
+        "__init__.py": [
+         "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+         []
+        ],
+        "refine.py": [
+         "d40520974938b1dd226021be40a79e1661860249",
+         []
+        ]
+       }
+      },
+      "send_alert_text": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ],
+       "conftest.py": [
+        "b080761bde881d236aed87dbfcd03963051ba443",
+        []
+       ]
+      },
+      "set_timeouts": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "set_window_rect": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "status": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "switch_to_frame": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "switch_to_parent_frame": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "switch_to_window": {
+       "__init__.py": [
+        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+        []
+       ]
+      },
+      "take_element_screenshot": {
+       "__init__.py": [
+        "9a82cc48eab7993dcd6588d89b5aae9ed4ebfc82",
+        []
+       ]
+      },
+      "take_screenshot": {
+       "__init__.py": [
+        "f3001d946df56e58c4e3fa1319db12bf29f3e341",
+        []
+       ]
+      }
      },
      "conftest.py": [
       "fe9f5cd268240662d0d7a6753e58a7fbedecad4e",
       []
      ],
-     "delete_all_cookies": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "delete_cookie": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "delete_session": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "dismiss_alert": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "element_clear": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "element_click": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ],
-      "support": {
-       "input.html": [
-        "e2c6dadd1218e0a7d8b7d243a1c49b7f47092d77",
-        []
-       ],
-       "test_click_wdspec.html": [
-        "a9451ec82bec97654896f697704218bb6068d14e",
-        []
-       ]
-      }
-     },
-     "element_send_keys": {
-      "__init__.py": [
-       "a7facf6fcf70309251757e3fb90b89255e13133f",
-       []
-      ],
-      "conftest.py": [
-       "17bdd162a772bb0a5a4d14a2c2627a25ded9eca3",
-       []
-      ]
-     },
-     "execute_async_script": {
-      "__init__.py": [
-       "9cd37ecdca13921d71b70c9ce335e93fc0e0d799",
-       []
-      ]
-     },
-     "execute_script": {
-      "__init__.py": [
-       "1ab36eb054143df81bd41140f844916d9e2949c1",
-       []
-      ]
-     },
-     "find_element": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "find_element_from_element": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "find_element_from_shadow_root": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "find_elements": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "find_elements_from_element": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "find_elements_from_shadow_root": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "forward": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ],
-      "conftest.py": [
-       "bd5db0cfeba7bbc8aaf23c3151109cf48094ff09",
-       []
-      ]
-     },
-     "fullscreen_window": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_active_element": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_alert_text": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_computed_label": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_computed_role": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_current_url": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_element_attribute": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_element_css_value": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_element_property": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_element_rect": {
-      "__init__.py": [
-       "8b137891791fe96927ad78e64b0aad7bded08bdc",
-       []
-      ]
-     },
-     "get_element_shadow_root": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_element_tag_name": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_element_text": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_named_cookie": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_page_source": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_timeouts": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_title": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_window_handle": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_window_handles": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "get_window_rect": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "is_element_enabled": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "is_element_selected": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "maximize_window": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "minimize_window": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "navigate_to": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "new_session": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ],
-      "conftest.py": [
-       "d67fdba449dea79fb5113b39f795d874a53ffc40",
-       []
-      ],
-      "support": {
-       "__init__.py": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "create.py": [
-        "a0d0ce37b57d396621729c2966748514039e84ad",
-        []
-       ]
-      }
-     },
-     "new_window": {
-      "__init__.py": [
-       "e16014597cf88f465e910358c27f72381292bd6d",
-       []
-      ]
-     },
      "perform_actions": {
       "DIR_METADATA": [
        "71b1a71b1fc10f62a9c9b29c86269a4b75f64892",
        []
-      ],
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ],
-      "conftest.py": [
-       "0694cce494f25df68c4def8aec170586adb0f7d4",
-       []
-      ],
-      "support": {
-       "__init__.py": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "mouse.py": [
-        "b3672eb213af68a9e4d9f931ca6499723a1a5019",
-        []
-       ],
-       "refine.py": [
-        "35c962b9ecbfa21c61535683c094e17884770e9f",
-        []
-       ]
-      }
-     },
-     "permissions": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "print": {
-      "__init__.py": [
-       "eb9a890cc45592c0566b0004440225d162332687",
-       []
-      ]
-     },
-     "refresh": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "release_actions": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ],
-      "conftest.py": [
-       "8275efc23b70de3f06eb9d081d4fa2d3c13d7fc5",
-       []
-      ],
-      "support": {
-       "__init__.py": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "refine.py": [
-        "d40520974938b1dd226021be40a79e1661860249",
-        []
-       ]
-      }
-     },
-     "send_alert_text": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ],
-      "conftest.py": [
-       "b080761bde881d236aed87dbfcd03963051ba443",
-       []
-      ]
-     },
-     "set_timeouts": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "set_window_rect": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "status": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
       ]
      },
      "support": {
@@ -396081,36 +396209,6 @@
        "015ebd37a0966860a452a6f69420ba6787b4877e",
        []
       ]
-     },
-     "switch_to_frame": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "switch_to_parent_frame": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "switch_to_window": {
-      "__init__.py": [
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-       []
-      ]
-     },
-     "take_element_screenshot": {
-      "__init__.py": [
-       "9a82cc48eab7993dcd6588d89b5aae9ed4ebfc82",
-       []
-      ]
-     },
-     "take_screenshot": {
-      "__init__.py": [
-       "f3001d946df56e58c4e3fa1319db12bf29f3e341",
-       []
-      ]
      }
     }
    },
@@ -443892,7 +443990,7 @@
        ]
       ],
       "color-valid-color-mix-function.html": [
-       "659117a23b0ddd073d7f8a243e4f2dd86a7e4bff",
+       "1df42804996f3e23daf5bec7752a31e2b7ae1ec8",
        [
         null,
         {}
@@ -444735,6 +444833,13 @@
         {}
        ]
       ],
+      "nested-size-style-container-invalidation.html": [
+       "8d04bf589a2e03e2f89b69c69f0d5d3a38a2872f",
+       [
+        null,
+        {}
+       ]
+      ],
       "never-match-container.html": [
        "9d5ff6d2272c809cd2b95aeedb3b86896c469e37",
        [
@@ -458298,6 +458403,13 @@
        {}
       ]
      ],
+     "scrollbar-color-parsing.html": [
+      "17b649d54c8f12cb490bdd732770c95cec02273d",
+      [
+       null,
+       {}
+      ]
+     ],
      "scrollbar-width-001.html": [
       "21dfd3d1165ffeba35762a35f41014ff33042635",
       [
@@ -542312,12 +542424,464 @@
        ]
       ],
       "shared-worker.https.window.js": [
-       "0bfa72e2e5464ed060789ee9eef98f8847167619",
+       "5e259a5acc9731aace980cd99385caa951242c1d",
        [
-        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html",
+        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless",
         {
          "script_metadata": [
           [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "script",
+           "/common/get-host-info.sub.js"
+          ],
+          [
+           "script",
+           "/common/utils.js"
+          ],
+          [
+           "script",
+           "/common/dispatcher/dispatcher.js"
+          ],
+          [
+           "script",
+           "./resources/common.js"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html?request_origin=cross_origin&worker_coep=credentialless&window_coep=none",
+        {
+         "script_metadata": [
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "script",
+           "/common/get-host-info.sub.js"
+          ],
+          [
+           "script",
+           "/common/utils.js"
+          ],
+          [
+           "script",
+           "/common/dispatcher/dispatcher.js"
+          ],
+          [
+           "script",
+           "./resources/common.js"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html?request_origin=cross_origin&worker_coep=none&window_coep=credentialless",
+        {
+         "script_metadata": [
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "script",
+           "/common/get-host-info.sub.js"
+          ],
+          [
+           "script",
+           "/common/utils.js"
+          ],
+          [
+           "script",
+           "/common/dispatcher/dispatcher.js"
+          ],
+          [
+           "script",
+           "./resources/common.js"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html?request_origin=cross_origin&worker_coep=none&window_coep=none",
+        {
+         "script_metadata": [
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "script",
+           "/common/get-host-info.sub.js"
+          ],
+          [
+           "script",
+           "/common/utils.js"
+          ],
+          [
+           "script",
+           "/common/dispatcher/dispatcher.js"
+          ],
+          [
+           "script",
+           "./resources/common.js"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless",
+        {
+         "script_metadata": [
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "script",
+           "/common/get-host-info.sub.js"
+          ],
+          [
+           "script",
+           "/common/utils.js"
+          ],
+          [
+           "script",
+           "/common/dispatcher/dispatcher.js"
+          ],
+          [
+           "script",
+           "./resources/common.js"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html?request_origin=same_origin&worker_coep=credentialless&window_coep=none",
+        {
+         "script_metadata": [
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "script",
+           "/common/get-host-info.sub.js"
+          ],
+          [
+           "script",
+           "/common/utils.js"
+          ],
+          [
+           "script",
+           "/common/dispatcher/dispatcher.js"
+          ],
+          [
+           "script",
+           "./resources/common.js"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html?request_origin=same_origin&worker_coep=none&window_coep=credentialless",
+        {
+         "script_metadata": [
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "script",
+           "/common/get-host-info.sub.js"
+          ],
+          [
+           "script",
+           "/common/utils.js"
+          ],
+          [
+           "script",
+           "/common/dispatcher/dispatcher.js"
+          ],
+          [
+           "script",
+           "./resources/common.js"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.html?request_origin=same_origin&worker_coep=none&window_coep=none",
+        {
+         "script_metadata": [
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=none&window_coep=credentialless"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=none"
+          ],
+          [
+           "variant",
+           "?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless"
+          ],
+          [
            "timeout",
            "long"
           ],
@@ -555719,6 +556283,13 @@
          {}
         ]
        ],
+       "input-type-change-value.html": [
+        "74aeef7cd514c4994e60495cc1247fe8c7c5333f",
+        [
+         null,
+         {}
+        ]
+       ],
        "input-type-checkbox.html": [
         "7dd2f26b12c459405b8e6c59563f09cc1ec15c0c",
         [
@@ -557819,7 +558390,7 @@
        ]
       ],
       "popover-light-dismiss.html": [
-       "4b888169e1becc6daca007a6d6e71df0004e8049",
+       "59a12a2c9ac18e8eefe603c481057074541109a5",
        [
         null,
         {
@@ -570481,7 +571052,7 @@
      ]
     ],
     "idlharness.html": [
-     "84d1c7ff9aea26fe7b5810b3d236213d8fac6a5a",
+     "5f5d286b356cf5dcffd76f2ed6f689804e8426ba",
      [
       null,
       {}
@@ -570502,7 +571073,7 @@
      ]
     ],
     "image-full-viewport.html": [
-     "e67e21a17c7d743e632c15770eafa8fe23cc1f6c",
+     "2f8e17fb3220729eb1ee8841efdb9d3bcc8256d0",
      [
       null,
       {}
@@ -570516,14 +571087,14 @@
      ]
     ],
     "image-not-fully-visible.html": [
-     "1aee495fe194fb3defb1b3296564bd90a76e264a",
+     "514a424f68ec55f01269be8016ae86cf84f2c522",
      [
       null,
       {}
      ]
     ],
     "image-removed-before-load.html": [
-     "3e557a4fdc77266e8462047dc03658ac450ad79f",
+     "08e5ee56dba1507cab5d444f01bcbaa18c675d68",
      [
       null,
       {}
@@ -570551,7 +571122,7 @@
      ]
     ],
     "initially-invisible-images.html": [
-     "b4d68a5cb9230232781b88bf1f37b8c19a38e35e",
+     "061a0140d10c5e070a560edb76ebd2045454a4e2",
      [
       null,
       {}
@@ -570579,14 +571150,14 @@
      ]
     ],
     "larger-image.html": [
-     "948f00d0c61d4bd5e78b6c577fa007c5f3519562",
+     "9415cbc32fa8092c7206d030246b7e35980a7556",
      [
       null,
       {}
      ]
     ],
     "larger-text.html": [
-     "8758c1c839b5f725e6d15ea6ec6ac7375cf78a49",
+     "c577899eccbd97cca9730b3849d9e5a20473e549",
      [
       null,
       {}
@@ -570600,7 +571171,7 @@
      ]
     ],
     "mouseover-heuristics-background.tentative.html": [
-     "16cbd0f0cb9ac90ff741f431350dea546ac2269c",
+     "ddd4f9672e78e5e0ede5ec94fbdbd352081e670d",
      [
       null,
       {
@@ -570609,7 +571180,7 @@
      ]
     ],
     "mouseover-heuristics-element.tentative.html": [
-     "bbd87235e826af4518c869c19920d21dba05cd86",
+     "afc4b2a50d6bdbe63039b2bec42225dd873f1355",
      [
       null,
       {
@@ -570653,7 +571224,7 @@
      ]
     ],
     "non-tao-image-subsequent-lcp-candidate.tentative.html": [
-     "50f9a229ea6bd99c38e2a40ab4219c1eb96e3cf5",
+     "4d799c1b05af386a946fdd2eaf1041df555d21e0",
      [
       null,
       {}
@@ -570716,7 +571287,7 @@
      ]
     ],
     "placeholder-image.html": [
-     "6a2ce5c7c6df636e7003e7c69a58e65eb444f454",
+     "06691cef22e507fc21d9b381d963268d118856da",
      [
       null,
       {}
@@ -584857,7 +585428,7 @@
       ]
      ],
      "pointerevent_mouse-on-object.html": [
-      "78edfbde1b81d963e767e36bca0faf9133b935d8",
+      "27142a4f59c1b8448dab3d1c47ca62ea1f54587a",
       [
        null,
        {
@@ -611258,7 +611829,7 @@
      ]
     ],
     "image-lcp-followed-by-image-softnav-lcp.tentative.html": [
-     "27e9bbbd13c6c9affad7bbd4b0aa3cdad2d0b3bb",
+     "7a2018d20ee811ff1ec9ca88c80038b0f1239874",
      [
       null,
       {
@@ -611267,7 +611838,7 @@
      ]
     ],
     "image-lcp-followed-by-text-softnav-lcp.tentative.html": [
-     "5aa1b1da2ef1c1fecddedbef0067a1a24167c9fa",
+     "501d1c5fb6fa0346f3c5cecd550001f933c9f1f1",
      [
       null,
       {
@@ -611276,7 +611847,7 @@
      ]
     ],
     "image-lcp-followed-by-two-image-softnavs-lcp.tentative.html": [
-     "7f5bafb5e685d9c07eb16663af823d0f06e9023e",
+     "1489ae1a94a811c9f098f0fca97edc50b53692ba",
      [
       null,
       {
@@ -638757,24 +639328,26 @@
    },
    "webdriver": {
     "tests": {
-     "idlharness.window.js": [
-      "e92e151d89836e06966339daabc6b1be50ded744",
-      [
-       "webdriver/tests/idlharness.window.html",
-       {
-        "script_metadata": [
-         [
-          "script",
-          "/resources/WebIDLParser.js"
-         ],
-         [
-          "script",
-          "/resources/idlharness.js"
+     "classic": {
+      "idlharness.window.js": [
+       "e92e151d89836e06966339daabc6b1be50ded744",
+       [
+        "webdriver/tests/classic/idlharness.window.html",
+        {
+         "script_metadata": [
+          [
+           "script",
+           "/resources/WebIDLParser.js"
+          ],
+          [
+           "script",
+           "/resources/idlharness.js"
+          ]
          ]
-        ]
-       }
+        }
+       ]
       ]
-     ]
+     }
     }
    },
    "webhid": {
@@ -679220,1450 +679793,1533 @@
    },
    "webdriver": {
     "tests": {
-     "accept_alert": {
-      "accept.py": [
-       "b83477e5ca7247913e33abda0315a66ee0c0b3ff",
-       [
-        null,
-        {}
+     "classic": {
+      "accept_alert": {
+       "accept.py": [
+        "b83477e5ca7247913e33abda0315a66ee0c0b3ff",
+        [
+         null,
+         {}
+        ]
        ]
-      ]
-     },
-     "add_cookie": {
-      "add.py": [
-       "3a19432fc6a243544bcd6b8d9b13ffc01e185eaf",
-       [
-        null,
-        {}
+      },
+      "add_cookie": {
+       "add.py": [
+        "3a19432fc6a243544bcd6b8d9b13ffc01e185eaf",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "f58aacd02a71d73112fcb6140c6b766919f9b85f",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "f58aacd02a71d73112fcb6140c6b766919f9b85f",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "back": {
+       "back.py": [
+        "62434323e0ad5339a861d0752d29f7d1f95c81cc",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "9d04f0f4ab12d98f0313639013fce4f26869a753",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "back": {
-      "back.py": [
-       "62434323e0ad5339a861d0752d29f7d1f95c81cc",
-       [
-        null,
-        {}
+      },
+      "close_window": {
+       "close.py": [
+        "7b382fa9bbcb297081027391e9ac052840be48f7",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "c0f9cc7610c21ea97064392eb2e09fce6f853bbc",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "9d04f0f4ab12d98f0313639013fce4f26869a753",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "delete_all_cookies": {
+       "delete.py": [
+        "86d66561b00c27100e3b205e6089074f50098d87",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "dca4f3c8bf6473e7fb767519d7f4a9417503f044",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "close_window": {
-      "close.py": [
-       "7b382fa9bbcb297081027391e9ac052840be48f7",
-       [
-        null,
-        {}
+      },
+      "delete_cookie": {
+       "delete.py": [
+        "4b37c0453b990483a51c62a82a6ed44667ba9edf",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "1ed7db6e8e320575ffa99ec2f7b7cf2cfeb0ee6a",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "c0f9cc7610c21ea97064392eb2e09fce6f853bbc",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "delete_session": {
+       "delete.py": [
+        "a3032cc13475bf2980b360d9d140e2d2f58a9034",
+        [
+         null,
+         {}
+        ]
        ]
-      ]
-     },
-     "delete_all_cookies": {
-      "delete.py": [
-       "86d66561b00c27100e3b205e6089074f50098d87",
-       [
-        null,
-        {}
+      },
+      "dismiss_alert": {
+       "dismiss.py": [
+        "a28dec768750fef214027534a8e6f18cbc7034c8",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "dca4f3c8bf6473e7fb767519d7f4a9417503f044",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "element_clear": {
+       "clear.py": [
+        "9b0d7f2133f7686603449897c659c7e4220ec746",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "user_prompts.py": [
+        "7a8564a684a7edc5d1af0812b3353f2f5ccba629",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "delete_cookie": {
-      "delete.py": [
-       "4b37c0453b990483a51c62a82a6ed44667ba9edf",
-       [
-        null,
-        {}
+      },
+      "element_click": {
+       "bubbling.py": [
+        "7620ec3224fc228e57fe42614d978bbb48b0a97a",
+        [
+         null,
+         {}
+        ]
+       ],
+       "center_point.py": [
+        "eb5cc19f14f80b586a731574c1da7963364422d7",
+        [
+         null,
+         {}
+        ]
+       ],
+       "click.py": [
+        "3c3f7d70e6c6b23932e7452f73e160a2d213a5ba",
+        [
+         null,
+         {}
+        ]
+       ],
+       "events.py": [
+        "30f2dfa0a4a9b5f643832d751f0b35ecfff89fc2",
+        [
+         null,
+         {}
+        ]
+       ],
+       "file_upload.py": [
+        "73832d0f85ae683ee2d1f54e9c0b7e3e432e9afd",
+        [
+         null,
+         {}
+        ]
+       ],
+       "interactability.py": [
+        "d55860c8746f33ba86468fbfc9952363f01e7110",
+        [
+         null,
+         {}
+        ]
+       ],
+       "navigate.py": [
+        "4d1c48235ca176554375ebd26fb4d96aabad4d4d",
+        [
+         null,
+         {}
+        ]
+       ],
+       "scroll_into_view.py": [
+        "c2dc6485286efc1f65679772d515c31c0d584686",
+        [
+         null,
+         {}
+        ]
+       ],
+       "select.py": [
+        "62d40755b59bc39c8dc4650a03c7ad7127c31013",
+        [
+         null,
+         {}
+        ]
+       ],
+       "shadow_dom.py": [
+        "18768a60b292816a904fdfa4d2805755c5f98034",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "140aceb3cedfe84ec8f9a3ac0285497b6e670285",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "1ed7db6e8e320575ffa99ec2f7b7cf2cfeb0ee6a",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "element_send_keys": {
+       "content_editable.py": [
+        "9db19d5b8a2da810b603b369cf1981e036790177",
+        [
+         null,
+         {}
+        ]
+       ],
+       "events.py": [
+        "4be1432bf3c2e02c8ea8a9f7bb034f9739ed0de6",
+        [
+         null,
+         {}
+        ]
+       ],
+       "file_upload.py": [
+        "f62a633c202d6fca8d5062ae6b15e2df8b20783c",
+        [
+         null,
+         {}
+        ]
+       ],
+       "form_controls.py": [
+        "364d4c28fae7807f109cdcdc32aead43d985a1fe",
+        [
+         null,
+         {}
+        ]
+       ],
+       "interactability.py": [
+        "273843fb7b46a31aadf6387ad4815b58a251b4ea",
+        [
+         null,
+         {}
+        ]
+       ],
+       "scroll_into_view.py": [
+        "7ccaeaf8142011ccbe7830876147d73853d0b07a",
+        [
+         null,
+         {}
+        ]
+       ],
+       "send_keys.py": [
+        "281c7ad719ddd05dac2ab7c6de343e9bebde4a5b",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "c1046840fa4ef24a5e063d09aee8c58803e835f7",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "delete_session": {
-      "delete.py": [
-       "a3032cc13475bf2980b360d9d140e2d2f58a9034",
-       [
-        null,
-        {}
+      },
+      "execute_async_script": {
+       "arguments.py": [
+        "ead6e0c186ea40771643aea56ccc7180e6cc28d7",
+        [
+         null,
+         {}
+        ]
+       ],
+       "collections.py": [
+        "5dfbf2059470a2f17604a0a3d9bf47f905bca82e",
+        [
+         null,
+         {}
+        ]
+       ],
+       "cyclic.py": [
+        "ff536f3477c497dce59d60b26834ef986e971c2b",
+        [
+         null,
+         {}
+        ]
+       ],
+       "execute_async.py": [
+        "42cf4aacee8342939c515b5e56a40ef15a1cacfb",
+        [
+         null,
+         {}
+        ]
+       ],
+       "node.py": [
+        "53abda4b300597ade2f5b8d38260caad9cb17f31",
+        [
+         null,
+         {}
+        ]
+       ],
+       "objects.py": [
+        "edcf06505aac243ac54ecf7195887fed387c892f",
+        [
+         null,
+         {}
+        ]
+       ],
+       "promise.py": [
+        "d726d0d71283033086b1ca8851b444968654876b",
+        [
+         null,
+         {}
+        ]
+       ],
+       "properties.py": [
+        "b9592e7edd40a5d4225fc0fc7d2c6bbade01307e",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "e39574fd4ac1b734006614c4ab6caf0a9542676b",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "dismiss_alert": {
-      "dismiss.py": [
-       "a28dec768750fef214027534a8e6f18cbc7034c8",
-       [
-        null,
-        {}
+      },
+      "execute_script": {
+       "arguments.py": [
+        "b8657ce0efae2a266158bb8c2846864cd63c1d5e",
+        [
+         null,
+         {}
+        ]
+       ],
+       "collections.py": [
+        "ec5d5ee1e32beb19b799b633534ec31fcfb0c7ad",
+        [
+         null,
+         {}
+        ]
+       ],
+       "cyclic.py": [
+        "29db2f27e669a9e7b0c2068c09b6d9bb3b5e1f07",
+        [
+         null,
+         {}
+        ]
+       ],
+       "execute.py": [
+        "fbccc98633867b9ab137b26f0f8818b98a29c81f",
+        [
+         null,
+         {}
+        ]
+       ],
+       "json_serialize_windowproxy.py": [
+        "8e76feda23809bf65a77c6bcd3994209aaba40e0",
+        [
+         null,
+         {}
+        ]
+       ],
+       "node.py": [
+        "caf85988f15413eca765c5d5cb019b06777d3b9d",
+        [
+         null,
+         {}
+        ]
+       ],
+       "objects.py": [
+        "e254fe275e26f1adda0cf6f4898616703302e2da",
+        [
+         null,
+         {}
+        ]
+       ],
+       "promise.py": [
+        "c206674baefc75d23443fb5b7999ef465b09a3e2",
+        [
+         null,
+         {}
+        ]
+       ],
+       "properties.py": [
+        "c3b01dea29b5a160cda24ea82d0135cb1761032b",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "48d735ea754c0f74726d5a89f43eabb245b8bc5a",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "element_clear": {
-      "user_prompts.py": [
-       "7a8564a684a7edc5d1af0812b3353f2f5ccba629",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "find_element": {
+       "find.py": [
+        "50de92554bcb29659d5a5b842ef12a485a0cde3a",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "ada8e8ebee33a6ce9fcfb4871093ce1eef1d1dae",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "element_click": {
-      "bubbling.py": [
-       "7620ec3224fc228e57fe42614d978bbb48b0a97a",
-       [
-        null,
-        {}
+      },
+      "find_element_from_element": {
+       "find.py": [
+        "102704cd8e318c69f51a762d3eda2b125eed23ae",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "0537a786189c41420f50e6c3b747482c331fdaa3",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "center_point.py": [
-       "eb5cc19f14f80b586a731574c1da7963364422d7",
-       [
-        null,
-        {}
+      },
+      "find_element_from_shadow_root": {
+       "find.py": [
+        "62a5bc60f543aa06aff658056c23117cb2d9cf85",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "3e3381e7853b25577a0f465542c848c9429e3099",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "click.py": [
-       "3c3f7d70e6c6b23932e7452f73e160a2d213a5ba",
-       [
-        null,
-        {}
+      },
+      "find_elements": {
+       "find.py": [
+        "0d9ce21186c9a6963018d4dc819038749758ff47",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "f9a45e527515fc7448162a86dca69d3f95e76491",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "events.py": [
-       "e3d32c1bcb44c7eb3b810fbce5ca0709c97abcd9",
-       [
-        null,
-        {}
+      },
+      "find_elements_from_element": {
+       "find.py": [
+        "fc898bc95afecd71535bca0f23d375a1c3738299",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "467bec09a1bd61346b3df2fa5b0b8c16e02fe975",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "file_upload.py": [
-       "73832d0f85ae683ee2d1f54e9c0b7e3e432e9afd",
-       [
-        null,
-        {}
+      },
+      "find_elements_from_shadow_root": {
+       "find.py": [
+        "db739fd440fc3e7724f740fa5bd04772cc0d9488",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "45986ad6dab9322ca7126050d623904d2542e338",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "navigate.py": [
-       "492718292a178e5bfe242d75acad4b6efc3cbf71",
-       [
-        null,
-        {}
+      },
+      "forward": {
+       "forward.py": [
+        "f27be403f9e95bd2359d5ae6224f6ae2708ff7c8",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "3eeaf6e71cdb7311614b271257f4cd6d19a2e619",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "scroll_into_view.py": [
-       "c2dc6485286efc1f65679772d515c31c0d584686",
-       [
-        null,
-        {}
+      },
+      "fullscreen_window": {
+       "fullscreen.py": [
+        "94f25ed9bdbd4a9cf619982f9b02582b5c137335",
+        [
+         null,
+         {}
+        ]
+       ],
+       "stress.py": [
+        "b907a31f17e0167ff27a4e8ceb2ad44cd372b537",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "user_prompts.py": [
+        "106bc457f0c18769afe1d9f76c39937d17783666",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "select.py": [
-       "62d40755b59bc39c8dc4650a03c7ad7127c31013",
-       [
-        null,
-        {}
+      },
+      "get_active_element": {
+       "get.py": [
+        "1d2960c88c5f587bf2dea86f5b97ad1e5fae9b5c",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "1ff77697b707886bbfeaee8acf08bdb8aba2de38",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "shadow_dom.py": [
-       "18768a60b292816a904fdfa4d2805755c5f98034",
-       [
-        null,
-        {}
+      },
+      "get_alert_text": {
+       "get.py": [
+        "7ee7ff1808f928e67ab0e3423c13a885e28db08f",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "140aceb3cedfe84ec8f9a3ac0285497b6e670285",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "get_computed_label": {
+       "get.py": [
+        "0dc00a471a9a37509e4ed7a448c1213bb978eeda",
+        [
+         null,
+         {}
+        ]
        ]
-      ]
-     },
-     "element_send_keys": {
-      "content_editable.py": [
-       "9db19d5b8a2da810b603b369cf1981e036790177",
-       [
-        null,
-        {}
+      },
+      "get_computed_role": {
+       "get.py": [
+        "51b6a8b3b6d1e302be8885e4b2976cc0c02ff4bd",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "events.py": [
-       "4be1432bf3c2e02c8ea8a9f7bb034f9739ed0de6",
-       [
-        null,
-        {}
+      },
+      "get_current_url": {
+       "file.py": [
+        "ef6ae2383550330bfd41c10fffb41b4545d7007d",
+        [
+         null,
+         {}
+        ]
+       ],
+       "get.py": [
+        "baeab0960b6860579a7e648c650dffc4c548fa67",
+        [
+         null,
+         {}
+        ]
+       ],
+       "iframe.py": [
+        "80a960ce8a15e831941b4bf97ab6375b64b70ea7",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "d657c188241d8e0b53153d6b0e64fd386642847a",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "file_upload.py": [
-       "f62a633c202d6fca8d5062ae6b15e2df8b20783c",
-       [
-        null,
-        {}
+      },
+      "get_element_attribute": {
+       "get.py": [
+        "375f25032c06a10fecf78a884647056fbd826b9d",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "009cb1e5fa1e1bdf4a9b433fe943f6ee4a97506d",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "form_controls.py": [
-       "364d4c28fae7807f109cdcdc32aead43d985a1fe",
-       [
-        null,
-        {}
+      },
+      "get_element_css_value": {
+       "get.py": [
+        "6f0a8a56395788be0f9152028f569f133fcd79ed",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "b1f9a3fb0a00f17c9c5bd5b590c8628d7888ea2e",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "interactability.py": [
-       "273843fb7b46a31aadf6387ad4815b58a251b4ea",
-       [
-        null,
-        {}
+      },
+      "get_element_property": {
+       "get.py": [
+        "bb63481dfcae75ee6f80503413c552db78d3c8ac",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "e5e76947863e61ca082a66367e3ea876b8ebec73",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "scroll_into_view.py": [
-       "7ccaeaf8142011ccbe7830876147d73853d0b07a",
-       [
-        null,
-        {}
+      },
+      "get_element_rect": {
+       "get.py": [
+        "942f119f43c9bb30eaefd52f3c793d7e47cfbfc4",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "20131603381bc574e44251a6909e389457dd0059",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "send_keys.py": [
-       "281c7ad719ddd05dac2ab7c6de343e9bebde4a5b",
-       [
-        null,
-        {}
+      },
+      "get_element_shadow_root": {
+       "get.py": [
+        "d9adde0b9e3aee402aa2e03db9d02259d968e81b",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "5b991bac26b6247b743f81ccf82faaa94dcb71a1",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "c1046840fa4ef24a5e063d09aee8c58803e835f7",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "get_element_tag_name": {
+       "get.py": [
+        "3bb03d79886d88c6ba045d9f0bedae7414412025",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "89697d0ad6a20503d6ec906862d58e674ed90839",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "execute_async_script": {
-      "arguments.py": [
-       "ead6e0c186ea40771643aea56ccc7180e6cc28d7",
-       [
-        null,
-        {}
+      },
+      "get_element_text": {
+       "get.py": [
+        "e8d559cf661acee18a39cbc4b6bb03289385ca08",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "9f0bb386cdf549ae1edbb7843fe893bd74700212",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "collections.py": [
-       "5dfbf2059470a2f17604a0a3d9bf47f905bca82e",
-       [
-        null,
-        {}
+      },
+      "get_named_cookie": {
+       "get.py": [
+        "d1e83b6a81521728556b20a875164a21924c8b5e",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "3ef52a58a419352ab01a7bd016e9f3adcf1ac321",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "cyclic.py": [
-       "ff536f3477c497dce59d60b26834ef986e971c2b",
-       [
-        null,
-        {}
+      },
+      "get_page_source": {
+       "source.py": [
+        "cc4e208835c8620ac5d665db69babb5b2adef1dc",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "13cb31595e6165ffb6e3491661d630921ade5699",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "execute_async.py": [
-       "42cf4aacee8342939c515b5e56a40ef15a1cacfb",
-       [
-        null,
-        {}
+      },
+      "get_timeouts": {
+       "get.py": [
+        "aa02c0990e1a110b5d5e7e0f479ade9cc909b956",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "node.py": [
-       "53abda4b300597ade2f5b8d38260caad9cb17f31",
-       [
-        null,
-        {}
+      },
+      "get_title": {
+       "get.py": [
+        "e696ec340339e64d68956c3ea3bcfa5e8fceb774",
+        [
+         null,
+         {}
+        ]
+       ],
+       "iframe.py": [
+        "9c5ab0b595d33ce38b419da1565445c9d7e221e0",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "0fd51e46f32ab5c5a6a14392afe08a0cf725115a",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "objects.py": [
-       "edcf06505aac243ac54ecf7195887fed387c892f",
-       [
-        null,
-        {}
+      },
+      "get_window_handle": {
+       "get.py": [
+        "68441da5ef8460bb472beecd2e31a6cc34f0faa3",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "0bd660cfa1fb31ba4fc93bb0ecb239fc4a6c136c",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "promise.py": [
-       "d726d0d71283033086b1ca8851b444968654876b",
-       [
-        null,
-        {}
+      },
+      "get_window_handles": {
+       "get.py": [
+        "8f4361e30c9c42e5c064b03e47f5471611e4406a",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "217e9849b4417d7124e203f937270a9e4823666a",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "properties.py": [
-       "b9592e7edd40a5d4225fc0fc7d2c6bbade01307e",
-       [
-        null,
-        {}
+      },
+      "get_window_rect": {
+       "get.py": [
+        "f7592a30e067030f3c6433bc2419db06c0db8da8",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "37c8da6bd3838422441fc089d8191930dd2b3da6",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "e39574fd4ac1b734006614c4ab6caf0a9542676b",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "interface": {
+       "interface.py": [
+        "6a7afcd26358aaad3779a912fd4bc00a66ca9571",
+        [
+         null,
+         {}
+        ]
        ]
-      ]
-     },
-     "execute_script": {
-      "arguments.py": [
-       "b8657ce0efae2a266158bb8c2846864cd63c1d5e",
-       [
-        null,
-        {}
+      },
+      "is_element_enabled": {
+       "enabled.py": [
+        "fccff383a55a7929179810216407acbdea0a079c",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "5dd7d582bd3d80a3d3affc4052bc933d75bcbca6",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "collections.py": [
-       "ec5d5ee1e32beb19b799b633534ec31fcfb0c7ad",
-       [
-        null,
-        {}
+      },
+      "is_element_selected": {
+       "selected.py": [
+        "1fb5b9ce86b521069f638956272e3101ea62cc5c",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "96da2c08bd7e5465ed12eb49cede25d70a6fbef5",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "cyclic.py": [
-       "29db2f27e669a9e7b0c2068c09b6d9bb3b5e1f07",
-       [
-        null,
-        {}
+      },
+      "maximize_window": {
+       "maximize.py": [
+        "e233e45a10d7136929380e2a80f5d6fdd0c32a9e",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "stress.py": [
+        "4527c64a28844b009f33b8051194a6f624899ba5",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "user_prompts.py": [
+        "032edc893a53a05dd0272cc081265bde6f0b5d53",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "execute.py": [
-       "fbccc98633867b9ab137b26f0f8818b98a29c81f",
-       [
-        null,
-        {}
+      },
+      "minimize_window": {
+       "minimize.py": [
+        "616b250c705a523f049c7c008c1c3b5c5dd9b095",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "stress.py": [
+        "8990f12669d70aa9693d798c6d75105c6075c3d6",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "user_prompts.py": [
+        "19059b3c395ecd22690d999f60838257cbe93449",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "json_serialize_windowproxy.py": [
-       "8e76feda23809bf65a77c6bcd3994209aaba40e0",
-       [
-        null,
-        {}
+      },
+      "navigate_to": {
+       "file.py": [
+        "5dae5f5c4d0edfed3113d5d50511b52dfbd111c5",
+        [
+         null,
+         {}
+        ]
+       ],
+       "navigate.py": [
+        "d61377af275902c48083d3d84b35c3bba30bc34e",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "682bc40f4fe9d4b530b406a74b1451bbf88a5d75",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "node.py": [
-       "caf85988f15413eca765c5d5cb019b06777d3b9d",
-       [
-        null,
-        {}
+      },
+      "new_session": {
+       "create_alwaysMatch.py": [
+        "64fd0a7425657fa0596298ec281ea4a1bbe08a4f",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "create_firstMatch.py": [
+        "d4523f4330c76e46fd9441901dc17314aec85c66",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "default_values.py": [
+        "abd4a5a64c510ee90ef9f52660581a097873e96c",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "invalid_capabilities.py": [
+        "be397edcf0f263f381d4901e4064c18d65eae29d",
+        [
+         null,
+         {}
+        ]
+       ],
+       "merge.py": [
+        "857d289fcaf054492e17ba730c6f530d55fe2640",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "page_load_strategy.py": [
+        "69288ef43335605e4c9d21cfa56bd2806f6e92b0",
+        [
+         null,
+         {}
+        ]
+       ],
+       "platform_name.py": [
+        "54fe4743bed44e75d6771ede5d4b7bf2f267bb95",
+        [
+         null,
+         {}
+        ]
+       ],
+       "response.py": [
+        "43a8d57931143f9cf2b5cb0946f982b003afd85c",
+        [
+         null,
+         {}
+        ]
+       ],
+       "timeouts.py": [
+        "4f2652bba86ce67eb6f6e0c42ee4d2e2685f113e",
+        [
+         null,
+         {}
+        ]
+       ],
+       "websocket_url.py": [
+        "452decc90aa18420459d72886a85d89918a0fb38",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "objects.py": [
-       "e254fe275e26f1adda0cf6f4898616703302e2da",
-       [
-        null,
-        {}
+      },
+      "new_window": {
+       "new.py": [
+        "fd0a1ffceb81de4ef944943a953ee1a3108335e7",
+        [
+         null,
+         {}
+        ]
+       ],
+       "new_tab.py": [
+        "f6cacf3c3586bc2962e67be4cacf3fbbc838216d",
+        [
+         null,
+         {}
+        ]
+       ],
+       "new_window.py": [
+        "a3fce364ccc8ac8e7de942d4718a6eda151464f9",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "0d841468ee48995a4f1b2c71ec7f69adcb37baae",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "promise.py": [
-       "c206674baefc75d23443fb5b7999ef465b09a3e2",
-       [
-        null,
-        {}
-       ]
-      ],
-      "properties.py": [
-       "c3b01dea29b5a160cda24ea82d0135cb1761032b",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "48d735ea754c0f74726d5a89f43eabb245b8bc5a",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "find_element": {
-      "user_prompts.py": [
-       "ada8e8ebee33a6ce9fcfb4871093ce1eef1d1dae",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "find_element_from_element": {
-      "user_prompts.py": [
-       "0537a786189c41420f50e6c3b747482c331fdaa3",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "find_element_from_shadow_root": {
-      "user_prompts.py": [
-       "3e3381e7853b25577a0f465542c848c9429e3099",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "find_elements": {
-      "user_prompts.py": [
-       "f9a45e527515fc7448162a86dca69d3f95e76491",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "find_elements_from_element": {
-      "user_prompts.py": [
-       "467bec09a1bd61346b3df2fa5b0b8c16e02fe975",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "find_elements_from_shadow_root": {
-      "user_prompts.py": [
-       "45986ad6dab9322ca7126050d623904d2542e338",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "forward": {
-      "forward.py": [
-       "f27be403f9e95bd2359d5ae6224f6ae2708ff7c8",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "3eeaf6e71cdb7311614b271257f4cd6d19a2e619",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "fullscreen_window": {
-      "fullscreen.py": [
-       "94f25ed9bdbd4a9cf619982f9b02582b5c137335",
-       [
-        null,
-        {}
-       ]
-      ],
-      "stress.py": [
-       "b907a31f17e0167ff27a4e8ceb2ad44cd372b537",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "user_prompts.py": [
-       "106bc457f0c18769afe1d9f76c39937d17783666",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_active_element": {
-      "get.py": [
-       "1d2960c88c5f587bf2dea86f5b97ad1e5fae9b5c",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "1ff77697b707886bbfeaee8acf08bdb8aba2de38",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_alert_text": {
-      "get.py": [
-       "7ee7ff1808f928e67ab0e3423c13a885e28db08f",
-       [
-        null,
-        {}
-       ]
-      ]
-     },
-     "get_computed_label": {
-      "get.py": [
-       "0dc00a471a9a37509e4ed7a448c1213bb978eeda",
-       [
-        null,
-        {}
-       ]
-      ]
-     },
-     "get_computed_role": {
-      "get.py": [
-       "51b6a8b3b6d1e302be8885e4b2976cc0c02ff4bd",
-       [
-        null,
-        {}
-       ]
-      ]
-     },
-     "get_current_url": {
-      "file.py": [
-       "ef6ae2383550330bfd41c10fffb41b4545d7007d",
-       [
-        null,
-        {}
-       ]
-      ],
-      "get.py": [
-       "baeab0960b6860579a7e648c650dffc4c548fa67",
-       [
-        null,
-        {}
-       ]
-      ],
-      "iframe.py": [
-       "80a960ce8a15e831941b4bf97ab6375b64b70ea7",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "d657c188241d8e0b53153d6b0e64fd386642847a",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_element_attribute": {
-      "get.py": [
-       "375f25032c06a10fecf78a884647056fbd826b9d",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "009cb1e5fa1e1bdf4a9b433fe943f6ee4a97506d",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_element_css_value": {
-      "get.py": [
-       "6f0a8a56395788be0f9152028f569f133fcd79ed",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "b1f9a3fb0a00f17c9c5bd5b590c8628d7888ea2e",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_element_property": {
-      "get.py": [
-       "bb63481dfcae75ee6f80503413c552db78d3c8ac",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "e5e76947863e61ca082a66367e3ea876b8ebec73",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_element_rect": {
-      "get.py": [
-       "942f119f43c9bb30eaefd52f3c793d7e47cfbfc4",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "20131603381bc574e44251a6909e389457dd0059",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_element_shadow_root": {
-      "get.py": [
-       "d9adde0b9e3aee402aa2e03db9d02259d968e81b",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "5b991bac26b6247b743f81ccf82faaa94dcb71a1",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_element_tag_name": {
-      "get.py": [
-       "3bb03d79886d88c6ba045d9f0bedae7414412025",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "89697d0ad6a20503d6ec906862d58e674ed90839",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_element_text": {
-      "get.py": [
-       "e8d559cf661acee18a39cbc4b6bb03289385ca08",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "9f0bb386cdf549ae1edbb7843fe893bd74700212",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_named_cookie": {
-      "get.py": [
-       "d1e83b6a81521728556b20a875164a21924c8b5e",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "3ef52a58a419352ab01a7bd016e9f3adcf1ac321",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_page_source": {
-      "source.py": [
-       "cc4e208835c8620ac5d665db69babb5b2adef1dc",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "13cb31595e6165ffb6e3491661d630921ade5699",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_timeouts": {
-      "get.py": [
-       "aa02c0990e1a110b5d5e7e0f479ade9cc909b956",
-       [
-        null,
-        {}
-       ]
-      ]
-     },
-     "get_title": {
-      "get.py": [
-       "e696ec340339e64d68956c3ea3bcfa5e8fceb774",
-       [
-        null,
-        {}
-       ]
-      ],
-      "iframe.py": [
-       "9c5ab0b595d33ce38b419da1565445c9d7e221e0",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "0fd51e46f32ab5c5a6a14392afe08a0cf725115a",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_window_handle": {
-      "get.py": [
-       "68441da5ef8460bb472beecd2e31a6cc34f0faa3",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "0bd660cfa1fb31ba4fc93bb0ecb239fc4a6c136c",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_window_handles": {
-      "get.py": [
-       "8f4361e30c9c42e5c064b03e47f5471611e4406a",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "217e9849b4417d7124e203f937270a9e4823666a",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "get_window_rect": {
-      "get.py": [
-       "f7592a30e067030f3c6433bc2419db06c0db8da8",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "37c8da6bd3838422441fc089d8191930dd2b3da6",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "interface": {
-      "interface.py": [
-       "6a7afcd26358aaad3779a912fd4bc00a66ca9571",
-       [
-        null,
-        {}
-       ]
-      ]
-     },
-     "is_element_enabled": {
-      "enabled.py": [
-       "fccff383a55a7929179810216407acbdea0a079c",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "5dd7d582bd3d80a3d3affc4052bc933d75bcbca6",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "is_element_selected": {
-      "selected.py": [
-       "1fb5b9ce86b521069f638956272e3101ea62cc5c",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "96da2c08bd7e5465ed12eb49cede25d70a6fbef5",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "maximize_window": {
-      "maximize.py": [
-       "e233e45a10d7136929380e2a80f5d6fdd0c32a9e",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "stress.py": [
-       "4527c64a28844b009f33b8051194a6f624899ba5",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "user_prompts.py": [
-       "032edc893a53a05dd0272cc081265bde6f0b5d53",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "minimize_window": {
-      "minimize.py": [
-       "616b250c705a523f049c7c008c1c3b5c5dd9b095",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "stress.py": [
-       "8990f12669d70aa9693d798c6d75105c6075c3d6",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "user_prompts.py": [
-       "19059b3c395ecd22690d999f60838257cbe93449",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "navigate_to": {
-      "file.py": [
-       "5dae5f5c4d0edfed3113d5d50511b52dfbd111c5",
-       [
-        null,
-        {}
-       ]
-      ],
-      "navigate.py": [
-       "d61377af275902c48083d3d84b35c3bba30bc34e",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "682bc40f4fe9d4b530b406a74b1451bbf88a5d75",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "new_session": {
-      "create_alwaysMatch.py": [
-       "a4cc9efc02e2a9c61fb8a79eecd5dcff49ca21a6",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "create_firstMatch.py": [
-       "ec671530f79692c04135ec441426f0044a72e8bc",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "default_values.py": [
-       "abd4a5a64c510ee90ef9f52660581a097873e96c",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "merge.py": [
-       "857d289fcaf054492e17ba730c6f530d55fe2640",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "page_load_strategy.py": [
-       "69288ef43335605e4c9d21cfa56bd2806f6e92b0",
-       [
-        null,
-        {}
-       ]
-      ],
-      "platform_name.py": [
-       "54fe4743bed44e75d6771ede5d4b7bf2f267bb95",
-       [
-        null,
-        {}
-       ]
-      ],
-      "timeouts.py": [
-       "4f2652bba86ce67eb6f6e0c42ee4d2e2685f113e",
-       [
-        null,
-        {}
-       ]
-      ],
-      "websocket_url.py": [
-       "452decc90aa18420459d72886a85d89918a0fb38",
-       [
-        null,
-        {}
-       ]
-      ]
-     },
-     "new_window": {
-      "new.py": [
-       "fd0a1ffceb81de4ef944943a953ee1a3108335e7",
-       [
-        null,
-        {}
-       ]
-      ],
-      "new_tab.py": [
-       "f6cacf3c3586bc2962e67be4cacf3fbbc838216d",
-       [
-        null,
-        {}
-       ]
-      ],
-      "new_window.py": [
-       "a3fce364ccc8ac8e7de942d4718a6eda151464f9",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "0d841468ee48995a4f1b2c71ec7f69adcb37baae",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "perform_actions": {
-      "key.py": [
-       "6730b1c18bf761473be2cf1a54eed5f35b0a64e5",
-       [
-        null,
-        {}
-       ]
-      ],
-      "key_events.py": [
-       "472fb54c28509cb936b98ee5c299288776a182e1",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "key_modifiers.py": [
-       "652106f46c2d3910b81afa6a795ae01a96524077",
-       [
-        null,
-        {}
-       ]
-      ],
-      "key_shortcuts.py": [
-       "46bc3c43390c5b178ff5a03b5f2cb2f8adb113a0",
-       [
-        null,
-        {}
-       ]
-      ],
-      "key_special_keys.py": [
-       "003bba4294105eb2757bfbe9e4f808b4ea13047c",
-       [
-        null,
-        {}
-       ]
-      ],
-      "none.py": [
-       "4fadec40a45cd685ac856551f557b9178abb6040",
-       [
-        null,
-        {}
-       ]
-      ],
-      "pointer_contextmenu.py": [
-       "2e06e8ca59fea429ad00093100c2fb1094263032",
-       [
-        null,
-        {}
-       ]
-      ],
-      "pointer_dblclick.py": [
-       "5be635a4d5604e33bf61c41b2190e620309179b8",
-       [
-        null,
-        {}
-       ]
-      ],
-      "pointer_modifier_click.py": [
-       "ffba6fc306b6913375fe0c229363ef08444252cd",
-       [
-        null,
-        {}
-       ]
-      ],
-      "pointer_mouse.py": [
-       "14da9871f4047a6dd57e0f394d0870cabb4b3e56",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "pointer_origin.py": [
-       "8d4dc9045e688eb3acad3ca6e5119f59603d117b",
-       [
-        null,
-        {}
-       ]
-      ],
-      "pointer_pause_dblclick.py": [
-       "d46178a1d650828ef84ccb02f08a12b292f4c3eb",
-       [
-        null,
-        {}
-       ]
-      ],
-      "pointer_pen.py": [
-       "29d40276b25b11d52099af6a0dbe630d99625ef2",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "pointer_touch.py": [
-       "03f32af2b48cc03c90f86317ef075ec6b292cc02",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "pointer_tripleclick.py": [
-       "fff70b8fa62d82c532f4e665d82bbd8b09f5fcb9",
-       [
-        null,
-        {}
-       ]
-      ],
-      "sequence.py": [
-       "3536abeb12bcf667e4b6eab2cb723baa10c9ffa7",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "user_prompts.py": [
-       "6bbd22a2a29a574dbacd207e9fc43810a68ebff6",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "validity.py": [
-       "9c056b197d25808864e36dd7a58040a0dbff4abc",
-       [
-        null,
-        {}
-       ]
-      ],
-      "wheel.py": [
-       "59da29fe8922dd08e2c4ed3c52fec49aa8a202d6",
-       [
-        null,
-        {}
-       ]
-      ]
-     },
-     "permissions": {
-      "set.py": [
-       "9b71c4486c37a77a78c701c67caee4129c792b5b",
-       [
-        null,
-        {}
-       ]
-      ]
-     },
-     "print": {
-      "background.py": [
-       "22b392db2e3c51dbf68fe616bb3340535adf53f8",
-       [
-        null,
-        {}
-       ]
-      ],
-      "orientation.py": [
-       "c2afacf94fb45adb7d163fd45974416b6a9fcc25",
-       [
-        null,
-        {}
-       ]
-      ],
-      "printcmd.py": [
-       "f3fe50bd92d6a7dc4f8bf0c2290f2ecebc0dd1d7",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "user_prompts.py": [
-       "fb13ec2d65a25038641a42a67e48237fdef60c10",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "refresh": {
-      "refresh.py": [
-       "b3647130c77ec6c0c84514ff9f599b9a872303e7",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "7e944b53b0964e68b897e6315faa0cfa65802143",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "release_actions": {
-      "release.py": [
-       "5df1ff4be902874529fcc5573bcf4df2755b9ae7",
-       [
-        null,
-        {}
-       ]
-      ],
-      "sequence.py": [
-       "24ca16c86043ac091b5173fcc3e8571a50107eca",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "set_timeouts": {
-      "set.py": [
-       "6620f4df2a8999df28636de7a2121aa691d9d71b",
-       [
-        null,
-        {}
-       ]
-      ],
-      "user_prompts.py": [
-       "a98d87e9b2e2ca252a3ed7cf215a20bd1c299818",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "set_window_rect": {
-      "set.py": [
-       "23382288a3d87b6788c2809fd5335bffc2260e70",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ],
-      "user_prompts.py": [
-       "908a9d920f36d0b8664c6b906bc71b0aefba96e6",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
-       ]
-      ]
-     },
-     "status": {
-      "status.py": [
-       "8c7ae22a67b5988cd94daa979a5ade8d5377a684",
-       [
-        null,
-        {}
+      },
+      "perform_actions": {
+       "key.py": [
+        "6c34452082aebbfe2f83a879bea44a75ed2bea1f",
+        [
+         null,
+         {}
+        ]
+       ],
+       "key_events.py": [
+        "a1cd9cea8e438407e5c050bc234e1d02592360f9",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "key_modifiers.py": [
+        "652106f46c2d3910b81afa6a795ae01a96524077",
+        [
+         null,
+         {}
+        ]
+       ],
+       "key_shortcuts.py": [
+        "a5e151569671e03b673cc97bbd664375bc00c9c5",
+        [
+         null,
+         {}
+        ]
+       ],
+       "key_special_keys.py": [
+        "c55f3a113ebf76428bfaab208634a029c87b28e0",
+        [
+         null,
+         {}
+        ]
+       ],
+       "none.py": [
+        "4fadec40a45cd685ac856551f557b9178abb6040",
+        [
+         null,
+         {}
+        ]
+       ],
+       "pointer_contextmenu.py": [
+        "4a48ea0b23750eb7796b5a4bd9796dfcc767fe31",
+        [
+         null,
+         {}
+        ]
+       ],
+       "pointer_dblclick.py": [
+        "659e27bd5c8883db62333cb451c8e40ace6701ee",
+        [
+         null,
+         {}
+        ]
+       ],
+       "pointer_modifier_click.py": [
+        "f3e54288474e829bda1c7311dff547e7b4a82f46",
+        [
+         null,
+         {}
+        ]
+       ],
+       "pointer_mouse.py": [
+        "31d08491ccb832e951bcc7598f3795ec4a38a796",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "pointer_origin.py": [
+        "33b8a25959f9df75983acbfa62116230fb9f6c0f",
+        [
+         null,
+         {}
+        ]
+       ],
+       "pointer_pause_dblclick.py": [
+        "209de727a6cbb14a14a3c1abbee4ff78462c4043",
+        [
+         null,
+         {}
+        ]
+       ],
+       "pointer_pen.py": [
+        "e9cd103301ee7ab965098e7ba048917014b057d7",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "pointer_touch.py": [
+        "7f940f6203c16a7f7bc019f3fe06af3da8330f59",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "pointer_tripleclick.py": [
+        "b45709da3cb06bb037ecb8b18a92ce325a5380dd",
+        [
+         null,
+         {}
+        ]
+       ],
+       "sequence.py": [
+        "f6c12220c450146a7a491b0fa9172264114debdc",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "user_prompts.py": [
+        "820edbe32cbe0ade5fd63966002003e841f67dd4",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "validity.py": [
+        "9c056b197d25808864e36dd7a58040a0dbff4abc",
+        [
+         null,
+         {}
+        ]
+       ],
+       "wheel.py": [
+        "7ee0ae79f773ecf3b5fd0ef1a23ebea51ea0900e",
+        [
+         null,
+         {}
+        ]
        ]
-      ]
-     },
-     "switch_to_frame": {
-      "cross_origin.py": [
-       "633eba3f4248575f1c06deb1cab536a8c5414ac5",
-       [
-        null,
-        {}
+      },
+      "permissions": {
+       "set.py": [
+        "9b71c4486c37a77a78c701c67caee4129c792b5b",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "switch.py": [
-       "b9cccb3ecc099232682955fd0e2fc54362895bc0",
-       [
-        null,
-        {}
+      },
+      "print": {
+       "background.py": [
+        "22b392db2e3c51dbf68fe616bb3340535adf53f8",
+        [
+         null,
+         {}
+        ]
+       ],
+       "orientation.py": [
+        "c2afacf94fb45adb7d163fd45974416b6a9fcc25",
+        [
+         null,
+         {}
+        ]
+       ],
+       "printcmd.py": [
+        "f3fe50bd92d6a7dc4f8bf0c2290f2ecebc0dd1d7",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "user_prompts.py": [
+        "fb13ec2d65a25038641a42a67e48237fdef60c10",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "switch_number.py": [
-       "c8858e77ff10478e982d911f030a615470987df6",
-       [
-        null,
-        {}
+      },
+      "refresh": {
+       "refresh.py": [
+        "b3647130c77ec6c0c84514ff9f599b9a872303e7",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "7e944b53b0964e68b897e6315faa0cfa65802143",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "switch_webelement.py": [
-       "ceadccd812101584b4a8a9ab343048344339cefa",
-       [
-        null,
-        {}
+      },
+      "release_actions": {
+       "release.py": [
+        "5df1ff4be902874529fcc5573bcf4df2755b9ae7",
+        [
+         null,
+         {}
+        ]
+       ],
+       "sequence.py": [
+        "78912d8b38904ba61a8450995b64358f8105e151",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "switch_to_parent_frame": {
-      "switch.py": [
-       "9c6db8d2cd61d6e92f45ac1843dbe0f43f69af76",
-       [
-        null,
-        {}
+      },
+      "send_alert_text": {
+       "send.py": [
+        "df218c803bb0a4f558c8bc1547dc3982af01216b",
+        [
+         null,
+         {}
+        ]
        ]
-      ]
-     },
-     "switch_to_window": {
-      "alerts.py": [
-       "2fc390e8641b980bc1c317db93f9f1166bcb8284",
-       [
-        null,
-        {}
+      },
+      "set_timeouts": {
+       "set.py": [
+        "6620f4df2a8999df28636de7a2121aa691d9d71b",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "a98d87e9b2e2ca252a3ed7cf215a20bd1c299818",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "switch.py": [
-       "28d432a8b5b42623d49c4fbe0d1da0539c36e71c",
-       [
-        null,
-        {}
+      },
+      "set_window_rect": {
+       "set.py": [
+        "23382288a3d87b6788c2809fd5335bffc2260e70",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
+       ],
+       "user_prompts.py": [
+        "908a9d920f36d0b8664c6b906bc71b0aefba96e6",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
-     },
-     "take_element_screenshot": {
-      "iframe.py": [
-       "e7f1b0c8053db0fedbb37c0a1b528a259591813f",
-       [
-        null,
-        {}
+      },
+      "status": {
+       "status.py": [
+        "8c7ae22a67b5988cd94daa979a5ade8d5377a684",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "screenshot.py": [
-       "ea4cc290db4cdd603d9dc20bbc90914c4e241cb5",
-       [
-        null,
-        {}
+      },
+      "switch_to_frame": {
+       "cross_origin.py": [
+        "633eba3f4248575f1c06deb1cab536a8c5414ac5",
+        [
+         null,
+         {}
+        ]
+       ],
+       "switch.py": [
+        "b9cccb3ecc099232682955fd0e2fc54362895bc0",
+        [
+         null,
+         {}
+        ]
+       ],
+       "switch_number.py": [
+        "c8858e77ff10478e982d911f030a615470987df6",
+        [
+         null,
+         {}
+        ]
+       ],
+       "switch_webelement.py": [
+        "ceadccd812101584b4a8a9ab343048344339cefa",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "39fefe9325a9bf2880d333d48a58337edb3508cd",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "switch_to_parent_frame": {
+       "switch.py": [
+        "9c6db8d2cd61d6e92f45ac1843dbe0f43f69af76",
+        [
+         null,
+         {}
+        ]
        ]
-      ]
-     },
-     "take_screenshot": {
-      "iframe.py": [
-       "258e764407a7e936455c3c00fdfafb063bf231b8",
-       [
-        null,
-        {}
+      },
+      "switch_to_window": {
+       "alerts.py": [
+        "2fc390e8641b980bc1c317db93f9f1166bcb8284",
+        [
+         null,
+         {}
+        ]
+       ],
+       "switch.py": [
+        "28d432a8b5b42623d49c4fbe0d1da0539c36e71c",
+        [
+         null,
+         {}
+        ]
        ]
-      ],
-      "screenshot.py": [
-       "9e71a633c708b628b40fe8e3be143d36c821a8f9",
-       [
-        null,
-        {}
+      },
+      "take_element_screenshot": {
+       "iframe.py": [
+        "e7f1b0c8053db0fedbb37c0a1b528a259591813f",
+        [
+         null,
+         {}
+        ]
+       ],
+       "screenshot.py": [
+        "ea4cc290db4cdd603d9dc20bbc90914c4e241cb5",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "39fefe9325a9bf2880d333d48a58337edb3508cd",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ],
-      "user_prompts.py": [
-       "7d57f8f2716b393696fb3ce45ded196d83a0bf68",
-       [
-        null,
-        {
-         "timeout": "long"
-        }
+      },
+      "take_screenshot": {
+       "iframe.py": [
+        "258e764407a7e936455c3c00fdfafb063bf231b8",
+        [
+         null,
+         {}
+        ]
+       ],
+       "screenshot.py": [
+        "9e71a633c708b628b40fe8e3be143d36c821a8f9",
+        [
+         null,
+         {}
+        ]
+       ],
+       "user_prompts.py": [
+        "7d57f8f2716b393696fb3ce45ded196d83a0bf68",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
-      ]
+      }
      }
     }
    }
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht b/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht
deleted file mode 100644
index 947e869..0000000
--- a/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht
+++ /dev/null
@@ -1,51 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-    <head>
-        <title>CSS Test: Text-align set to 'justify' with 'white-space' set to 'pre-wrap'</title>
-        <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
-        <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2012-06-28 -->
-        <link rel="help" href="http://www.w3.org/TR/CSS21/text.html#alignment-prop" />
-		<link rel="match" href="text-align-white-space-002-ref.xht" />
-
-	<meta name="flags" content="ahem may" /> <!-- "may" because level 3 makes it no longer mandatory -->
-        <link rel="help" href="https://drafts.csswg.org/css-text-3/#text-align-property" />
-        <meta name="assert" content="Setting 'text-align' to 'justify' and 'white-space' to 'pre-wrap', text-align is computed to its initial value." />
-        <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
-        <style type="text/css">
-            div
-            {
-                font: 20px/1 Ahem;
-                position: relative;
-                width: 9em;
-            }
-            div div
-            {
-                position: absolute;
-            }
-            #test
-            {
-                color: green;
-                text-align: justify;
-                white-space: pre-wrap;
-            }
-            .red
-            {
-                color: red;
-            }
-            .green
-            {
-                color: green;
-            }
-        </style>
-    </head>
-    <body>
-        <p>Test passes if there is <strong>no red</strong>.</p>
-        <div>
-            <div><span class="red">xxx</span><span class="green">x</span><span class="red">xxx</span><span class="green">xx</span>
-                <span class="red">xxx</span><span class="green">x</span><span class="red">xxx</span><span class="green">xx</span>
-                <span class="red">xxx</span><span class="green">x</span><span class="red">xxx</span><span class="green">xx</span>
-                <span class="red">xxx</span><span class="green">x</span><span class="red">xxx</span><span class="green">xx</span></div>
-            <div id="test">XXX XXX XXX XXX XXX XXX XXX XXX</div>
-        </div>
-    </body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht.ini
deleted file mode 100644
index 629be9f..0000000
--- a/third_party/blink/web_tests/external/wpt/css/CSS2/text/text-align-white-space-003.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[text-align-white-space-003.xht]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-border-radius-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-border-radius-001.html
new file mode 100644
index 0000000..6f81ca8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-border-radius-001.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Backgrounds Test: 'border-radius: 50%' with a box-shadow that has a tall and wide spread</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+  <link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-shadow-property">
+  <link rel="match" href="reference/box-shadow-border-radius-001-ref.html">
+  <link rel="mismatch" href="reference/box-shadow-border-radius-001-notref.html">
+
+  <meta content="" name="flags">
+
+  <!--
+
+  [css-backgrounds] The shape of box-shadow should be a circle for a box with border-radius:50% and big spread
+  https://github.com/w3c/csswg-drafts/issues/7103
+
+  https://lists.w3.org/Archives/Public/www-archive/2022Sep/att-0012/shadow-radius.html
+
+  -->
+
+  <style>
+  div
+    {
+      background-color: black;
+      border-radius: 50%;
+      box-shadow: black 0 0 0 149px;
+      height: 2px;
+      margin: 157px 149px 0px;
+      width: 2px;
+    }
+
+  /*
+
+      149px
+    +
+        2px
+    +
+      149px
+    ========
+      300px
+
+  */
+  </style>
+
+  <div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-border-radius-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-border-radius-001.html.ini
new file mode 100644
index 0000000..c4286b0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-border-radius-001.html.ini
@@ -0,0 +1,2 @@
+[box-shadow-border-radius-001.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-inset-spread-without-border-radius.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-inset-spread-without-border-radius.html
deleted file mode 100644
index 0e74fbf..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-inset-spread-without-border-radius.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>CSS Backgrounds and Borders Test: box-shadow</title>
-    <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
-    <link rel="help" href="http://www.w3.org/TR/css3-background/#the-box-shadow">
-    <link rel="match" href="reference/box-shadow-inset-spread-without-border-radius.html">
-    <meta name="assert" content="inset spread box-shadow should show shadow.">
-    <style type="text/css">
-        .container {
-            position: relative;
-        }
-        .container div {
-            position: absolute;
-            height: 150px;
-            width: 150px;
-            left: 0;
-            top: 0;
-        }
-        .container .test {
-            box-shadow: red 10px 10px 0 10px inset;
-        }
-        .container .ref {
-            background-color: green;
-        }
-    </style>
-</head>
-<body>
-    <p>The test passes if there is a filled green square and no red.</p>
-    <div class="container">
-        <div class="test"></div>
-        <div class="ref"></div>
-    </div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-inset-without-border-radius.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-inset-without-border-radius.html
index a6ad944..8b2c691 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-inset-without-border-radius.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-inset-without-border-radius.html
@@ -1,35 +1,94 @@
 <!DOCTYPE html>
-<html>
-<head>
-    <title>CSS Backgrounds and Borders Test: box-shadow</title>
-    <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
-    <link rel="help" href="http://www.w3.org/TR/css3-background/#the-box-shadow">
-    <link rel="match" href="reference/box-shadow-inset-without-border-radius.html">
-    <meta name="assert" content="inset box-shadow should show shadow.">
-    <style type="text/css">
-        .container {
-            position: relative;
-        }
-        .container div {
-            position: absolute;
-            height: 150px;
-            width: 150px;
-            left: 0;
-            top: 0;
-        }
-        .container .test {
-            box-shadow: red 10px 10px inset;
-        }
-        .container .ref {
-            background-color: green;
-        }
-    </style>
-</head>
-<body>
-    <p>The test passes if there is a filled green square and no red.</p>
-    <div class="container">
-        <div class="test"></div>
-        <div class="ref"></div>
-    </div>
-</body>
-</html>
+
+ <meta charset="UTF-8">
+
+  <title>CSS Backgrounds and Borders Test: box-shadow inset without border-radius</title>
+
+  <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+  <link rel="help" href="http://www.w3.org/TR/css3-background/#the-box-shadow">
+  <link rel="match" href="reference/box-shadow-inset-without-border-radius-ref.html">
+
+  <meta content="" name="flags">
+
+  <!--
+
+  Reviewed by Gérard Talbot on April 9th 2023
+
+  More info: https://github.com/web-platform-tests/wpt/issues/10013
+
+  https://github.com/web-platform-tests/wpt/pull/39445
+
+  -->
+
+  <style>
+  div
+    {
+      border: transparent solid 8px;
+      display: inline-block;
+      height: 32px;
+      margin: 0px 8px 8px 0px;
+      padding: 16px;
+      vertical-align: top;
+      width: 32px;
+    }
+
+  /*
+
+  An inner box-shadow casts a shadow as if everything outside
+  the padding edge were opaque. Assuming a spread distance of
+  zero, its perimeter has the exact same size and shape as the
+  padding box. The shadow is drawn inside the padding edge only:
+  it is clipped outside the padding box of the element.
+
+  If a spread distance is defined, the shadow perimeter
+  defined above is contracted inward (for inner box-shadows)
+  by insetting the shadow’s straight edges by the spread
+  distance (and flooring the resulting width/height at zero).
+
+  */
+
+  div#first-subtest /* inset with NO spread */
+    {
+      box-shadow: black 10px 10px 0px 0px inset;
+    }
+
+  div#second-subtest /* inset with a 15px spread */
+    {
+      box-shadow: black 10px 10px 0px 15px inset;
+    }
+
+  div#third-subtest /* inset with NO spread */
+    {
+      box-shadow: black 10px -10px 0px 0px inset;
+    }
+
+  div#fourth-subtest /* inset with a 15px spread */
+    {
+      box-shadow: black 10px -10px 0px 15px inset;
+    }
+
+  div#fifth-subtest /* inset with NO spread */
+    {
+      box-shadow: black -10px 10px 0px 0px inset;
+    }
+
+  div#sixth-subtest /* inset with a 15px spread */
+    {
+      box-shadow: black -10px 10px 0px 15px inset;
+    }
+
+  div#seventh-subtest /* inset with NO spread */
+    {
+      box-shadow: black -10px -10px 0px 0px inset;
+    }
+
+  div#eighth-subtest /* inset with a 15px spread */
+    {
+      box-shadow: black -10px -10px 0px 15px inset;
+    }
+  </style>
+
+  <div id="first-subtest"></div><div id="second-subtest"></div><div id="third-subtest"></div><div id="fourth-subtest"></div><br>
+
+  <div id="fifth-subtest"></div><div id="sixth-subtest"></div><div id="seventh-subtest"></div><div id="eighth-subtest"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-invalid-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-invalid-001.html
new file mode 100644
index 0000000..acd0bdf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-invalid-001.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Background and Borders Test: invalid box-shadow declarations</title>
+
+  <!--
+
+  Created: May 20th 2023
+
+  Last modified: May 20th 2023
+
+  -->
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+  <link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#box-shadow">
+  <link rel="match" href="reference/ref-filled-green-100px-square.xht">
+
+  <meta content="This test checks that 'box-shadow' accepts either the 'none' value or (exclusive or) a comma-separated list of shadows but not both at the same time." name="assert">
+  <meta content="invalid" name="flags">
+
+  <!--
+
+  <shadow> = <color>? && [<length>{2} <length [0,∞]>? <length>?] && inset?
+
+  The box-shadow property attaches one or more drop-shadows to
+  the box. The property accepts either the none value, which
+  indicates no shadows, or a comma-separated list of shadows,
+  ordered front to back.
+
+  -->
+
+  <style>
+  div
+    {
+      background-color: red;
+      box-shadow: green 100px 100px inset;
+      /*
+      This inset 'box-shadow' declaration will paint and cover
+      the inside of the red square. This way, we verify that
+      the UA actually supports 'box-shadow'.
+      */
+      box-shadow: none, red 0px -100px, red 100px 0px, red 0px 100px, red -100px 0px; /* invalid */
+      box-shadow: red 0px -100px, none, red 100px 0px, red 0px 100px, red -100px 0px; /* invalid */
+      box-shadow: red 0px -100px, red 100px 0px, none, red 0px 100px, red -100px 0px; /* invalid */
+      box-shadow: red 0px -100px, red 100px 0px, red 0px 100px, none, red -100px 0px; /* invalid */
+      box-shadow: red 0px -100px, red 100px 0px, red 0px 100px, red -100px 0px, none; /* invalid */
+      height: 100px;
+      width: 100px;
+   }
+  </style>
+
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+  <div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-multiple-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-multiple-001.html
new file mode 100644
index 0000000..e95fb68
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-multiple-001.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Backgrounds Test: multiple outset box-shadow</title>
+
+  <!--
+
+  Created: May 18th 2023
+
+  Last modified: May 18th 2023
+
+  -->
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+  <link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#box-shadow">
+  <link rel="match" href="reference/box-shadow-multiple-001-ref.html">
+
+  <meta content="" name="flags">
+
+  <!--
+
+  <shadow> = <color>? && [<length>{2} <length [0,∞]>? <length>?] && inset?
+
+  The box-shadow property attaches one or more drop-shadows to
+  the box. The property accepts either the none value, which
+  indicates no shadows, or a comma-separated list of shadows,
+  ordered front to back.
+
+  Each shadow is given as a <shadow>, represented by 2-4 length
+  values, an optional color, and an optional inset keyword.
+
+  -->
+
+  <style>
+  div
+    {
+      background-color: yellow;
+      font-size: 50px;
+      height: 1em;
+      margin: 1em auto 2.2em 1em;
+      width: 1em;
+   }
+
+  div#multiple
+    {
+      box-shadow: purple 0em -1em, blue 1em 0em, fuchsia 0em 1em, orange -1em 0em;
+      margin-top: 58px;
+    }
+
+  div#multiple-overlapping1
+    {
+      box-shadow: purple 0em -1em, red 0em -1em, blue 1em 0em, red 1em 0em, fuchsia 0em 1em, red 0em 1em, orange -1em 0em, red -1em 0em;
+    }
+
+  div#multiple-overlapping2
+    {
+      box-shadow: rgb(128 0 128 / 50%) 0em -1em, rgb(255 255 0 / 50%) 0em -1em, rgb(0 0 255 / 50%) 1em 0em, rgb(255 255 0 / 50%) 1em 0em, rgb(255 0 255 / 50%) 0em 1em, rgb(255 255 0 / 50%) 0em 1em, rgb(255 165 0 / 50%) -1em 0em, rgb(255 255 0 / 50%) -1em 0em;
+    }
+  </style>
+
+  <div id="multiple"></div>
+
+  <div id="multiple-overlapping1"></div>
+
+  <div id="multiple-overlapping2"></div>
+
+  <!--
+
+  The top first 2 are:
+
+                  .........
+                  .       .
+                  .       . <-purple
+                  .       .
+           .......................
+           .      .       .      .
+  orange-> .      .  yel  .      . <-blue
+           .      .  low  .      .
+           .......................
+                  .       .
+                  .       . <-fuchsia
+                  .       .
+                  .........
+
+  The bottom one is:
+
+                  .........
+                  .       .
+                  .       . <-#BF7F7F
+                  .       .
+           .......................
+           .      .       .      .
+ #FFD23F-> .      .  yel  .      . <-#7F7FBF
+           .      .  low  .      .
+           .......................
+                  .       .
+                  .       . <-#FF7FBF
+                  .       .
+                  .........
+
+  -->
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-spread-without-border-radius.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-spread-without-border-radius.html
deleted file mode 100644
index 5ebde55..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-spread-without-border-radius.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>CSS Backgrounds and Borders Test: box-shadow</title>
-    <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
-    <link rel="help" href="http://www.w3.org/TR/css3-background/#the-box-shadow">
-    <link rel="match" href="reference/box-shadow-outset-spread-without-border-radius.html">
-    <meta name="assert" content="outset spread box-shadow should show shadow.">
-    <style type="text/css">
-        .container {
-            position: relative;
-        }
-        .container div {
-            position: absolute;
-            height: 150px;
-            left: 0;
-            top: 0;
-            width: 150px;
-        }
-        .container .test {
-            box-shadow: red 10px 10px 0 5px;
-        }
-        .container .ref {
-            background-color: green;
-            height: 160px;
-            left: 5px;
-            top: 5px;
-            width: 160px;
-        }
-    </style>
-</head>
-<body>
-    <p>The test passes if there is a filled green square and no red.</p>
-    <div class="container">
-        <div class="test"></div>
-        <div class="ref"></div>
-    </div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-without-border-radius-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-without-border-radius-001.html
new file mode 100644
index 0000000..71735a9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-without-border-radius-001.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+  <title>CSS Backgrounds and Borders Test: box-shadow outset without border-radius</title>
+
+  <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+  <link rel="help" href="http://www.w3.org/TR/css3-background/#the-box-shadow">
+  <link rel="match" href="reference/box-shadow-outset-without-border-radius-001-ref.html">
+
+  <meta content="" name="flags">
+
+  <!--
+
+  Reviewed by Gérard Talbot on April 9th 2023
+
+  More info: https://github.com/web-platform-tests/wpt/issues/10013
+
+  https://github.com/web-platform-tests/wpt/pull/39445
+
+  -->
+
+  <style>
+  div
+    {
+      border: transparent solid 8px;
+      display: inline-block;
+      height: 32px;
+      margin: 32px 20px;
+      padding: 16px;
+      vertical-align: top;
+      width: 32px;
+    }
+
+  /*
+
+  An outer box-shadow casts a shadow as if the border-box
+  of the element were opaque. Assuming a spread distance
+  of zero, its perimeter has the exact same size and
+  shape as the border box. The shadow is drawn outside
+  the border edge only: it is clipped inside the border-box
+  of the element.
+
+  If a spread distance is defined, the shadow perimeter
+  defined above is expanded outward (for outer box-shadows)
+  by outset withting the shadow’s straight edges by the spread
+  distance (and flooring the resulting width/height at zero).
+
+  */
+
+  div#first-subtest /* outset with NO spread */
+    {
+      box-shadow: black 10px 10px 0px 0px;
+    }
+
+  div#second-subtest /* outset with a 15px spread */
+    {
+      box-shadow: black 10px 10px 0px 15px;
+    }
+
+  div#third-subtest /* outset with NO spread */
+    {
+      box-shadow: black 10px -10px 0px 0px;
+    }
+
+  div#fourth-subtest /* outset with a 15px spread */
+    {
+      box-shadow: black 10px -10px 0px 15px;
+    }
+
+  div#fifth-subtest /* outset with NO spread */
+    {
+      box-shadow: black -10px 10px 0px 0px;
+    }
+
+  div#sixth-subtest /* outset with a 15px spread */
+    {
+      box-shadow: black -10px 10px 0px 15px;
+    }
+
+  div#seventh-subtest /* outset with NO spread */
+    {
+      box-shadow: black -10px -10px 0px 0px;
+    }
+
+  div#eighth-subtest /* outset with a 15px spread */
+    {
+      box-shadow: black -10px -10px 0px 15px;
+    }
+  </style>
+
+  <div id="first-subtest"></div><div id="second-subtest"></div><div id="third-subtest"></div><div id="fourth-subtest"></div><br>
+
+  <div id="fifth-subtest"></div><div id="sixth-subtest"></div><div id="seventh-subtest"></div><div id="eighth-subtest"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-without-border-radius.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-without-border-radius.html
deleted file mode 100644
index 9f21354..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/box-shadow-outset-without-border-radius.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>CSS Backgrounds and Borders Test: box-shadow</title>
-    <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
-    <link rel="help" href="http://www.w3.org/TR/css3-background/#the-box-shadow">
-    <link rel="match" href="reference/box-shadow-outset-without-border-radius.html">
-    <meta name="assert" content="box-shadow should show shadow.">
-    <style type="text/css">
-        .container {
-            position: relative;
-        }
-        .container div {
-            position: absolute;
-            height: 150px;
-            width: 150px;
-        }
-        .container .test {
-            box-shadow: red 10px 10px;
-            left: 0;
-            top: 0;
-        }
-        .container .ref {
-            background-color: green;
-            left: 10px;
-            top: 10px;
-        }
-    </style>
-</head>
-<body>
-    <p>The test passes if there is a filled green square and no red.</p>
-    <div class="container">
-        <div class="test"></div>
-        <div class="ref"></div>
-    </div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-border-radius-001-notref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-border-radius-001-notref.html
new file mode 100644
index 0000000..fd0c1eb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-border-radius-001-notref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest reference</title>
+
+  <style>
+  div
+    {
+      background-color: black;
+      border-radius: 4px;
+      height: 300px;
+      width: 300px;
+    }
+  </style>
+
+  <div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-border-radius-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-border-radius-001-ref.html
new file mode 100644
index 0000000..ff99f43
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-border-radius-001-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest reference</title>
+
+  <style>
+  div
+    {
+      background-color: black;
+      border-radius: 50%;
+      height: 300px;
+      width: 300px;
+    }
+  </style>
+
+  <div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-spread-without-border-radius.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-spread-without-border-radius.html
deleted file mode 100644
index 5e9cf0d3..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-spread-without-border-radius.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>Reference File</title>
-    <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
-    <style type="text/css">
-        .container {
-            position: relative;
-        }
-        .ref {
-            background-color: green;
-            height: 150px;
-            position: absolute;
-            width: 150px;
-        }
-    </style>
-</head>
-<body>
-    <p>The test passes if there is a filled green square and no red.</p>
-    <div class="container">
-        <div class="ref"></div>
-    </div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-without-border-radius-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-without-border-radius-ref.html
new file mode 100644
index 0000000..dca329f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-without-border-radius-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest reference</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+  <style>
+  div
+    {
+      border-color: black;
+      border-style: solid;
+      display: inline-block;
+      margin: 8px 8px 16px 16px;
+      vertical-align: top;
+    }
+
+  </style>
+
+  <div id="first-subtest" style="border-width: 10px 0px 0px 10px; height: 54px; width: 54px; margin-left: 8px;"></div><div id="second-subtest" style="border-width: 25px 5px 5px 25px; height: 34px; width: 34px;"></div><div id="third-subtest" style="border-width: 0px 0px 10px 10px; height: 54px; width: 54px;"></div><div id="fourth-subtest" style="border-width: 5px 5px 25px 25px; height: 34px; width: 34px;"></div><br>
+
+  <div id="fifth-subtest" style="border-width: 10px 10px 0px 0px; height: 54px; width: 54px; margin-left: 8px;"></div><div id="sixth-subtest" style="border-width: 25px 25px 5px 5px; height: 34px; width: 34px;"></div><div id="seventh-subtest" style="border-width: 0px 10px 10px 0px; height: 54px; width: 54px;"></div><div id="eighth-subtest" style="border-width: 5px 25px 25px 5px; height: 34px; width: 34px;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-without-border-radius.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-without-border-radius.html
deleted file mode 100644
index 5e9cf0d3..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-inset-without-border-radius.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>Reference File</title>
-    <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
-    <style type="text/css">
-        .container {
-            position: relative;
-        }
-        .ref {
-            background-color: green;
-            height: 150px;
-            position: absolute;
-            width: 150px;
-        }
-    </style>
-</head>
-<body>
-    <p>The test passes if there is a filled green square and no red.</p>
-    <div class="container">
-        <div class="ref"></div>
-    </div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-multiple-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-multiple-001-ref.html
new file mode 100644
index 0000000..ada9dba
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-multiple-001-ref.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reference Test</title>
+
+  <link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+  <style>
+  div
+    {
+      color: transparent;
+      font-family: Ahem;
+      font-size: 50px;
+      line-height: 1;
+    }
+
+  div.purple
+    {
+      text-shadow: 1em 0em purple;
+    }
+
+  div.orange-blue
+    {
+      color: yellow;
+      margin-left: 1em;
+      text-shadow: -1em 0em orange, 1em 0em blue;
+    }
+
+  div.fuchsia
+    {
+      margin-bottom: 0.2em;
+      text-shadow: 1em 0em fuchsia;
+    }
+
+  div#third-top
+    {
+      text-shadow: 1em 0em #BF7F7F;
+    }
+
+  div#third-horiz-left-right
+    {
+      color: yellow;
+      margin-left: 1em;
+      text-shadow: -1em 0em #FFD23F , 1em 0em #7F7FBF;
+    }
+
+  div#third-bottom
+    {
+      text-shadow: 1em 0em #FF7FBF;
+    }
+  </style>
+
+  <div class="purple">U</div>
+
+  <div class="orange-blue">B</div>
+
+  <div class="fuchsia">F</div>
+
+
+  <div class="purple">U</div>
+
+  <div class="orange-blue">B</div>
+
+  <div class="fuchsia">F</div>
+
+
+  <div id="third-top">T</div>
+
+  <div id="third-horiz-left-right">H</div>
+
+  <div id="third-bottom">B</div>
+
+
+  <!--
+
+  The top first 2 are:
+
+                  .........
+                  .       .
+                  .       . <-purple
+                  .       .
+           .......................
+           .      .       .      .
+  orange-> .      .  yel  .      . <-blue
+           .      .  low  .      .
+           .......................
+                  .       .
+                  .       . <-fuchsia
+                  .       .
+                  .........
+
+  The bottom one is:
+
+                  .........
+                  .       .
+                  .       . <-#BF7F7F
+                  .       .
+           .......................
+           .      .       .      .
+ #FFD23F-> .      .  yel  .      . <-#7F7FBF
+           .      .  low  .      .
+           .......................
+                  .       .
+                  .       . <-#FF7FBF
+                  .       .
+                  .........
+
+  -->
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-spread-without-border-radius.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-spread-without-border-radius.html
deleted file mode 100644
index f62399abc..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-spread-without-border-radius.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>Reference File</title>
-    <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
-    <style type="text/css">
-        .container {
-            position: relative;
-        }
-        .ref {
-            background-color: green;
-            height: 160px;
-            left: 5px;
-            position: absolute;
-            top: 5px;
-            width: 160px;
-        }
-    </style>
-</head>
-<body>
-    <p>The test passes if there is a filled green square and no red.</p>
-    <div class="container">
-        <div class="ref"></div>
-    </div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-without-border-radius-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-without-border-radius-001-ref.html
new file mode 100644
index 0000000..7dfef37a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-without-border-radius-001-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest reference</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+  <style>
+  div
+    {
+      border-color: black;
+      border-style: solid;
+      display: inline-block;
+      vertical-align: top;
+    }
+  </style>
+
+  <div id="first-subtest" style="border-width: 0px 10px 10px 0px; height: 70px; width: 70px; margin: 42px 0px 0px 30px;"></div><div id="second-subtest" style="border-width: 5px 25px 25px 5px; height: 80px; width: 80px; margin: 27px 0px 0px 25px;"></div><div id="third-subtest" style="border-width: 10px 10px 0px 0px; height: 70px; width: 70px; margin: 22px 0px 0px 25px;"></div><div id="fourth-subtest" style="border-width: 25px 25px 5px 5px; height: 80px; width: 80px; margin: 7px 0px 0px 25px;"></div><br>
+
+  <div id="fifth-subtest" style="border-width: 0px 0px 10px 10px; height: 70px; width: 70px; margin: 49px 0px 0px 10px;"></div><div id="sixth-subtest" style="border-width: 5px 5px 25px 25px; height: 80px; width: 80px; margin: 34px 0px 0px 25px;"></div><div id="seventh-subtest" style="border-width: 10px 0px 0px 10px; height: 70px; width: 70px; margin: 29px 0px 0px 25px;"></div><div id="eighth-subtest" style="border-width: 25px 5px 5px 25px; height: 80px; width: 80px; margin: 14px 0px 0px 25px;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-without-border-radius.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-without-border-radius.html
deleted file mode 100644
index 2bca4c6..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/box-shadow-outset-without-border-radius.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>Reference File</title>
-    <link rel="author" title="Zhang Xiaochong" href="mailto:joy.xczhang@gmail.com">
-    <style type="text/css">
-        .container {
-            position: relative;
-        }
-        .ref {
-            background-color: green;
-            height: 150px;
-            left: 10px;
-            position: absolute;
-            top: 10px;
-            width: 150px;
-        }
-    </style>
-</head>
-<body>
-    <p>The test passes if there is a filled green square and no red.</p>
-    <div class="container">
-        <div class="ref"></div>
-    </div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
deleted file mode 100644
index 7749c322..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
+++ /dev/null
@@ -1,461 +0,0 @@
-This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = 3 duplicate test names: "e.style['color'] = "color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value", "e.style['color'] = "color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value", "e.style['color'] = "color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value"
-Found 456 tests; 440 PASS, 16 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS e.style['color'] = "color-mix(in srgb, red, blue)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, red, blue)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, red calc(20%), blue)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, red calc(var(--v)*1%), blue)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, currentcolor, blue)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, red 60%, blue 40%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch decreasing hue, red, hsl(120, 100%, 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, 25% hsl(120deg 10% 20%), hsl(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%), 25% hsl(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%) 30%, hsl(30deg 30% 40%) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%) 12.5%, hsl(30deg 30% 40%) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, 25% hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20% / .4), 25% hsl(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20% / .4) 25%, hsl(30deg 30% 40% / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20% / .4) 30%, hsl(30deg 30% 40% / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20% / .4) 12.5%, hsl(30deg 30% 40% / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20% / .4) 0%, hsl(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(40deg 50% 50%), hsl(60deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(60deg 50% 50%), hsl(40deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(50deg 50% 50%), hsl(330deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl shorter hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl shorter hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl shorter hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl shorter hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl shorter hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl shorter hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl longer hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl longer hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl longer hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl longer hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl longer hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl longer hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl increasing hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl increasing hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl increasing hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl increasing hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl increasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl increasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl decreasing hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl decreasing hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl decreasing hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl decreasing hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl decreasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl decreasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-PASS e.style['color'] = "color-mix(in hsl, hsl(none none none), hsl(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 20% none), hsl(30deg 40% 60%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 20% 40%), hsl(30deg 20% none))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(none 20% 40%), hsl(30deg none 80%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, lab(100 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value
-FAIL e.style['color'] = "color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value assert_equals: serialization should be canonical expected "color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" but got "color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)"
-PASS e.style['color'] = "color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value
-FAIL e.style['color'] = "color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value assert_equals: serialization should be canonical expected "color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" but got "color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)"
-PASS e.style['color'] = "color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), 25% hwb(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%) 30%, hwb(30deg 30% 40%) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%) 12.5%, hwb(30deg 30% 40%) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / .4) 25%, hwb(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, 25% hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), 25% hwb(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / .4) 25%, hwb(30deg 30% 40% / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / .4) 30%, hwb(30deg 30% 40% / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / .4) 12.5%, hwb(30deg 30% 40% / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / .4) 0%, hwb(30deg 30% 40% / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(40deg 30% 40%), hwb(60deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(60deg 30% 40%), hwb(40deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(50deg 30% 40%), hwb(330deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb shorter hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb shorter hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb shorter hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb shorter hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb shorter hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb shorter hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb longer hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb longer hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb longer hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb longer hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb longer hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb longer hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb increasing hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb increasing hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb increasing hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb increasing hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb increasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb increasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb decreasing hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb decreasing hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb decreasing hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb decreasing hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb decreasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb decreasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-PASS e.style['color'] = "color-mix(in hwb, hwb(none none none), hwb(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% none), hwb(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% none))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(none 10% 20%), hwb(30deg none 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40%))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, lab(100 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value
-FAIL e.style['color'] = "color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value assert_equals: serialization should be canonical expected "color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" but got "color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)"
-PASS e.style['color'] = "color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value
-FAIL e.style['color'] = "color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value assert_equals: serialization should be canonical expected "color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" but got "color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)"
-PASS e.style['color'] = "color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg), lch(50 60 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg) 25%, lch(50 60 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, 25% lch(10 20 30deg), lch(50 60 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg), 25% lch(50 60 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg), lch(50 60 70deg) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg) 25%, lch(50 60 70deg) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg) 30%, lch(50 60 70deg) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg) 12.5%, lch(50 60 70deg) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg) 0%, lch(50 60 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / .4), lch(50 60 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / .4) 25%, lch(50 60 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, 25% lch(10 20 30deg / .4), lch(50 60 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / .4), 25% lch(50 60 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / .4), lch(50 60 70deg / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / .4) 25%, lch(50 60 70deg / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / .4) 30%, lch(50 60 70deg / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / .4) 12.5%, lch(50 60 70deg / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / .4) 0%, lch(50 60 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(100 0 40deg), lch(100 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(100 0 60deg), lch(100 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(100 0 50deg), lch(100 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(100 0 330deg), lch(100 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(100 0 20deg), lch(100 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(100 0 320deg), lch(100 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch shorter hue, lch(100 0 40deg), lch(100 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch shorter hue, lch(100 0 60deg), lch(100 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch shorter hue, lch(100 0 50deg), lch(100 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch shorter hue, lch(100 0 330deg), lch(100 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch shorter hue, lch(100 0 20deg), lch(100 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch shorter hue, lch(100 0 320deg), lch(100 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch longer hue, lch(100 0 40deg), lch(100 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch longer hue, lch(100 0 60deg), lch(100 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch longer hue, lch(100 0 50deg), lch(100 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch longer hue, lch(100 0 330deg), lch(100 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch longer hue, lch(100 0 20deg), lch(100 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch longer hue, lch(100 0 320deg), lch(100 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch increasing hue, lch(100 0 40deg), lch(100 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch increasing hue, lch(100 0 60deg), lch(100 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch increasing hue, lch(100 0 50deg), lch(100 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch increasing hue, lch(100 0 330deg), lch(100 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch increasing hue, lch(100 0 20deg), lch(100 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch increasing hue, lch(100 0 320deg), lch(100 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 40deg), lch(100 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 60deg), lch(100 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 50deg), lch(100 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 330deg), lch(100 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 20deg), lch(100 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 320deg), lch(100 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(none none none), lch(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(none none none), lch(50 60 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg), lch(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 none), lch(50 60 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg), lch(50 60 none))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(none 20 30deg), lch(50 none 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / none), lch(50 60 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / none), lch(50 60 70deg / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / none), lch(50 60 70deg / none))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 25%, oklch(0.5 0.6 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, 25% oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), 25% oklch(0.5 0.6 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 25%, oklch(0.5 0.6 70deg) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 30%, oklch(0.5 0.6 70deg) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 12.5%, oklch(0.5 0.6 70deg) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 0%, oklch(0.5 0.6 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 25%, oklch(0.5 0.6 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, 25% oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4), 25% oklch(0.5 0.6 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 25%, oklch(0.5 0.6 70deg / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 30%, oklch(0.5 0.6 70deg / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 12.5%, oklch(0.5 0.6 70deg / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 0%, oklch(0.5 0.6 70deg / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(0.5 0.6 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 none), oklch(0.5 0.6 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 none))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(none 0.2 30deg), oklch(0.5 none 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg / none))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30), lab(50 60 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30) 25%, lab(50 60 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, 25% lab(10 20 30), lab(50 60 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30), 25% lab(50 60 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30), lab(50 60 70) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30) 25%, lab(50 60 70) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30) 30%, lab(50 60 70) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30) 12.5%, lab(50 60 70) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30) 0%, lab(50 60 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / .4), lab(50 60 70 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / .4) 25%, lab(50 60 70 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, 25% lab(10 20 30 / .4), lab(50 60 70 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / .4), 25% lab(50 60 70 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / .4), lab(50 60 70 / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / .4) 25%, lab(50 60 70 / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / .4) 30%, lab(50 60 70 / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / .4) 12.5%, lab(50 60 70 / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / .4) 0%, lab(50 60 70 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(none none none), lab(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(none none none), lab(50 60 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30), lab(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 none), lab(50 60 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30), lab(50 60 none))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(none 20 30), lab(50 none 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / none), lab(50 60 70))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / none), lab(50 60 70 / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / none), lab(50 60 70 / none))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, 25% oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), 25% oklab(0.5 0.6 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 30%, oklab(0.5 0.6 0.7) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 12.5%, oklab(0.5 0.6 0.7) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 0%, oklab(0.5 0.6 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 25%, oklab(0.5 0.6 0.7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, 25% oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), 25% oklab(0.5 0.6 0.7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 25%, oklab(0.5 0.6 0.7 / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 30%, oklab(0.5 0.6 0.7 / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 12.5%, oklab(0.5 0.6 0.7 / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 0%, oklab(0.5 0.6 0.7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(none none none), oklab(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(none none none), oklab(0.5 0.6 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 none), oklab(0.5 0.6 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 none))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(none 0.2 0.3), oklab(0.5 none 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / none))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3) 25%, color(srgb .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 .7) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3) 25%, color(srgb .5 .6 .7) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3) 30%, color(srgb .5 .6 .7) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3) 12.5%, color(srgb .5 .6 .7) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3) 0%, color(srgb .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / .5), color(srgb .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 25%, color(srgb .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 25%, color(srgb .5 .6 .7 / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 30%, color(srgb .5 .6 .7 / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 12.5%, color(srgb .5 .6 .7 / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 0%, color(srgb .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb 2 3 4 / 5), color(srgb 4 6 8 / 10))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb -2 -3 -4), color(srgb -4 -6 -8))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb -2 -3 -4 / -5), color(srgb -4 -6 -8 / -10))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb none none none), color(srgb none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb none none none), color(srgb .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 none), color(srgb .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 none))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb none .2 .3), color(srgb .5 none .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7 / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7 / none))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3) 25%, color(srgb-linear .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 .7) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3) 25%, color(srgb-linear .5 .6 .7) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3) 30%, color(srgb-linear .5 .6 .7) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3) 12.5%, color(srgb-linear .5 .6 .7) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3) 0%, color(srgb-linear .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / .5), color(srgb-linear .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / .4) 25%, color(srgb-linear .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / .4), color(srgb-linear .5 .6 .7 / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / .4) 25%, color(srgb-linear .5 .6 .7 / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / .4) 30%, color(srgb-linear .5 .6 .7 / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / .4) 12.5%, color(srgb-linear .5 .6 .7 / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / .4) 0%, color(srgb-linear .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear 2 3 4 / 5), color(srgb-linear 4 6 8 / 10))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear -2 -3 -4), color(srgb-linear -4 -6 -8))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear -2 -3 -4 / -5), color(srgb-linear -4 -6 -8 / -10))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear none none none), color(srgb-linear none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear none none none), color(srgb-linear .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 none), color(srgb-linear .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 none))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear none .2 .3), color(srgb-linear .5 none .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7 / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7 / none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3), color(xyz .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3) 25%, color(xyz .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3), color(xyz .5 .6 .7) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3) 25%, color(xyz .5 .6 .7) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3) 30%, color(xyz .5 .6 .7) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3) 12.5%, color(xyz .5 .6 .7) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3) 0%, color(xyz .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / .5), color(xyz .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 30%, color(xyz .5 .6 .7 / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 12.5%, color(xyz .5 .6 .7 / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 0%, color(xyz .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz 2 3 4 / 5), color(xyz 4 6 8 / 10))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz -2 -3 -4), color(xyz -4 -6 -8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz -2 -3 -4 / -5), color(xyz -4 -6 -8 / -10))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz none none none), color(xyz none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz none none none), color(xyz .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3), color(xyz none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 none), color(xyz .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3), color(xyz .5 .6 none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz none .2 .3), color(xyz .5 none .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7 / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7 / none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3) 25%, color(xyz-d50 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 .7) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3) 25%, color(xyz-d50 .5 .6 .7) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3) 30%, color(xyz-d50 .5 .6 .7) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3) 12.5%, color(xyz-d50 .5 .6 .7) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3) 0%, color(xyz-d50 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / .5), color(xyz-d50 .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / .4) 25%, color(xyz-d50 .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / .4), color(xyz-d50 .5 .6 .7 / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / .4) 25%, color(xyz-d50 .5 .6 .7 / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / .4) 30%, color(xyz-d50 .5 .6 .7 / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / .4) 12.5%, color(xyz-d50 .5 .6 .7 / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / .4) 0%, color(xyz-d50 .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 2 3 4 / 5), color(xyz-d50 4 6 8 / 10))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 -2 -3 -4), color(xyz-d50 -4 -6 -8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 -2 -3 -4 / -5), color(xyz-d50 -4 -6 -8 / -10))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 none none none), color(xyz-d50 none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 none none none), color(xyz-d50 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 none), color(xyz-d50 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 none .2 .3), color(xyz-d50 .5 none .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7 / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7 / none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3) 25%, color(xyz-d65 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 .7) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3) 25%, color(xyz-d65 .5 .6 .7) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3) 30%, color(xyz-d65 .5 .6 .7) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3) 12.5%, color(xyz-d65 .5 .6 .7) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3) 0%, color(xyz-d65 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / .5), color(xyz-d65 .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / .4) 25%, color(xyz-d65 .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / .4), color(xyz-d65 .5 .6 .7 / .8) 25%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / .4) 25%, color(xyz-d65 .5 .6 .7 / .8) 75%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / .4) 30%, color(xyz-d65 .5 .6 .7 / .8) 90%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / .4) 12.5%, color(xyz-d65 .5 .6 .7 / .8) 37.5%)" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / .4) 0%, color(xyz-d65 .5 .6 .7 / .8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 2 3 4 / 5), color(xyz-d65 4 6 8 / 10))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 -2 -3 -4), color(xyz-d65 -4 -6 -8))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 -2 -3 -4 / -5), color(xyz-d65 -4 -6 -8 / -10))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 none none none), color(xyz-d65 none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 none none none), color(xyz-d65 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 none none none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 none), color(xyz-d65 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 none))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 none .2 .3), color(xyz-d65 .5 none .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7 / 0.5))" should set the property value
-PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7 / none))" should set the property value
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html
index 659117a23..1df42804 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html
@@ -79,14 +79,6 @@
     test_valid_value(`color`, `color-mix(in hsl decreasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))`, `color-mix(in hsl decreasing hue, rgb(191, 106, 64), rgb(191, 64, 149))`);
     test_valid_value(`color`, `color-mix(in hsl decreasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))`, `color-mix(in hsl decreasing hue, rgb(191, 64, 149), rgb(191, 106, 64))`);
 
-
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))`, `color-mix(in hsl specified hue, rgb(191, 149, 64), rgb(191, 191, 64))`);
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))`, `color-mix(in hsl specified hue, rgb(191, 191, 64), rgb(191, 149, 64))`);
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))`, `color-mix(in hsl specified hue, rgb(191, 170, 64), rgb(191, 64, 128))`);
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))`, `color-mix(in hsl specified hue, rgb(191, 64, 128), rgb(191, 170, 64))`);
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))`, `color-mix(in hsl specified hue, rgb(191, 106, 64), rgb(191, 64, 149))`);
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))`, `color-mix(in hsl specified hue, rgb(191, 64, 149), rgb(191, 106, 64))`);
-
     test_valid_value(`color`, `color-mix(in hsl, hsl(none none none), hsl(none none none))`, `color-mix(in hsl, rgb(0, 0, 0), rgb(0, 0, 0))`);
     test_valid_value(`color`, `color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))`, `color-mix(in hsl, rgb(0, 0, 0), rgb(224, 204, 184))`);
     test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))`, `color-mix(in hsl, rgb(82, 122, 82), rgb(0, 0, 0))`);
@@ -103,11 +95,10 @@
     test_valid_value(`color`, `color-mix(in hsl, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hsl, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hsl, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`);
-    test_valid_value(`color`, `color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
+    test_valid_value(`color`, `color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
-    test_valid_value(`color`, `color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
+    test_valid_value(`color`, `color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
-    test_valid_value(`color`, `color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
 
@@ -166,13 +157,6 @@
     test_valid_value(`color`, `color-mix(in hwb decreasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))`, `color-mix(in hwb decreasing hue, rgb(153, 102, 77), rgb(153, 77, 128))`);
     test_valid_value(`color`, `color-mix(in hwb decreasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))`, `color-mix(in hwb decreasing hue, rgb(153, 77, 128), rgb(153, 102, 77))`);
 
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))`, `color-mix(in hwb specified hue, rgb(153, 128, 77), rgb(153, 153, 77))`);
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))`, `color-mix(in hwb specified hue, rgb(153, 153, 77), rgb(153, 128, 77))`);
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))`, `color-mix(in hwb specified hue, rgb(153, 140, 77), rgb(153, 77, 115))`);
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))`, `color-mix(in hwb specified hue, rgb(153, 77, 115), rgb(153, 140, 77))`);
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))`, `color-mix(in hwb specified hue, rgb(153, 102, 77), rgb(153, 77, 128))`);
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))`, `color-mix(in hwb specified hue, rgb(153, 77, 128), rgb(153, 102, 77))`);
-
     test_valid_value(`color`, `color-mix(in hwb, hwb(none none none), hwb(none none none))`, `color-mix(in hwb, rgb(255, 0, 0), rgb(255, 0, 0))`);
     test_valid_value(`color`, `color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))`, `color-mix(in hwb, rgb(255, 0, 0), rgb(153, 115, 77))`);
     test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))`, `color-mix(in hwb, rgb(26, 204, 26), rgb(255, 0, 0))`);
@@ -188,15 +172,12 @@
     test_valid_value(`color`, `color-mix(in hwb, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hwb, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hwb, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`);
-    test_valid_value(`color`, `color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
+    test_valid_value(`color`, `color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
-    test_valid_value(`color`, `color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
+    test_valid_value(`color`, `color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
-
     test_valid_value(`color`, `color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
-    test_valid_value(`color`, `color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`);
     test_valid_value(`color`, `color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
-    test_valid_value(`color`, `color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`);
 
     // lch()
     test_valid_value(`color`, `color-mix(in lch, lch(10 20 30deg), lch(50 60 70deg))`, `color-mix(in lch, lch(10 20 30), lch(50 60 70))`);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009-ref.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009-ref.html
index b0d269a..2ee9d0a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009-ref.html
@@ -11,7 +11,7 @@
   div {
     clear: left;
     float: left;
-    font: 64px/128px test;
+    font: 60px/120px test;
     color: orange;
     background: orange;
   }
@@ -22,12 +22,12 @@
   #test2 {
     color: blue;
     background: blue;
-    font-size: 96px;
+    font-size: 90px;
   }
   #test3 {
     color: magenta;
     background: magenta;
-    font-size: 48px;
+    font-size: 45px;
   }
 </style>
 <body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009.html
index 765447b2..133f96f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009.html
@@ -17,7 +17,7 @@
   div {
     clear: left;
     float: left;
-    font: 64px/128px test;
+    font: 60px/120px test;
     color: orange;
     background: orange;
   }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009.html.ini b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009.html.ini
deleted file mode 100644
index 2396ffa..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-009.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[font-size-adjust-009.html]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-010.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-010.html
index 6ee3ab7..c3b2bc1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-010.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-010.html
@@ -17,7 +17,7 @@
   div {
     clear: left;
     float: left;
-    font: 64px/128px test;
+    font: 60px/120px test;
     color: orange;
     background: orange;
   }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-010.html.ini b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-010.html.ini
deleted file mode 100644
index 0d99bb3..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-010.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[font-size-adjust-010.html]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-011.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-011.html
index f4ac39c2..3f6afd8a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-011.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-011.html
@@ -17,7 +17,7 @@
   div {
     clear: left;
     float: left;
-    font: 64px/128px test;
+    font: 60px/120px test;
     color: orange;
     background: orange;
   }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-011.html.ini b/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-011.html.ini
deleted file mode 100644
index 74ab826..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/font-size-adjust-011.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[font-size-adjust-011.html]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-none-video.html.ini b/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-none-video.html.ini
new file mode 100644
index 0000000..2dab034
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-none-video.html.ini
@@ -0,0 +1,3 @@
+[object-view-box-fit-none-video.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length2.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length2.html
index 0d86120..5a8e228 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length2.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length2.html
@@ -7,7 +7,7 @@
     width: 100px;
     height: 100px;
     background-color: green;
-    animation: clippath2 10s, clippath1 2s 1s;
+    animation: clippath2 100s, clippath1 20s 30s;
   }
 
   @keyframes clippath1 {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-svg-text-backdrop-filter.html.ini b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-svg-text-backdrop-filter.html.ini
index f181a1c..3bb4375 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-svg-text-backdrop-filter.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-svg-text-backdrop-filter.html.ini
@@ -1,3 +1,4 @@
 [clip-path-svg-text-backdrop-filter.html]
   expected:
     if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
+    if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scrollbars/inheritance-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-scrollbars/inheritance-expected.txt
deleted file mode 100644
index 754ac3a..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-scrollbars/inheritance-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL Property scrollbar-color has initial value auto assert_true: scrollbar-color doesn't seem to be supported in the computed style expected true got false
-FAIL Property scrollbar-color inherits assert_true: scrollbar-color doesn't seem to be supported in the computed style expected true got false
-PASS Property scrollbar-width has initial value auto
-PASS Property scrollbar-width does not inherit
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scrollbars/inheritance.html.ini b/third_party/blink/web_tests/external/wpt/css/css-scrollbars/inheritance.html.ini
deleted file mode 100644
index 21f956e6..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-scrollbars/inheritance.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[inheritance.html]
-  [Property scrollbar-color has initial value auto]
-    expected: FAIL
-
-  [Property scrollbar-color inherits]
-    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scrollbars/scrollbar-color-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-scrollbars/scrollbar-color-parsing.html
new file mode 100644
index 0000000..17b649d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-scrollbars/scrollbar-color-parsing.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Scrollbars: parsing scrollbar-color declarations</title>
+<link rel="help" href="https://drafts.csswg.org/css-scrollbars/"/>
+<meta name="assert" content="Parsing scrollbar-color declarations">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+
+<script>
+    test_valid_value('scrollbar-color', 'initial');
+    test_valid_value('scrollbar-color', 'inherit');
+    test_valid_value('scrollbar-color', 'unset');
+    test_valid_value('scrollbar-color', 'revert');
+    test_valid_value('scrollbar-color', 'auto');
+    test_valid_value("scrollbar-color", "red green");
+    test_valid_value("scrollbar-color", "#FF0000 #00FF00", "rgb(255, 0, 0) rgb(0, 255, 0)");
+    test_valid_value("scrollbar-color", "currentcolor currentcolor");
+
+    test_invalid_value("scrollbar-color", "");
+    test_invalid_value("scrollbar-color", "auto auto");
+    test_invalid_value("scrollbar-color", "auto currentcolor");
+    test_invalid_value("scrollbar-color", "red");
+    test_invalid_value("scrollbar-color", "#FF0000");
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/3d-rendering-context-and-z-ordering-002.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/3d-rendering-context-and-z-ordering-002.html.ini
new file mode 100644
index 0000000..e636573f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/3d-rendering-context-and-z-ordering-002.html.ini
@@ -0,0 +1,3 @@
+[3d-rendering-context-and-z-ordering-002.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-003.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-003.html.ini
index 2c5b9a6d..b376273 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-003.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-003.html.ini
@@ -1,5 +1,6 @@
 [preserve3d-and-flattening-003.html]
   expected:
-    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
+    if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
     if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
+    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
     if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-002.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-002.html.ini
new file mode 100644
index 0000000..d3268dc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-002.html.ini
@@ -0,0 +1,3 @@
+[preserve3d-and-flattening-z-order-002.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-backface-visibility-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-backface-visibility-001.html.ini
new file mode 100644
index 0000000..7f82adb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-backface-visibility-001.html.ini
@@ -0,0 +1,3 @@
+[transform3d-backface-visibility-001.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-perspective-004.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-perspective-004.html.ini
new file mode 100644
index 0000000..2176796
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-perspective-004.html.ini
@@ -0,0 +1,3 @@
+[transform3d-perspective-004.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-sorting-004.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-sorting-004.html.ini
new file mode 100644
index 0000000..4a1d7c3f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-sorting-004.html.ini
@@ -0,0 +1,3 @@
+[transform3d-sorting-004.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-right-color-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-right-color-001.html.ini
new file mode 100644
index 0000000..dd18d837
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-right-color-001.html.ini
@@ -0,0 +1,3 @@
+[kind-of-widget-fallback-color-input-border-right-color-001.html]
+  expected:
+    if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-block-end-width-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-block-end-width-001.html.ini
index 01b12488..72865fa 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-block-end-width-001.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-block-end-width-001.html.ini
@@ -1,3 +1,4 @@
 [kind-of-widget-fallback-input-search-border-block-end-width-001.html]
   expected:
     if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
+    if (product == "content_shell") and (os == "linux"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-image-outset-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-image-outset-001.html.ini
index 0094530e..a8737159 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-image-outset-001.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-image-outset-001.html.ini
@@ -1,3 +1,4 @@
 [kind-of-widget-fallback-input-search-border-image-outset-001.html]
   expected:
     if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
+    if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-bottom-width-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-bottom-width-001.html.ini
new file mode 100644
index 0000000..ef5ce44
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-bottom-width-001.html.ini
@@ -0,0 +1,3 @@
+[kind-of-widget-fallback-input-text-border-bottom-width-001.html]
+  expected:
+    if (product == "content_shell") and (os == "linux"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-top-width-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-top-width-001.html.ini
index e03dc2c..88c3007 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-top-width-001.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-top-width-001.html.ini
@@ -1,3 +1,3 @@
 [kind-of-widget-fallback-input-text-border-top-width-001.html]
   expected:
-    if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): FAIL
+    if (product == "content_shell") and (os == "win"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/old-content-captures-clip-path.html b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/old-content-captures-clip-path.html
index a2faa7f..467b19d9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/old-content-captures-clip-path.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/old-content-captures-clip-path.html
@@ -4,6 +4,7 @@
 <link rel="help" href="https://github.com/WICG/view-transitions">
 <link rel="author" href="mailto:vmpstr@chromium.org">
 <link rel="match" href="old-content-captures-clip-path-ref.html">
+<meta name="fuzzy" content="old-content-captures-clip-path-ref.html:0-1;0-500">
 <script src="/common/reftest-wait.js"></script>
 <style>
 .box {
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/css-backdrop-filters-animation-saturate.html.ini b/third_party/blink/web_tests/external/wpt/css/filter-effects/css-backdrop-filters-animation-saturate.html.ini
new file mode 100644
index 0000000..0564545
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/css-backdrop-filters-animation-saturate.html.ini
@@ -0,0 +1,3 @@
+[css-backdrop-filters-animation-saturate.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/has-with-nth-child.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/has-with-nth-child.html
new file mode 100644
index 0000000..e8d7d062
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/has-with-nth-child.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Selectors Test: :has(:nth-child()) invalidation for sibling change</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
+<style>
+  #test-container > div { background-color: green; }
+  #target1:has(.item:nth-child(3)) { background-color: red; }
+  #target2:has(.item:nth-last-child(3)) { background-color: red; }
+  #target3:has(.item:nth-child(3) > .child) { background-color: red; }
+  #target4:has(.item:nth-last-child(3) > .child) { background-color: red; }
+</style>
+<div id="test-container">
+  <div id="target1">
+    <div class="item" id="item1">FAIL if you see this text</div>
+    <div class="item"></div>
+    <div class="item">This text should have a green background</div>
+  </div>
+  <div id="target2">
+    <div class="item">This text should have a green background</div>
+    <div class="item"></div>
+    <div class="item" id="item2">FAIL if you see this text</div>
+  </div>
+  <div id="target3">
+    <div class="item" id="item3">FAIL if you see this text</div>
+    <div class="item"></div>
+    <div class="item">
+      <span class="child">This text should have a green background<span>
+    </div>
+  </div>
+  <div id="target4">
+    <div class="item">
+      <span class="child">This text should have a green background<span>
+    </div>
+    <div class="item"></div>
+    <div class="item" id="item4">FAIL if you see this text</div>
+  </div>
+</div>
+<script>
+  test(() => {
+    assert_equals(getComputedStyle(target1).backgroundColor, "rgb(255, 0, 0)");
+    assert_equals(getComputedStyle(target2).backgroundColor, "rgb(255, 0, 0)");
+    assert_equals(getComputedStyle(target3).backgroundColor, "rgb(255, 0, 0)");
+    assert_equals(getComputedStyle(target4).backgroundColor, "rgb(255, 0, 0)");
+  }, "Initially red");
+
+  test(() => {
+    item1.remove();
+    assert_equals(getComputedStyle(target1).backgroundColor, "rgb(0, 128, 0)");
+  }, ":nth-child() no longer matching after removal");
+
+  test(() => {
+    item2.remove();
+    assert_equals(getComputedStyle(target2).backgroundColor, "rgb(0, 128, 0)");
+  }, ":nth-last-child() no longer matching after removal");
+
+  test(() => {
+    item3.remove();
+    assert_equals(getComputedStyle(target3).backgroundColor, "rgb(0, 128, 0)");
+  }, ":nth-child() in non-subject no longer matching after removal");
+
+  test(() => {
+    item4.remove();
+    assert_equals(getComputedStyle(target4).backgroundColor, "rgb(0, 128, 0)");
+  }, ":nth-last-child() in non-subject no longer matching after removal");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/nth-child-of-attr-largedom.html.ini b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/nth-child-of-attr-largedom.html.ini
new file mode 100644
index 0000000..28f9700
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/nth-child-of-attr-largedom.html.ini
@@ -0,0 +1,3 @@
+[nth-child-of-attr-largedom.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/nth-child-of-pseudo-ref.html b/third_party/blink/web_tests/external/wpt/css/selectors/nth-child-of-pseudo-ref.html
new file mode 100644
index 0000000..7e816b5f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/nth-child-of-pseudo-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test Reference</title>
+<div class="a">a</div>
+<div class="b">xb</div>
+<div class="a">a</div>
+<div class="b">b</div>
+<div class="a">a</div>
+<div class="b">xb</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/nth-child-of-pseudo.html b/third_party/blink/web_tests/external/wpt/css/selectors/nth-child-of-pseudo.html
new file mode 100644
index 0000000..7113af90
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/nth-child-of-pseudo.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: :nth-child(of) with pseudo-elements</title>
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#child-index">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1834717">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="match" href="nth-child-of-pseudo-ref.html">
+<style>
+div:nth-child(odd of .b)::before {
+  content: "x";
+}
+</style>
+<div class="a">a</div>
+<div class="b">b</div>
+<div class="a">a</div>
+<div class="b">b</div>
+<div class="a">a</div>
+<div class="b">b</div>
diff --git a/third_party/blink/web_tests/external/wpt/docs/Dockerfile b/third_party/blink/web_tests/external/wpt/docs/Dockerfile
index bf5b7088..757552686 100644
--- a/third_party/blink/web_tests/external/wpt/docs/Dockerfile
+++ b/third_party/blink/web_tests/external/wpt/docs/Dockerfile
@@ -4,10 +4,8 @@
 ENV DEBIAN_FRONTEND=noninteractive \
     DEBCONF_NONINTERACTIVE_SEEN=true
 
-# Documentation is generated using Python 3.9 due to spinx-js not
-# supporting 3.10: https://github.com/mozilla/sphinx-js/issues/186
 RUN apt-get -qqy update \
-  && apt-get -qqy install git npm python3.9 python3.9-venv
+  && apt-get -qqy install git npm python3 python3-venv
 
 WORKDIR /app/
 
@@ -20,6 +18,6 @@
 # setting the environment variables needed for this to always be active. The
 # `./wpt build-docs` then uses this venv with --skip-venv-setup.
 ENV VIRTUAL_ENV=/app/venv
-RUN python3.9 -m venv $VIRTUAL_ENV
+RUN python3 -m venv $VIRTUAL_ENV
 ENV PATH=$VIRTUAL_ENV/bin:$PATH
 RUN pip install -r requirements.txt
diff --git a/third_party/blink/web_tests/external/wpt/docs/running-tests/chrome.md b/third_party/blink/web_tests/external/wpt/docs/running-tests/chrome.md
index 45293af6..aca93ea 100644
--- a/third_party/blink/web_tests/external/wpt/docs/running-tests/chrome.md
+++ b/third_party/blink/web_tests/external/wpt/docs/running-tests/chrome.md
@@ -27,7 +27,7 @@
 ./wpt run --binary-arg=--enable-blink-features=AsyncClipboard chrome clipboard-apis/
 ```
 
-[A detailed explanation is available](running-tests/chrome-chromium-installation-detection.html)
+[A detailed explanation is available](chrome-chromium-installation-detection.html)
 for more information on how wpt detects and installs the components for Chrome and Chromium.
 
 [1]: https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/platform/RuntimeEnabledFeatures.md
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.svg.html.ini b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.svg.html.ini
deleted file mode 100644
index c66b969..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.svg.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[2d.drawImage.svg.html]
-  expected:
-    if product == "chrome": ERROR
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html.ini b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html.ini
deleted file mode 100644
index 3f7b04de8..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[2d.drawImage.zerosource.image.html]
-  expected:
-    if product == "chrome": ERROR
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html.ini b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html.ini
deleted file mode 100644
index 9fdafd3e..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[2d.pattern.paint.repeat.basic.html]
-  expected: ERROR
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html.ini b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html.ini
deleted file mode 100644
index d423abd..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[2d.pattern.paint.repeat.outside.html]
-  expected: ERROR
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/gentestutilsunion.py b/third_party/blink/web_tests/external/wpt/html/canvas/tools/gentestutilsunion.py
index 73c28e3..2ffd374 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/gentestutilsunion.py
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/gentestutilsunion.py
@@ -233,20 +233,20 @@
     return code
 
 
-class CanvasType(str, enum.Enum):
+class TestType(str, enum.Enum):
     HTML_CANVAS = 'htmlcanvas'
     OFFSCREEN_CANVAS = 'offscreencanvas'
+    WORKER = 'worker'
 
 
-def _get_enabled_canvas_types(test: Mapping[str, Any]) -> List[CanvasType]:
-    return [CanvasType(t.lower()) for t in test.get('canvasType', CanvasType)]
+def _get_enabled_test_types(test: Mapping[str, Any]) -> set[TestType]:
+    return {TestType(t.lower()) for t in test.get('canvasType', TestType)}
 
 
 @dataclasses.dataclass
 class TestConfig:
     out_dir: str
     image_out_dir: str
-    enabled: bool
 
 
 _CANVAS_SIZE_REGEX = re.compile(r'(?P<width>.*), (?P<height>.*)',
@@ -267,8 +267,8 @@
 def _write_reference_test(test: Mapping[str, Any],
                           jinja_env: jinja2.Environment,
                           template_params: MutableMapping[str, Any],
-                          canvas_path: Optional[str],
-                          offscreen_path: Optional[str]):
+                          enabled_tests: set[TestType],
+                          canvas_path: str, offscreen_path: str):
     name = template_params["name"]
     js_ref = test.get('reference')
     html_ref = test.get('html_reference')
@@ -279,11 +279,11 @@
 
     ref_params = template_params | {'code': js_ref or html_ref}
     ref_template_name = 'reftest_element.html' if js_ref else 'reftest.html'
-    if canvas_path:
+    if TestType.HTML_CANVAS in enabled_tests:
         pathlib.Path(f'{canvas_path}-expected.html').write_text(
             jinja_env.get_template(ref_template_name).render(ref_params),
             'utf-8')
-    if offscreen_path:
+    if {TestType.OFFSCREEN_CANVAS, TestType.WORKER} & enabled_tests:
         pathlib.Path(f'{offscreen_path}-expected.html').write_text(
             jinja_env.get_template(ref_template_name).render(ref_params),
             'utf-8')
@@ -292,14 +292,15 @@
         'ref_link': f'{name}-expected.html',
         'fuzzy': test.get('fuzzy')
     }
-    if canvas_path:
+    if TestType.HTML_CANVAS in enabled_tests:
         pathlib.Path(f'{canvas_path}.html').write_text(
             jinja_env.get_template("reftest_element.html").render(params),
             'utf-8')
-    if offscreen_path:
+    if TestType.OFFSCREEN_CANVAS in enabled_tests:
         pathlib.Path(f'{offscreen_path}.html').write_text(
             jinja_env.get_template("reftest_offscreen.html").render(params),
             'utf-8')
+    if TestType.WORKER in enabled_tests:
         pathlib.Path(f'{offscreen_path}.w.html').write_text(
             jinja_env.get_template("reftest_worker.html").render(params),
             'utf-8')
@@ -307,29 +308,32 @@
 
 def _write_testharness_test(jinja_env: jinja2.Environment,
                             template_params: MutableMapping[str, Any],
-                            canvas_path: Optional[str],
-                            offscreen_path: Optional[str]):
+                            enabled_tests: set[TestType],
+                            canvas_path: str,
+                            offscreen_path: str):
     # Create test cases for canvas and offscreencanvas.
-    if canvas_path:
+    if TestType.HTML_CANVAS in enabled_tests:
         pathlib.Path(f'{canvas_path}.html').write_text(
             jinja_env.get_template("testharness_element.html").render(
                 template_params), 'utf-8')
 
-    if offscreen_path:
-        template_params['done_needed'] = ('then(t_pass, t_fail);'
-                                          not in template_params['code'])
+    template_params['done_needed'] = ('then(t_pass, t_fail);'
+                                      not in template_params['code'])
 
+    if TestType.OFFSCREEN_CANVAS in enabled_tests:
         pathlib.Path(f'{offscreen_path}.html').write_text(
             jinja_env.get_template("testharness_offscreen.html").render(
                 template_params), 'utf-8')
 
+    if TestType.WORKER in enabled_tests:
         pathlib.Path(f'{offscreen_path}.worker.js').write_text(
             jinja_env.get_template("testharness_worker.js").render(
                 template_params), 'utf-8')
 
 
 def _generate_test(test: Mapping[str, Any], jinja_env: jinja2.Environment,
-                   sub_dir: str, html_canvas_cfg: TestConfig,
+                   sub_dir: str, enabled_tests: set[TestType],
+                   html_canvas_cfg: TestConfig,
                    offscreen_canvas_cfg: TestConfig) -> None:
     name = test['name']
 
@@ -353,17 +357,20 @@
                 r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
                 r'\ncr = cairo.Context(surface)', expected)
 
-            expected_canvas = (
-                expected + "\nsurface.write_to_png('%s.png')\n" %
-                os.path.join(html_canvas_cfg.image_out_dir, sub_dir, name))
-            eval(compile(expected_canvas, '<test %s>' % name, 'exec'), {},
-                 {'cairo': cairo})
+            if TestType.HTML_CANVAS in enabled_tests:
+                expected_canvas = (
+                    expected + "\nsurface.write_to_png('%s.png')\n" %
+                    os.path.join(html_canvas_cfg.image_out_dir, sub_dir, name))
+                eval(compile(expected_canvas, '<test %s>' % name, 'exec'), {},
+                    {'cairo': cairo})
 
-            expected_offscreencanvas = (
-                expected + "\nsurface.write_to_png('%s.png')\n" % os.path.join(
-                    offscreen_canvas_cfg.image_out_dir, sub_dir, name))
-            eval(compile(expected_offscreencanvas, '<test %s>' % name, 'exec'),
-                 {}, {'cairo': cairo})
+            if {TestType.OFFSCREEN_CANVAS, TestType.WORKER} & enabled_tests:
+                expected_offscreen = (
+                    expected +
+                    "\nsurface.write_to_png('%s.png')\n" % os.path.join(
+                        offscreen_canvas_cfg.image_out_dir, sub_dir, name))
+                eval(compile(expected_offscreen, '<test %s>' % name, 'exec'),
+                     {}, {'cairo': cairo})
 
             expected_img = '%s.png' % name
 
@@ -421,15 +428,11 @@
         offscreen_path += '-manual'
 
     if 'reference' in test or 'html_reference' in test:
-        _write_reference_test(
-            test, jinja_env, template_params,
-            canvas_path if html_canvas_cfg.enabled else None,
-            offscreen_path if offscreen_canvas_cfg.enabled else None)
+        _write_reference_test(test, jinja_env, template_params, enabled_tests,
+                              canvas_path, offscreen_path)
     else:
-        _write_testharness_test(
-            jinja_env, template_params,
-            canvas_path if html_canvas_cfg.enabled else None,
-            offscreen_path if offscreen_canvas_cfg.enabled else None)
+        _write_testharness_test(jinja_env, template_params, enabled_tests,
+                                canvas_path, offscreen_path)
 
 
 def genTestUtils_union(NAME2DIRFILE: str) -> None:
@@ -502,28 +505,26 @@
             name = test['name']
             print('\r(%s)' % name, ' ' * 32, '\t')
 
-            enabled_canvas_types = _get_enabled_canvas_types(test)
+            enabled_test_types = _get_enabled_test_types(test)
 
             already_tested = used_tests[name].intersection(
-                enabled_canvas_types)
+                enabled_test_types)
             if already_tested:
                 raise InvalidTestDefinitionError(
                     f'Test {name} is defined twice for types {already_tested}')
-            used_tests[name].update(enabled_canvas_types)
+            used_tests[name].update(enabled_test_types)
 
             sub_dir = _get_test_sub_dir(name, name_to_sub_dir)
             _generate_test(
                 test,
                 jinja_env,
                 sub_dir,
+                enabled_test_types,
                 html_canvas_cfg=TestConfig(
                     out_dir=CANVASOUTPUTDIR,
-                    image_out_dir=CANVASIMAGEOUTPUTDIR,
-                    enabled=CanvasType.HTML_CANVAS in enabled_canvas_types),
+                    image_out_dir=CANVASIMAGEOUTPUTDIR),
                 offscreen_canvas_cfg=TestConfig(
                     out_dir=OFFSCREENCANVASOUTPUTDIR,
-                    image_out_dir=OFFSCREENCANVASIMAGEOUTPUTDIR,
-                    enabled=CanvasType.OFFSCREEN_CANVAS in
-                    enabled_canvas_types))
+                    image_out_dir=OFFSCREENCANVASIMAGEOUTPUTDIR))
 
     print()
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/compositing.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/compositing.yaml
index 0051f07d..bd7fae1 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/compositing.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/compositing.yaml
@@ -173,7 +173,7 @@
   expected: green
 
 - name: 2d.composite.globalAlpha.canvas
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     var offscreenCanvas2 = new OffscreenCanvas(100, 50);
     var ctx2 = offscreenCanvas2.getContext('2d');
@@ -203,7 +203,7 @@
   expected: green
 
 - name: 2d.composite.globalAlpha.canvaspattern
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     var offscreenCanvas2 = new OffscreenCanvas(100, 50);
     var ctx2 = offscreenCanvas2.getContext('2d');
@@ -218,7 +218,7 @@
     @assert pixel 50,25 ==~ 2,253,0,255;
 
 - name: 2d.composite.globalAlpha.canvascopy
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     var offscreenCanvas2 = new OffscreenCanvas(100, 50);
     var ctx2 = offscreenCanvas2.getContext('2d');
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
index e183734..75eed14e 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
@@ -343,7 +343,7 @@
     @assert pixel 99,49 ==~ 0,255,0,255;
 
 - name: 2d.drawImage.canvas
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     var offscreenCanvas2 = new OffscreenCanvas(100, 50);
     var ctx2 = offscreenCanvas2.getContext('2d');
@@ -357,7 +357,7 @@
     @assert pixel 99,49 ==~ 0,255,0,255;
 
 - name: 2d.drawImage.zerocanvas
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     var offscreenCanvas2 = new OffscreenCanvas(0, 10);
     @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
@@ -424,7 +424,7 @@
 - name: 2d.drawImage.zerosource.image
   desc: drawImage with zero-sized source rectangle from image draws nothing without exception
   test_type: promise
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
@@ -519,7 +519,7 @@
 
 - name: 2d.drawImage.outsidesource
   DISABLED: fix this to match the current spec (transparent black outside source)
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     const response_red = await fetch('/images/red.png');
     const blob_red = await response_red.blob();
@@ -572,7 +572,7 @@
 - name: 2d.drawImage.svg
   desc: drawImage() of an SVG image
   test_type: promise
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     var promise = new Promise(function(resolve, reject) {
       var xhr = new XMLHttpRequest();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml
index dd84f91..9a90bed 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml
@@ -61,7 +61,7 @@
 
 - name: 2d.filter.canvasFilterObject.tentative
   desc: Test CanvasFilter() object
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     @assert ctx.filter == 'none';
     ctx.filter = 'blur(5px)';
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/layers.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/layers.yaml
index fe1902c..e0d2b3d7 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/layers.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/layers.yaml
@@ -317,7 +317,7 @@
   variants:
     convertToBlob:
       test_type: "promise"
-      canvasType: ['OffscreenCanvas']
+      canvasType: ['OffscreenCanvas', 'Worker']
       flush_canvas: |-
         await canvas.convertToBlob();
     createImageBitmap:
@@ -352,7 +352,7 @@
 - name: 2d.layer.render-opportunities.transferToImageBitmap
   desc: Checks that transferToImageBitmap flushes and rebuilds the state stack.
   size: 200, 200
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     ctx.fillStyle = 'purple';
     ctx.fillRect(60, 60, 75, 50);
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/pixel-manipulation.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/pixel-manipulation.yaml
index b9bdf3d2..0643b04 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/pixel-manipulation.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/pixel-manipulation.yaml
@@ -818,7 +818,7 @@
 
 - name: 2d.imageData.put.cross
   desc: putImageData() accepts image data got from a different canvas
-  canvasType: ['OffscreenCanvas']
+  canvasType: ['OffscreenCanvas', 'Worker']
   code: |
     var offscreenCanvas2 = new OffscreenCanvas(100, 50);
     var ctx2 = offscreenCanvas2.getContext('2d');
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.js b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.js
index 0bfa72e..5e259a5a 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.js
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/shared-worker.https.window.js
@@ -1,16 +1,60 @@
+// META: variant=?request_origin=same_origin&worker_coep=none&window_coep=none
+// META: variant=?request_origin=same_origin&worker_coep=none&window_coep=credentialless
+// META: variant=?request_origin=same_origin&worker_coep=credentialless&window_coep=none
+// META: variant=?request_origin=same_origin&worker_coep=credentialless&window_coep=credentialless
+// META: variant=?request_origin=cross_origin&worker_coep=none&window_coep=none
+// META: variant=?request_origin=cross_origin&worker_coep=none&window_coep=credentialless
+// META: variant=?request_origin=cross_origin&worker_coep=credentialless&window_coep=none
+// META: variant=?request_origin=cross_origin&worker_coep=credentialless&window_coep=credentialless
 // META: timeout=long
 // META: script=/common/get-host-info.sub.js
 // META: script=/common/utils.js
 // META: script=/common/dispatcher/dispatcher.js
 // META: script=./resources/common.js
 
+// Test description:
+//   Request a resource from a SharedWorker. Check the request's cookies.
+//
+// Variant:
+//   - The Window COEP policy: none or credentialless.
+//   - The SharedWorker COEP policy: none or credentialless.
+//   - The SharedWorker's request URL origin: same-origin or cross-origin.
+
 const same_origin = get_host_info().HTTPS_ORIGIN;
 const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
-const cookie_key = "credentialless_shared_worker";
+const cookie_key = token();
 const cookie_same_origin = "same_origin";
 const cookie_cross_origin = "cross_origin";
 
+const variants = new URLSearchParams(window.location.search);
+const window_coep = variants.get('window_coep') == 'none'
+  ? coep_none
+  : coep_credentialless;
+const worker_coep = variants.get('worker_coep') == 'none'
+  ? coep_none
+  : coep_credentialless;
+const request_origin = variants.get('request_origin') == 'same-origin'
+  ? same_origin
+  : cross_origin;
+
+// When using COEP:credentialless: cross-origin no-cors request do not include
+// credentials. Note: This must not depend on the window's COEP policy.
+const worker_expected_cookie =
+  request_origin == same_origin
+  ? cookie_same_origin
+  : (worker_coep == coep_credentialless
+    ? undefined
+    : cookie_cross_origin);
+
+// From a JSON representing the `response` HTTP headers key-values, return the
+// cookie corresponding to the `cookie_key`.
+const get_cookie = (response) => {
+  const headers_credentialless = JSON.parse(response);
+  return parseCookies(headers_credentialless)[cookie_key];
+}
+
 promise_test(async test => {
+  // 0. Populate cookies for the two origins.
   await Promise.all([
     setCookie(same_origin, cookie_key, cookie_same_origin +
       cookie_same_site_none),
@@ -18,102 +62,32 @@
       cookie_same_site_none),
   ]);
 
-  // One window with COEP:none. (control)
-  const w_control_token = token();
-  const w_control_url = same_origin + executor_path +
-    coep_none + `&uuid=${w_control_token}`
-  const w_control = window.open(w_control_url);
-  add_completion_callback(() => w_control.close());
+  // 1. Create the popup with the `window_coep` COEP policy:
+  const popup = environments.document(window_coep)[0];
 
-  // One window with COEP:credentialless. (experiment)
-  const w_credentialless_token = token();
-  const w_credentialless_url = same_origin + executor_path +
-    coep_credentialless + `&uuid=${w_credentialless_token}`;
-  const w_credentialless = window.open(w_credentialless_url);
-  add_completion_callback(() => w_credentialless.close());
+  // 2. Create the worker with the `worker_coep` COEP policy:
+  const worker_token = token();
+  const worker_error = token();
+  const worker_src = same_origin + executor_worker_path + worker_coep +
+    `&uuid=${worker_token}`;
+  send(popup, `
+    let worker = new SharedWorker("${worker_src}", {});
+    worker.onerror = () => {
+      send("${worker_error}", "Worker blocked");
+    }
+  `);
 
-  let GetCookie = (response) => {
-    const headers_credentialless = JSON.parse(response);
-    return parseCookies(headers_credentialless)[cookie_key];
-  }
+  // 3. Request the resource from the worker, with the `request_origin` origin.
+  const request_token = token();
+  const request_url = showRequestHeaders(request_origin, request_token);
+  send(worker_token, `fetch("${request_url}", {
+    mode: 'no-cors',
+    credentials: 'include',
+  })`);
+  const request_cookie = await Promise.race([
+    receive(worker_error),
+    receive(request_token).then(get_cookie)
+  ]);
 
-  const sharedWorkerTest = function(
-    description, origin, coep_for_worker,
-    expected_cookies_control,
-    expected_cookies_credentialless)
-  {
-    promise_test_parallel(async t => {
-      // Create workers for both window.
-      const worker_token_1 = token();
-      const worker_token_2 = token();
-
-      // Used to check for errors creating the DedicatedWorker.
-      const worker_error_1 = token();
-      const worker_error_2 = token();
-
-      const w_worker_src_1 = same_origin + executor_worker_path +
-        coep_for_worker + `&uuid=${worker_token_1}`;
-      send(w_control_token, `
-        let worker = new SharedWorker("${w_worker_src_1}", {});
-        worker.onerror = () => {
-          send("${worker_error_1}", "Worker blocked");
-        }
-      `);
-
-      const w_worker_src_2 = same_origin + executor_worker_path +
-        coep_for_worker + `&uuid=${worker_token_2}`;
-      send(w_credentialless_token, `
-        let worker = new SharedWorker("${w_worker_src_2}", {});
-        worker.onerror = () => {
-          send("${worker_error_2}", "Worker blocked");
-        }
-      `);
-
-      // Fetch resources with the workers.
-      const request_token_1 = token();
-      const request_token_2 = token();
-      const request_url_1 = showRequestHeaders(origin, request_token_1);
-      const request_url_2 = showRequestHeaders(origin, request_token_2);
-      send(worker_token_1,
-        `fetch("${request_url_1}", {mode: 'no-cors', credentials: 'include'})`);
-      send(worker_token_2,
-        `fetch("${request_url_2}", {mode: 'no-cors', credentials: 'include'})`);
-
-      const response_control = await Promise.race([
-        receive(worker_error_1),
-        receive(request_token_1).then(GetCookie)
-      ]);
-      assert_equals(response_control,
-        expected_cookies_control,
-        "coep:none => ");
-
-      const response_credentialless = await Promise.race([
-        receive(worker_error_2),
-        receive(request_token_2).then(GetCookie)
-      ]);
-      assert_equals(response_credentialless,
-        expected_cookies_credentialless,
-        "coep:credentialless => ");
-    }, `fetch ${description}`)
-  };
-
-  sharedWorkerTest("same-origin",
-    same_origin, coep_none,
-    cookie_same_origin,
-    cookie_same_origin);
-
-  sharedWorkerTest("same-origin + credentialless worker",
-    same_origin, coep_credentialless,
-    cookie_same_origin,
-    cookie_same_origin);
-
-  sharedWorkerTest("cross-origin",
-    cross_origin, coep_none,
-    cookie_cross_origin,
-    cookie_cross_origin);
-
-  sharedWorkerTest("cross-origin + credentialless worker",
-    cross_origin, coep_credentialless,
-    undefined,
-    undefined);
+  assert_equals(request_cookie, worker_expected_cookie);
 })
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html.ini b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html.ini
index 734deff..234eb932 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html.ini
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html.ini
@@ -1,5 +1,6 @@
 [resource-selection-invoke-remove-src.html]
   [NOT invoking media load or resource selection when removing the src attribute]
     expected:
-      if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS]
       if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
+      if (product == "content_shell") and (os == "linux") and (flag_specific == ""): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-empty-crash.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-empty-crash.html
new file mode 100644
index 0000000..6e44250c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-empty-crash.html
@@ -0,0 +1,8 @@
+<script>
+document.addEventListener('DOMContentLoaded', () => {
+  a.type = "foo"
+  document.execCommand("insertHorizontalRule", false)
+  a.type = "text"
+})
+</script>
+<input id="a" type="color">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value-expected.txt
new file mode 100644
index 0000000..147bdb41
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+FAIL Without focus assert_equals: Value dirty flag should remain false expected "" but got "#000000"
+FAIL With focus assert_equals: Value dirty flag should remain false expected "" but got "#000000"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value.html
new file mode 100644
index 0000000..74aeef7c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Input type switch from / to color</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://html.spec.whatwg.org/#input-type-change">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1833477">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+function runTest(focus) {
+  let input = document.createElement("input");
+  input.type = "color";
+  document.body.appendChild(input);
+  if (focus) {
+    input.focus();
+  }
+  assert_equals(input.value, "#000000", "Invalid color should return a non-empty sanitized value");
+  input.type = "text";
+  assert_equals(input.value, "", "Value dirty flag should remain false");
+  input.type = "color";
+  input.value = "#ffffff";
+  assert_equals(input.value, "#ffffff", "Valid color is returned");
+  input.type = "text";
+  assert_equals(input.value, "#ffffff", "Value dirty flag should remain true");
+  if (focus) {
+    assert_equals(document.activeElement, input, "Focus is preserved");
+  }
+}
+test(() => runTest(false), "Without focus");
+test(() => runTest(true), "With focus");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value.html.ini b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value.html.ini
new file mode 100644
index 0000000..3043141
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/input-type-change-value.html.ini
@@ -0,0 +1,6 @@
+[input-type-change-value.html]
+  [With focus]
+    expected: FAIL
+
+  [Without focus]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popovers/popover-light-dismiss.html b/third_party/blink/web_tests/external/wpt/html/semantics/popovers/popover-light-dismiss.html
index 4b888169..59a12a2 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/popovers/popover-light-dismiss.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popovers/popover-light-dismiss.html
@@ -106,13 +106,14 @@
     popover1.showPopover();
     await waitForRender();
     assert_true(popover1.matches(':popover-open'));
-    const actions = new test_driver.Actions();
-    await actions.pointerMove(0, 0, {origin: outside})
-      .pointerDown({button: actions.ButtonType.LEFT})
+    await new test_driver.Actions()
+      .pointerMove(0, 0, {origin: outside})
+      .pointerDown()
       .send();
     await waitForRender();
     assert_true(popover1.matches(':popover-open'),'pointerdown (outside the popover) should not hide the popover');
-    await actions.pointerUp({button: actions.ButtonType.LEFT})
+    await new test_driver.Actions()
+      .pointerUp()
       .send();
     await waitForRender();
     assert_false(popover1.matches(':popover-open'),'pointerup (outside the popover) should trigger light dismiss');
diff --git a/third_party/blink/web_tests/external/wpt/images/README.md b/third_party/blink/web_tests/external/wpt/images/README.md
new file mode 100644
index 0000000..6491564
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/README.md
@@ -0,0 +1,18 @@
+Largest contentful paint test images
+====================================
+
+The images in this directory prefixed with `lcp-` are specifically intended to
+be used by tests where a largest-contentful-paint entry should be generated. As
+Chromium has implemented a contentfulness threshold of 0.05 bits per pixel,
+these images, when rendered at their natural dimensions, have a minimum content
+length, as shown in the table below:
+
+File            | Dimensions | Area (px^2) | Minimum content-length (bytes)
+----------------+------------+-------------|-------------------------------
+lcp-256x256.png | 256x256    | 65536       | 410
+lcp-133x106.png | 133x106    | 14098       | 89
+lcp-100x50.png  | 100x50     | 5000        | 32
+lcp-96x96.png   | 96x96      | 9216        | 58
+lcp-16x16.png   | 16x16      | 256         | 2
+lcp-2x2.png     | 2x2        | 4           | 1
+lcp-1x1.png     | 1x1        | 1           | 1
diff --git a/third_party/blink/web_tests/external/wpt/images/lcp-100x50-alt.png b/third_party/blink/web_tests/external/wpt/images/lcp-100x50-alt.png
new file mode 100644
index 0000000..2fdd47c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/lcp-100x50-alt.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/images/lcp-100x50.png b/third_party/blink/web_tests/external/wpt/images/lcp-100x50.png
new file mode 100644
index 0000000..0e47221
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/lcp-100x50.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/images/lcp-133x106.png b/third_party/blink/web_tests/external/wpt/images/lcp-133x106.png
new file mode 100644
index 0000000..fb61e8d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/lcp-133x106.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/images/lcp-16x16.png b/third_party/blink/web_tests/external/wpt/images/lcp-16x16.png
new file mode 100644
index 0000000..f8ca4fae
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/lcp-16x16.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/images/lcp-1x1.png b/third_party/blink/web_tests/external/wpt/images/lcp-1x1.png
new file mode 100644
index 0000000..82863b8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/lcp-1x1.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/images/lcp-256x256.png b/third_party/blink/web_tests/external/wpt/images/lcp-256x256.png
new file mode 100644
index 0000000..944f10f8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/lcp-256x256.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/images/lcp-2x2.png b/third_party/blink/web_tests/external/wpt/images/lcp-2x2.png
new file mode 100644
index 0000000..5b628e07
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/lcp-2x2.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/images/lcp-96x96.png b/third_party/blink/web_tests/external/wpt/images/lcp-96x96.png
new file mode 100644
index 0000000..66464b77
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/images/lcp-96x96.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/idlharness.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/idlharness.html
index 84d1c7f..5f5d286b 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/idlharness.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/idlharness.html
@@ -27,4 +27,4 @@
 );
 </script>
 <!-- a contentful element to observe -->
-<img src=/images/green-100x50.png>
+<img src=/images/lcp-100x50.png>
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-full-viewport.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-full-viewport.html
index e67e21a..2f8e17f 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-full-viewport.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-full-viewport.html
@@ -29,7 +29,7 @@
     ).observe({type: 'largest-contentful-paint', buffered: true});
     // Add an image, setting width and height equal to viewport.
     img = document.createElement('img');
-    img.src = '/images/green-100x50.png';
+    img.src = '/images/lcp-100x50.png';
     img.id = 'image_id';
     img.width = viewportWidth * 2;
     img.height = viewportHeight * 2;
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-not-fully-visible.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-not-fully-visible.html
index 1aee495..514a424f 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-not-fully-visible.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-not-fully-visible.html
@@ -27,7 +27,7 @@
       t.step_func_done(function(entryList) {
         assert_equals(entryList.getEntries().length, 1);
         const entry = entryList.getEntries()[0];
-        const url = window.location.origin + '/images/green-100x50.png';
+        const url = window.location.origin + '/images/lcp-100x50.png';
         // To compute the size, compute the percentage of the image visible and
         // scale by its natural dimensions. In this test, the image is expanded to twice its size
         // but place towards the bottom right corner of the viewport, so it is
@@ -42,7 +42,7 @@
     ).observe({type: 'largest-contentful-paint', buffered: true});
     // Add an image, setting width and height equal to viewport.
     img = document.createElement('img');
-    img.src = '/images/green-100x50.png';
+    img.src = '/images/lcp-100x50.png';
     img.id = 'image_id';
     img.width = imgWidth * 2;
     img.height = imgHeight * 2;
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-removed-before-load.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-removed-before-load.html
index 3e557a4..08e5ee56 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-removed-before-load.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/image-removed-before-load.html
@@ -11,7 +11,7 @@
   setup({"hide_test_state": true});
   const numInitial = 100;
   const sleep = 1000;
-  const small_img_src = '/images/green-16x16.png';
+  const small_img_src = '/images/lcp-16x16.png';
   let beforeLoad;
   async_test(function (t) {
     assert_implements(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented");
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/initially-invisible-images.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/initially-invisible-images.html
index b4d68a5c..061a0140 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/initially-invisible-images.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/initially-invisible-images.html
@@ -16,10 +16,10 @@
 <body>
 <div>
 <div class='flex-container' id="container">
-  <img src='/images/yellow.png?pipe=trickle(d1)' width="1000" height="1000"/>
-  <img src='/images/green-1x1.png?1' width="1000" height="1000"/>
-  <img src='/images/green-1x1.png?2' width="1000" height="1000"/>
-  <img src='/images/green-1x1.png?3' width="1000" height="1000"/>
+  <img src='/images/lcp-100x50.png?pipe=trickle(d1)' width="1000" height="1000"/>
+  <img src='/images/lcp-1x1.png?1' width="1000" height="1000"/>
+  <img src='/images/lcp-1x1.png?2' width="1000" height="1000"/>
+  <img src='/images/lcp-1x1.png?3' width="1000" height="1000"/>
 </div>
 </div>
 <script>
@@ -48,7 +48,7 @@
         if (!entry.url) {
           return;
         }
-        assert_true(entry.url.includes("yellow.png"), "Re-visible image has an entry");
+        assert_true(entry.url.includes("lcp-100x50.png"), "Re-visible image has an entry");
         resolve();
       });
     });
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/larger-image.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/larger-image.html
index 948f00d..9415cbc 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/larger-image.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/larger-image.html
@@ -6,11 +6,11 @@
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
   <script src="resources/largest-contentful-paint-helpers.js"></script>
-  <!-- There is some text and some images. We care about blue.png being reported, as it is the largest. -->
+  <!-- There is some text and some images. We care about lcp-133x106.png being reported, as it is the largest. -->
   <p>This is some text! :)</p>
-  <img src='' id='red' />
-  <img src='' id='blue' />
-  <img src='' id='black' />
+  <img src='' id='lcp1' />
+  <img src='' id='lcp2' />
+  <img src='' id='lcp3' />
   <p>More text!</p>
   <script>
     // Add listener for load event that is fired when image is loaded.
@@ -23,31 +23,30 @@
     promise_test(async (t) => {
       assert_implements(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented");
 
-      let promise = image_load_promise(document.getElementById('red'));
-      document.getElementById('red').src = '/images/red.png';
+      let promise = image_load_promise(document.getElementById('lcp1'));
+      document.getElementById('lcp1').src = '/images/lcp-100x50.png';
       await promise;
 
       const beforeLoad = performance.now();
 
-      promise = image_load_promise(document.getElementById('blue'));
-      document.getElementById('blue').src = '/images/blue.png';
+      promise = image_load_promise(document.getElementById('lcp2'));
+      document.getElementById('lcp2').src = '/images/lcp-133x106.png';
       await promise;
 
-      promise = image_load_promise(document.getElementById('black'));
-      document.getElementById('black').src = '/images/black-rectangle.png';
+      promise = image_load_promise(document.getElementById('lcp3'));
+      document.getElementById('lcp3').src = '/images/lcp-100x50-alt.png';
       await promise;
 
       const observer = new PerformanceObserver(
         t.step_func(entryList => {
           entryList.getEntries().forEach(entry => {
-            // The text or other image could be reported as LCP if it is rendered before the blue image.
-            if (entry.id !== 'blue')
+            // The text or other image could be reported as LCP if it is rendered before the larger image.
+            if (entry.id !== 'lcp2')
               return;
 
-            const url = window.location.origin + '/images/blue.png';
-            // blue.png is 133 by 106.
+            const url = window.location.origin + '/images/lcp-133x106.png';
             const size = 133 * 106;
-            checkImage(entry, url, 'blue', size, beforeLoad);
+            checkImage(entry, url, 'lcp2', size, beforeLoad);
             t.done();
           })
         })
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/larger-text.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/larger-text.html
index 8758c1c..c577899 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/larger-text.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/larger-text.html
@@ -14,10 +14,10 @@
 
   </style>
   <!-- These are some text and some tiny images. We care about the largest text. -->
-  <img id='green1' />
+  <img id='image1' />
   <div id='text1'></div>
   <div id='text2'></div>
-  <img id='green2' />
+  <img id='image2' />
   <script>
     const load_image = async (id, url) => {
       await new Promise(resolve => {
@@ -37,13 +37,13 @@
       let beforeRender = performance.now();
 
       // Load images and add texts.
-      await load_image('green1', '/images/green-1x1.png');
+      await load_image('image1', '/images/lcp-1x1.png');
 
       load_text('text1', 'This is some text.');
 
       load_text('text2', 'This is more text so it will be the Largest Contentful Paint!');
 
-      await load_image('green2', '/images/green-2x2.png');
+      await load_image('image2', '/images/lcp-2x2.png');
 
       await new Promise(resolve => {
         new PerformanceObserver(
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/mouseover-heuristics-background.tentative.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/mouseover-heuristics-background.tentative.html
index 16cbd0f0..ddd4f96 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/mouseover-heuristics-background.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/mouseover-heuristics-background.tentative.html
@@ -10,7 +10,7 @@
   <script src="resources/mouseover-utils.js"></script>
 </head>
 <body>
-  <img src="/images/green-16x16.png" id=image>
+  <img src="/images/lcp-16x16.png" id=image>
   <span id=span style="display: inline-block;width: 15px; height: 15px"></span>
   <script>
     run_mouseover_test(/*background=*/true);
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/mouseover-heuristics-element.tentative.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/mouseover-heuristics-element.tentative.html
index bbd8723..afc4b2a 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/mouseover-heuristics-element.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/mouseover-heuristics-element.tentative.html
@@ -10,7 +10,7 @@
   <script src="resources/mouseover-utils.js"></script>
 </head>
 <body>
-  <img src="/images/green-16x16.png" id=image>
+  <img src="/images/lcp-16x16.png" id=image>
   <span id=span style="display: inline-block;width: 15px; height: 15px"></span>
   <script>
     run_mouseover_test(/*background=*/false);
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/non-tao-image-subsequent-lcp-candidate.tentative.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/non-tao-image-subsequent-lcp-candidate.tentative.html
index 50f9a229..4d799c1 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/non-tao-image-subsequent-lcp-candidate.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/non-tao-image-subsequent-lcp-candidate.tentative.html
@@ -10,8 +10,8 @@
 <body>
   <script>
     promise_test(async t => {
-      let small_image_path = '/images/green-100x50.png';
-      let big_image_path = '/images/green-256x256.png';
+      let small_image_path = '/images/lcp-100x50.png';
+      let big_image_path = '/images/lcp-256x256.png';
       let non_tao_scheme = get_host_info().OTHER_ORIGIN;
 
       // Load non-tao image with 0 opacity so it won't trigger an LCP entry.
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/placeholder-image.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/placeholder-image.html
index 6a2ce5c..06691cef 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/placeholder-image.html
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/placeholder-image.html
@@ -5,13 +5,13 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="resources/largest-contentful-paint-helpers.js"></script>
-<img src='/images/green-1x1.png' id='image_id' width="133" height="106"/>
+<img src='/images/lcp-1x1.png' id='image_id' width="133" height="106"/>
 <script>
   async_test(function (t) {
     assert_implements(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented");
     let beforeLoad = performance.now();
-    document.getElementById('image_id').src = '/images/blue.png';
-    const url = window.location.origin + '/images/blue.png';
+    document.getElementById('image_id').src = '/images/lcp-133x106.png';
+    const url = window.location.origin + '/images/lcp-133x106.png';
     const observer = new PerformanceObserver(
       t.step_func(function(entryList) {
         let entries = entryList.getEntries().filter(e => e.url === url);
@@ -19,7 +19,6 @@
           return;
         assert_equals(entries.length, 1);
         const entry = entries[0];
-        // blue.png is 133 by 106.
         const size = 133 * 106;
         checkImage(entry, url, 'image_id', size, beforeLoad);
         t.done();
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/mouseover-utils.js b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/mouseover-utils.js
index 1836f2e..60a29ed0 100644
--- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/mouseover-utils.js
+++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/mouseover-utils.js
@@ -7,7 +7,7 @@
     } else {
       zoom = new Image();
     }
-    zoom.src=`/images/green-${size}.png`;
+    zoom.src=`/images/lcp-${size}.png`;
     ++counter;
     zoom.elementTiming = "zoom" + counter;
     document.body.appendChild(zoom);
@@ -19,7 +19,7 @@
     const [width, height] = size.split("x");
     ++counter;
     div.style = `background-image:
-      url(/images/green-${size}.png?${counter}); width: ${width}px; height: ${height}px`;
+      url(/images/lcp-${size}.png?${counter}); width: ${width}px; height: ${height}px`;
     div.elementTiming = "zoom" + counter;
     document.body.appendChild(div);
   }
diff --git a/third_party/blink/web_tests/external/wpt/lint.ignore b/third_party/blink/web_tests/external/wpt/lint.ignore
index 1672f3b..4e52e32 100644
--- a/third_party/blink/web_tests/external/wpt/lint.ignore
+++ b/third_party/blink/web_tests/external/wpt/lint.ignore
@@ -659,8 +659,8 @@
 # Adding the testharnessreport.js script causes the test to never complete.
 MISSING-TESTHARNESSREPORT: accessibility/crashtests/computed-node-checked.html
 
-PRINT STATEMENT: webdriver/tests/print/*
 PRINT STATEMENT: webdriver/tests/bidi/browsing_context/print/*
+PRINT STATEMENT: webdriver/tests/classic/print/*
 PRINT STATEMENT: webdriver/tests/support/fixtures_bidi.py
 
 DUPLICATE-BASENAME-PATH: acid/acid3/empty.html
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play-terminate-worker.html.ini b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play-terminate-worker.html.ini
index 2c24a1f5..391c16b5 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play-terminate-worker.html.ini
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play-terminate-worker.html.ini
@@ -1,16 +1,21 @@
 [mediasource-worker-play-terminate-worker.html]
   [Test worker MediaSource termination after at least 5 main thread setTimeouts, starting counting before setting srcObject]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
-      if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
+      if (product == "content_shell") and (os == "win") and (port == "win11"): [PASS, FAIL]
+      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
       if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
       if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
+
+  [Test worker MediaSource termination after at least 6 main thread setTimeouts, starting counting before setting srcObject]
+    expected:
+      if (product == "content_shell") and (os == "win") and (port == "win11"): [PASS, FAIL]
 
   [Test worker MediaSource termination after at least 8 main thread setTimeouts, starting counting before setting srcObject]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
+      if (product == "content_shell") and (os == "win") and (port == "win11"): [PASS, FAIL]
 
   [Test worker MediaSource termination after at least 9 main thread setTimeouts, starting counting before setting srcObject]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
+      if (product == "content_shell") and (os == "win") and (port == "win11"): [PASS, FAIL]
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/compat/pointerevent_mouse-on-object.html b/third_party/blink/web_tests/external/wpt/pointerevents/compat/pointerevent_mouse-on-object.html
index 78edfbd..27142a4 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/compat/pointerevent_mouse-on-object.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/compat/pointerevent_mouse-on-object.html
@@ -62,6 +62,12 @@
   });
 });
 
+// Simple test to check that passive listeners can't prevent compatibility events.
+target.addEventListener("pointerdown", function(event) {
+    event.preventDefault();
+  },
+  { passive: true, once: true });
+
 document.getElementById('done').addEventListener('click', (e) => done_clicked++);
 
 // Need to prevent the default behaviour for firefox
diff --git a/third_party/blink/web_tests/external/wpt/preload/modulepreload-as.html.ini b/third_party/blink/web_tests/external/wpt/preload/modulepreload-as.html.ini
index 134da6c8..6657ded 100644
--- a/third_party/blink/web_tests/external/wpt/preload/modulepreload-as.html.ini
+++ b/third_party/blink/web_tests/external/wpt/preload/modulepreload-as.html.ini
@@ -1,113 +1,105 @@
 [modulepreload-as.html]
   expected:
-    if (product == "content_shell") and (os == "win") and (port == "win11"): TIMEOUT
     if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [ERROR, TIMEOUT]
-    if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [ERROR, TIMEOUT, OK]
-    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [ERROR, OK]
-    if (product == "content_shell") and (os == "mac") and (port == "mac11"): OK
+    if (product == "content_shell") and (os == "win") and (port == "win11"): TIMEOUT
     if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): OK
-    if (product == "content_shell") and (os == "mac") and (port == "mac12"): OK
+    if (product == "content_shell") and (os == "mac") and (port == "mac11"): OK
     ERROR
   [Modulepreload with as="audio"]
-    expected: FAIL
+    expected:
+      if product == "chrome": NOTRUN
+      FAIL
 
   [Modulepreload with as="audioworklet"]
     expected: FAIL
 
   [Modulepreload with as="document"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
+      if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS]
+      if product == "chrome": NOTRUN
       FAIL
 
   [Modulepreload with as="embed"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
       if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS]
       if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [FAIL, PASS]
+      if product == "chrome": NOTRUN
       FAIL
 
   [Modulepreload with as="fetch"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
-      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
-      if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
-      if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
+      if (product == "content_shell") and (os == "win") and (port == "win11"): PASS
+      if (product == "content_shell") and (os == "linux"): PASS
+      if product == "chrome": NOTRUN
+      FAIL
 
   [Modulepreload with as="font"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
       if (product == "content_shell") and (os == "win") and (port == "win11"): PASS
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [FAIL, PASS]
       if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
-      if product == "chrome": PASS
+      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [FAIL, PASS]
+      if product == "chrome": NOTRUN
       FAIL
 
   [Modulepreload with as="frame"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "win") and (port == "win11"): PASS
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
       if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
-      if product == "chrome": PASS
-      FAIL
+      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
+      if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
+      if product == "chrome": NOTRUN
 
   [Modulepreload with as="iMaGe"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
-      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
       if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
       if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
+      if product == "chrome": NOTRUN
 
   [Modulepreload with as="iframe"]
     expected:
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "win"): PASS
-      if product == "chrome": PASS
-      FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
+      if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS]
 
   [Modulepreload with as="image"]
     expected:
       if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
       if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "win"): PASS
-      if product == "chrome": PASS
-      FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
 
   [Modulepreload with as="invalid-dest"]
     expected: FAIL
 
   [Modulepreload with as="manifest"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "linux") and (flag_specific == ""): PASS
-      if (product == "content_shell") and (os == "win"): PASS
-      if product == "chrome": PASS
-      FAIL
-
-  [Modulepreload with as="object"]
-    expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
+      if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
       if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
       if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
       if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
+      if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
+      if product == "chrome": NOTRUN
+
+  [Modulepreload with as="object"]
+    expected:
+      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
+      if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
 
   [Modulepreload with as="paintworklet"]
     expected: FAIL
 
   [Modulepreload with as="report"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
-      if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
       if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
+      if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL
 
   [Modulepreload with as="serviceworker"]
     expected: FAIL
@@ -117,36 +109,30 @@
 
   [Modulepreload with as="style"]
     expected:
+      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
       if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [FAIL, PASS]
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
-      if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): PASS
+      if product == "chrome": NOTRUN
       FAIL
 
   [Modulepreload with as="track"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
-      if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): PASS
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
       if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
+      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
+      if product == "chrome": NOTRUN
       FAIL
 
   [Modulepreload with as="video"]
     expected:
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
       if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
-      if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): PASS
-      if product == "chrome": PASS
+      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
+      if product == "chrome": NOTRUN
       FAIL
 
   [Modulepreload with as="webidentity"]
     expected:
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
       if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL]
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
-      if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): PASS
-      if product == "chrome": PASS
+      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
+      if product == "chrome": NOTRUN
       FAIL
 
   [Modulepreload with as="worker"]
@@ -154,9 +140,6 @@
 
   [Modulepreload with as="xslt"]
     expected:
-      if (product == "content_shell") and (os == "linux") and (flag_specific == ""): PASS
-      if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [PASS, FAIL]
-      if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): [FAIL, PASS]
-      if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): PASS
-      if product == "chrome": PASS
+      if (product == "content_shell") and (os == "linux"): PASS
+      if product == "chrome": NOTRUN
       FAIL
diff --git a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-image-softnav-lcp.tentative.html b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-image-softnav-lcp.tentative.html
index 27e9bbbd..7a2018d 100644
--- a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-image-softnav-lcp.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-image-softnav-lcp.tentative.html
@@ -12,7 +12,7 @@
 <body>
   <main id=main>
     <div>
-      <a id=link><img src="/images/ggrr-256x256.png"></a>
+      <a id=link><img src="/images/lcp-256x256.png"></a>
     </div>
   </main>
   <script>
diff --git a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-text-softnav-lcp.tentative.html b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-text-softnav-lcp.tentative.html
index 5aa1b1d..501d1c5f 100644
--- a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-text-softnav-lcp.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-text-softnav-lcp.tentative.html
@@ -12,7 +12,7 @@
 <body>
   <main id=main>
     <div>
-      <a id=link><img src="/images/ggrr-256x256.png"></a>
+      <a id=link><img src="/images/lcp-256x256.png"></a>
     </div>
   </main>
   <script>
diff --git a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-two-image-softnavs-lcp.tentative.html b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-two-image-softnavs-lcp.tentative.html
index 7f5bafb..1489ae1 100644
--- a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-two-image-softnavs-lcp.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/image-lcp-followed-by-two-image-softnavs-lcp.tentative.html
@@ -12,7 +12,7 @@
 <body>
   <main id=main>
     <div>
-      <a id=link><img src="/images/ggrr-256x256.png"></a>
+      <a id=link><img src="/images/lcp-256x256.png"></a>
     </div>
   </main>
   <script>
diff --git a/third_party/blink/web_tests/external/wpt/url/a-element-origin-xhtml.xhtml.ini b/third_party/blink/web_tests/external/wpt/url/a-element-origin-xhtml.xhtml.ini
index a84d07fe..3661cc2 100644
--- a/third_party/blink/web_tests/external/wpt/url/a-element-origin-xhtml.xhtml.ini
+++ b/third_party/blink/web_tests/external/wpt/url/a-element-origin-xhtml.xhtml.ini
@@ -7,6 +7,18 @@
     expected:
       if (product == "content_shell") and (os == "win"): FAIL
 
+  [Parsing origin: <blob:file://host/path> against <about:blank>]
+    expected: FAIL
+
+  [Parsing origin: <blob:ftp://host/path> against <about:blank>]
+    expected: FAIL
+
+  [Parsing origin: <blob:ws://example.org/> against <about:blank>]
+    expected: FAIL
+
+  [Parsing origin: <blob:wss://example.org/> against <about:blank>]
+    expected: FAIL
+
   [Parsing origin: <c:/foo> against <http://example.org/foo/bar>]
     expected:
       if (product == "content_shell") and (os == "win"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/url/a-element-origin.html.ini b/third_party/blink/web_tests/external/wpt/url/a-element-origin.html.ini
index e0447aa..845c5c5 100644
--- a/third_party/blink/web_tests/external/wpt/url/a-element-origin.html.ini
+++ b/third_party/blink/web_tests/external/wpt/url/a-element-origin.html.ini
@@ -7,6 +7,18 @@
     expected:
       if (product == "content_shell") and (os == "win"): FAIL
 
+  [Parsing origin: <blob:file://host/path> against <about:blank>]
+    expected: FAIL
+
+  [Parsing origin: <blob:ftp://host/path> against <about:blank>]
+    expected: FAIL
+
+  [Parsing origin: <blob:ws://example.org/> against <about:blank>]
+    expected: FAIL
+
+  [Parsing origin: <blob:wss://example.org/> against <about:blank>]
+    expected: FAIL
+
   [Parsing origin: <c:/foo> against <http://example.org/foo/bar>]
     expected:
       if (product == "content_shell") and (os == "win"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/url/resources/urltestdata.json b/third_party/blink/web_tests/external/wpt/url/resources/urltestdata.json
index 58f6b87..680d2b9 100644
--- a/third_party/blink/web_tests/external/wpt/url/resources/urltestdata.json
+++ b/third_party/blink/web_tests/external/wpt/url/resources/urltestdata.json
@@ -7785,6 +7785,113 @@
     "search": "",
     "hash": ""
   },
+  "blob: in blob:",
+  {
+    "input": "blob:blob:",
+    "base": null,
+    "href": "blob:blob:",
+    "origin": "null",
+    "protocol": "blob:",
+    "username": "",
+    "password": "",
+    "host": "",
+    "hostname": "",
+    "port": "",
+    "pathname": "blob:",
+    "search": "",
+    "hash": ""
+  },
+  {
+    "input": "blob:blob:https://example.org/",
+    "base": null,
+    "href": "blob:blob:https://example.org/",
+    "origin": "null",
+    "protocol": "blob:",
+    "username": "",
+    "password": "",
+    "host": "",
+    "hostname": "",
+    "port": "",
+    "pathname": "blob:https://example.org/",
+    "search": "",
+    "hash": ""
+  },
+  "Non-http(s): in blob:",
+  {
+    "input": "blob:about:blank",
+    "base": null,
+    "href": "blob:about:blank",
+    "origin": "null",
+    "protocol": "blob:",
+    "username": "",
+    "password": "",
+    "host": "",
+    "hostname": "",
+    "port": "",
+    "pathname": "about:blank",
+    "search": "",
+    "hash": ""
+  },
+  {
+    "input": "blob:file://host/path",
+    "base": null,
+    "href": "blob:file://host/path",
+    "origin": "null",
+    "protocol": "blob:",
+    "username": "",
+    "password": "",
+    "host": "",
+    "hostname": "",
+    "port": "",
+    "pathname": "file://host/path",
+    "search": "",
+    "hash": ""
+  },
+  {
+    "input": "blob:ftp://host/path",
+    "base": null,
+    "href": "blob:ftp://host/path",
+    "origin": "null",
+    "protocol": "blob:",
+    "username": "",
+    "password": "",
+    "host": "",
+    "hostname": "",
+    "port": "",
+    "pathname": "ftp://host/path",
+    "search": "",
+    "hash": ""
+  },
+  {
+    "input": "blob:ws://example.org/",
+    "base": null,
+    "href": "blob:ws://example.org/",
+    "origin": "null",
+    "protocol": "blob:",
+    "username": "",
+    "password": "",
+    "host": "",
+    "hostname": "",
+    "port": "",
+    "pathname": "ws://example.org/",
+    "search": "",
+    "hash": ""
+  },
+  {
+    "input": "blob:wss://example.org/",
+    "base": null,
+    "href": "blob:wss://example.org/",
+    "origin": "null",
+    "protocol": "blob:",
+    "username": "",
+    "password": "",
+    "host": "",
+    "hostname": "",
+    "port": "",
+    "pathname": "wss://example.org/",
+    "search": "",
+    "hash": ""
+  },
   "Invalid IPv4 radix digits",
   {
     "input": "http://0x7f.0.0.0x7g",
diff --git a/third_party/blink/web_tests/external/wpt/url/url-origin.any.js.ini b/third_party/blink/web_tests/external/wpt/url/url-origin.any.js.ini
index 837c7c2..ed88ccc 100644
--- a/third_party/blink/web_tests/external/wpt/url/url-origin.any.js.ini
+++ b/third_party/blink/web_tests/external/wpt/url/url-origin.any.js.ini
@@ -13,6 +13,18 @@
     expected:
       if (product == "content_shell") and (os == "win"): FAIL
 
+  [Origin parsing: <blob:file://host/path> without base]
+    expected: FAIL
+
+  [Origin parsing: <blob:ftp://host/path> without base]
+    expected: FAIL
+
+  [Origin parsing: <blob:ws://example.org/> without base]
+    expected: FAIL
+
+  [Origin parsing: <blob:wss://example.org/> without base]
+    expected: FAIL
+
   [Origin parsing: <c:/foo> against <http://example.org/foo/bar>]
     expected:
       if (product == "content_shell") and (os == "win"): FAIL
@@ -52,6 +64,18 @@
     expected:
       if (product == "content_shell") and (os == "win"): FAIL
 
+  [Origin parsing: <blob:file://host/path> without base]
+    expected: FAIL
+
+  [Origin parsing: <blob:ftp://host/path> without base]
+    expected: FAIL
+
+  [Origin parsing: <blob:ws://example.org/> without base]
+    expected: FAIL
+
+  [Origin parsing: <blob:wss://example.org/> without base]
+    expected: FAIL
+
   [Origin parsing: <c:/foo> against <http://example.org/foo/bar>]
     expected:
       if (product == "content_shell") and (os == "win"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/OWNERS b/third_party/blink/web_tests/external/wpt/webaudio/OWNERS
index a7db251..32f919a5 100644
--- a/third_party/blink/web_tests/external/wpt/webaudio/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/webaudio/OWNERS
@@ -1,3 +1,4 @@
 hongchan@chromium.org
 mjwilson@chromium.org
-alvinji@chromium.org
\ No newline at end of file
+alvinji@chromium.org
+sinafirooz@chromium.org
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/accept_alert/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/accept_alert/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/accept_alert/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/accept_alert/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/accept_alert/accept.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/accept_alert/accept.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/accept_alert/accept.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/accept_alert/accept.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/add_cookie/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/add_cookie/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/add_cookie/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/add_cookie/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/add_cookie/add.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/add_cookie/add.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/add_cookie/add.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/add_cookie/add.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/add_cookie/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/add_cookie/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/add_cookie/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/add_cookie/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/back/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/back/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/back/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/back/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/back/back.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/back/back.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/back/back.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/back/back.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/back/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/back/conftest.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/back/conftest.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/back/conftest.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/back/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/back/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/back/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/back/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/close_window/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/close_window/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/close.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/close_window/close.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/close.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/close_window/close.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/close_window/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/close_window/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/delete_all_cookies/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_all_cookies/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/delete_all_cookies/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_all_cookies/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/delete_all_cookies/delete.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_all_cookies/delete.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/delete_all_cookies/delete.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_all_cookies/delete.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/delete_all_cookies/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_all_cookies/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/delete_all_cookies/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_all_cookies/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/delete_cookie/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_cookie/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/delete_cookie/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_cookie/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/delete_cookie/delete.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_cookie/delete.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/delete_cookie/delete.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_cookie/delete.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/delete_cookie/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_cookie/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/delete_cookie/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_cookie/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/delete_session/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_session/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/delete_session/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_session/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/delete_session/delete.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_session/delete.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/delete_session/delete.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/delete_session/delete.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/dismiss_alert/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/dismiss_alert/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/dismiss_alert/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/dismiss_alert/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/dismiss_alert/dismiss.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/dismiss_alert/dismiss.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/dismiss_alert/dismiss.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/dismiss_alert/dismiss.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_clear/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_clear/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_clear/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_clear/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_clear/clear.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_clear/clear.py
new file mode 100644
index 0000000..9b0d7f2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_clear/clear.py
@@ -0,0 +1,454 @@
+# META: timeout=long
+
+import pytest
+from webdriver import Element
+
+from tests.support.asserts import (
+    assert_element_has_focus,
+    assert_error,
+    assert_events_equal,
+    assert_in_events,
+    assert_success,
+)
+
+
+@pytest.fixture
+def tracked_events():
+    return [
+        "blur",
+        "change",
+        "focus",
+    ]
+
+
+def element_clear(session, element):
+    return session.transport.send(
+        "POST", "/session/{session_id}/element/{element_id}/clear".format(
+            session_id=session.session_id,
+            element_id=element.id))
+
+
+@pytest.fixture(scope="session")
+def text_file(tmpdir_factory):
+    fh = tmpdir_factory.mktemp("tmp").join("hello.txt")
+    fh.write("hello")
+    return fh
+
+
+def test_null_response_value(session, inline):
+    session.url = inline("<input>")
+    element = session.find.css("input", all=False)
+
+    response = element_clear(session, element)
+    value = assert_success(response)
+    assert value is None
+
+
+def test_no_top_browsing_context(session, closed_window):
+    element = Element(session, "foo")
+    response = element_clear(session, element)
+    assert_error(response, "no such window")
+
+    original_handle, element = closed_window
+    response = element_clear(session, element)
+    assert_error(response, "no such window")
+
+    session.window_handle = original_handle
+    response = element_clear(session, element)
+    assert_error(response, "no such element")
+
+
+def test_no_browsing_context(session, closed_frame):
+    element = Element(session, "foo")
+
+    response = element_clear(session, element)
+    assert_error(response, "no such window")
+
+
+def test_no_such_element_with_invalid_value(session):
+    element = Element(session, "foo")
+
+    response = element_clear(session, element)
+    assert_error(response, "no such element")
+
+
+def test_no_such_element_with_shadow_root(session, get_test_page):
+    session.url = get_test_page()
+
+    element = session.find.css("custom-element", all=False)
+
+    result = element_clear(session, element.shadow_root)
+    assert_error(result, "no such element")
+
+
+@pytest.mark.parametrize("closed", [False, True], ids=["open", "closed"])
+def test_no_such_element_from_other_window_handle(session, inline, closed):
+    session.url = inline("<div id='parent'><p/>")
+    element = session.find.css("#parent", all=False)
+
+    new_handle = session.new_window()
+
+    if closed:
+        session.window.close()
+
+    session.window_handle = new_handle
+
+    response = element_clear(session, element)
+    assert_error(response, "no such element")
+
+
+@pytest.mark.parametrize("closed", [False, True], ids=["open", "closed"])
+def test_no_such_element_from_other_frame(session, get_test_page, closed):
+    session.url = get_test_page(as_frame=True)
+
+    frame = session.find.css("iframe", all=False)
+    session.switch_frame(frame)
+
+    element = session.find.css("div", all=False)
+
+    session.switch_frame("parent")
+
+    if closed:
+        session.execute_script("arguments[0].remove();", args=[frame])
+
+    response = element_clear(session, element)
+    assert_error(response, "no such element")
+
+
+@pytest.mark.parametrize("as_frame", [False, True], ids=["top_context", "child_context"])
+def test_stale_element_reference(session, stale_element, as_frame):
+    element = stale_element("input#text", as_frame=as_frame)
+
+    response = element_clear(session, element)
+    assert_error(response, "stale element reference")
+
+
+def test_pointer_interactable(session, inline):
+    session.url = inline("<input style='margin-left: -1000px' value=foobar>")
+    element = session.find.css("input", all=False)
+
+    response = element_clear(session, element)
+    assert_error(response, "element not interactable")
+
+
+def test_keyboard_interactable(session, inline):
+    session.url = inline("""
+        <input value=foobar>
+        <div></div>
+
+        <style>
+        div {
+          position: absolute;
+          background: blue;
+          top: 0;
+        }
+        </style>
+        """)
+    element = session.find.css("input", all=False)
+    assert element.property("value") == "foobar"
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("value") == ""
+
+
+@pytest.mark.parametrize("type,value,default",
+                         [("number", "42", ""),
+                          ("range", "42", "50"),
+                          ("email", "foo@example.com", ""),
+                          ("password", "password", ""),
+                          ("search", "search", ""),
+                          ("tel", "999", ""),
+                          ("text", "text", ""),
+                          ("url", "https://example.com/", ""),
+                          ("color", "#ff0000", "#000000"),
+                          ("date", "2017-12-26", ""),
+                          ("datetime", "2017-12-26T19:48", ""),
+                          ("datetime-local", "2017-12-26T19:48", ""),
+                          ("time", "19:48", ""),
+                          ("month", "2017-11", ""),
+                          ("week", "2017-W52", "")])
+def test_input(session, inline, add_event_listeners, tracked_events, type, value, default):
+    session.url = inline("<input type=%s value='%s'>" % (type, value))
+    element = session.find.css("input", all=False)
+    add_event_listeners(element, tracked_events)
+    assert element.property("value") == value
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("value") == default
+    assert_in_events(session, ["focus", "change", "blur"])
+    assert_element_has_focus(session.execute_script("return document.body"))
+
+
+@pytest.mark.parametrize("type",
+                         ["number",
+                          "range",
+                          "email",
+                          "password",
+                          "search",
+                          "tel",
+                          "text",
+                          "url",
+                          "color",
+                          "date",
+                          "datetime",
+                          "datetime-local",
+                          "time",
+                          "month",
+                          "week",
+                          "file"])
+def test_input_disabled(session, inline, type):
+    session.url = inline("<input type=%s disabled>" % type)
+    element = session.find.css("input", all=False)
+
+    response = element_clear(session, element)
+    assert_error(response, "invalid element state")
+
+
+@pytest.mark.parametrize("type",
+                         ["number",
+                          "range",
+                          "email",
+                          "password",
+                          "search",
+                          "tel",
+                          "text",
+                          "url",
+                          "color",
+                          "date",
+                          "datetime",
+                          "datetime-local",
+                          "time",
+                          "month",
+                          "week",
+                          "file"])
+def test_input_readonly(session, inline, type):
+    session.url = inline("<input type=%s readonly>" % type)
+    element = session.find.css("input", all=False)
+
+    response = element_clear(session, element)
+    assert_error(response, "invalid element state")
+
+
+def test_textarea(session, inline, add_event_listeners, tracked_events):
+    session.url = inline("<textarea>foobar</textarea>")
+    element = session.find.css("textarea", all=False)
+    add_event_listeners(element, tracked_events)
+    assert element.property("value") == "foobar"
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("value") == ""
+    assert_in_events(session, ["focus", "change", "blur"])
+
+
+def test_textarea_disabled(session, inline):
+    session.url = inline("<textarea disabled></textarea>")
+    element = session.find.css("textarea", all=False)
+
+    response = element_clear(session, element)
+    assert_error(response, "invalid element state")
+
+
+def test_textarea_readonly(session, inline):
+    session.url = inline("<textarea readonly></textarea>")
+    element = session.find.css("textarea", all=False)
+
+    response = element_clear(session, element)
+    assert_error(response, "invalid element state")
+
+
+def test_input_file(session, text_file, inline):
+    session.url = inline("<input type=file>")
+    element = session.find.css("input", all=False)
+    element.send_keys(str(text_file))
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("value") == ""
+
+
+def test_input_file_multiple(session, text_file, inline):
+    session.url = inline("<input type=file multiple>")
+    element = session.find.css("input", all=False)
+    element.send_keys(str(text_file))
+    element.send_keys(str(text_file))
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("value") == ""
+
+
+def test_select(session, inline):
+    session.url = inline("""
+        <select>
+          <option>foo
+        </select>
+        """)
+    select = session.find.css("select", all=False)
+    option = session.find.css("option", all=False)
+
+    response = element_clear(session, select)
+    assert_error(response, "invalid element state")
+    response = element_clear(session, option)
+    assert_error(response, "invalid element state")
+
+
+def test_button(session, inline):
+    session.url = inline("<button></button>")
+    button = session.find.css("button", all=False)
+
+    response = element_clear(session, button)
+    assert_error(response, "invalid element state")
+
+
+def test_button_with_subtree(session, inline):
+    """
+    Elements inside button elements are interactable.
+    """
+    session.url = inline("""
+        <button>
+          <input value=foobar>
+        </button>
+        """)
+    text_field = session.find.css("input", all=False)
+
+    response = element_clear(session, text_field)
+    assert_success(response)
+
+
+def test_contenteditable(session, inline, add_event_listeners, tracked_events):
+    session.url = inline("<p contenteditable>foobar</p>")
+    element = session.find.css("p", all=False)
+    add_event_listeners(element, tracked_events)
+    assert element.property("innerHTML") == "foobar"
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("innerHTML") == ""
+    assert_events_equal(session, ["focus", "blur"])
+    assert_element_has_focus(session.execute_script("return document.body"))
+
+
+def test_designmode(session, inline):
+    session.url = inline("foobar")
+    element = session.find.css("body", all=False)
+    assert element.property("innerHTML") == "foobar"
+    session.execute_script("document.designMode = 'on'")
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("innerHTML") in ["", "<br>"]
+    assert_element_has_focus(session.execute_script("return document.body"))
+
+
+def test_resettable_element_focus_when_empty(session, inline, add_event_listeners, tracked_events):
+    session.url = inline("<input>")
+    element = session.find.css("input", all=False)
+    add_event_listeners(element, tracked_events)
+    assert element.property("value") == ""
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("value") == ""
+    assert_events_equal(session, [])
+
+
+@pytest.mark.parametrize("type,invalid_value",
+                         [("number", "foo"),
+                          ("range", "foo"),
+                          ("email", "foo"),
+                          ("url", "foo"),
+                          ("color", "foo"),
+                          ("date", "foo"),
+                          ("datetime", "foo"),
+                          ("datetime-local", "foo"),
+                          ("time", "foo"),
+                          ("month", "foo"),
+                          ("week", "foo")])
+def test_resettable_element_does_not_satisfy_validation_constraints(session, inline, type, invalid_value):
+    """
+    Some UAs allow invalid input to certain types of constrained
+    form controls.  For example, Gecko allows non-valid characters
+    to be typed into <input type=number> but Chrome does not.
+    Since we want to test that Element Clear works for clearing the
+    invalid characters in these UAs, it is fine to skip this test
+    where UAs do not allow the element to not satisfy its constraints.
+    """
+    session.url = inline("<input type=%s>" % type)
+    element = session.find.css("input", all=False)
+
+    def is_valid(element):
+        return session.execute_script("""
+            var input = arguments[0];
+            return input.validity.valid;
+            """, args=(element,))
+
+    # value property does not get updated if the input is invalid
+    element.send_keys(invalid_value)
+
+    # UA does not allow invalid input for this form control type
+    if is_valid(element):
+        return
+
+    response = element_clear(session, element)
+    assert_success(response)
+    assert is_valid(element)
+
+
+@pytest.mark.parametrize("type",
+                         ["checkbox",
+                          "radio",
+                          "hidden",
+                          "submit",
+                          "button",
+                          "image"])
+def test_non_editable_inputs(session, inline, type):
+    session.url = inline("<input type=%s>" % type)
+    element = session.find.css("input", all=False)
+
+    response = element_clear(session, element)
+    assert_error(response, "invalid element state")
+
+
+def test_scroll_into_view(session, inline):
+    session.url = inline("""
+        <input value=foobar>
+        <div style='height: 200vh; width: 5000vh'>
+        """)
+    element = session.find.css("input", all=False)
+    assert element.property("value") == "foobar"
+    assert session.execute_script("return window.pageYOffset") == 0
+
+    # scroll to the bottom right of the page
+    session.execute_script("""
+        var body = document.body;
+        window.scrollTo(body.scrollWidth, body.scrollHeight);
+        """)
+
+    # clear and scroll back to the top of the page
+    response = element_clear(session, element)
+    assert_success(response)
+    assert element.property("value") == ""
+
+    # check if element cleared is scrolled into view
+    rect = session.execute_script("""
+        var input = arguments[0];
+        var rect = input.getBoundingClientRect();
+        return {"top": rect.top,
+                "left": rect.left,
+                "height": rect.height,
+                "width": rect.width};
+        """, args=(element,))
+    window = session.execute_script("""
+        return {"innerHeight": window.innerHeight,
+                "innerWidth": window.innerWidth,
+                "pageXOffset": window.pageXOffset,
+                "pageYOffset": window.pageYOffset};
+        """)
+
+    assert rect["top"] < (window["innerHeight"] + window["pageYOffset"]) and \
+           rect["left"] < (window["innerWidth"] + window["pageXOffset"]) and \
+           (rect["top"] + element.rect["height"]) > window["pageYOffset"] and \
+           (rect["left"] + element.rect["width"]) > window["pageXOffset"]
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_clear/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_clear/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_clear/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_clear/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/bubbling.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/bubbling.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/bubbling.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/bubbling.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/center_point.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/center_point.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/center_point.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/center_point.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/click.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/click.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/click.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/click.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/events.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/events.py
similarity index 90%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/events.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/events.py
index e3d32c1..30f2dfa 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/events.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/events.py
@@ -13,7 +13,9 @@
             element_id=element.id))
 
 def test_event_mousemove(session, url):
-    session.url = url("/webdriver/tests/element_click/support/test_click_wdspec.html")
+    session.url = url(
+        "/webdriver/tests/classic/element_click/support/test_click_wdspec.html"
+    )
 
     element = session.find.css('#outer', all=False)
     response = element_click(session, element)
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/file_upload.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/file_upload.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/file_upload.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/file_upload.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/interactability.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/interactability.py
new file mode 100644
index 0000000..d55860c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/interactability.py
@@ -0,0 +1,130 @@
+import pytest
+
+from tests.support.asserts import assert_error, assert_success
+
+
+def element_click(session, element):
+    return session.transport.send(
+        "POST", "session/{session_id}/element/{element_id}/click".format(
+            session_id=session.session_id,
+            element_id=element.id))
+
+
+def test_display_none(session, inline):
+    session.url = inline("""<button style="display: none">foobar</button>""")
+    element = session.find.css("button", all=False)
+
+    response = element_click(session, element)
+    assert_error(response, "element not interactable")
+
+
+def test_visibility_hidden(session, inline):
+    session.url = inline("""<button style="visibility: hidden">foobar</button>""")
+    element = session.find.css("button", all=False)
+
+    response = element_click(session, element)
+    assert_error(response, "element not interactable")
+
+
+def test_hidden(session, inline):
+    session.url = inline("<button hidden>foobar</button>")
+    element = session.find.css("button", all=False)
+
+    response = element_click(session, element)
+    assert_error(response, "element not interactable")
+
+
+def test_disabled(session, inline):
+    session.url = inline("""<button disabled>foobar</button>""")
+    element = session.find.css("button", all=False)
+
+    response = element_click(session, element)
+    assert_success(response)
+
+
+@pytest.mark.parametrize("transform", ["translate(-100px, -100px)", "rotate(50deg)"])
+def test_element_not_interactable_css_transform(session, inline, transform):
+    session.url = inline("""
+        <div style="width: 500px; height: 100px;
+            background-color: blue; transform: {transform};">
+            <input type=button>
+        </div>""".format(transform=transform))
+    element = session.find.css("input", all=False)
+    response = element_click(session, element)
+    assert_error(response, "element not interactable")
+
+
+def test_element_not_interactable_out_of_view(session, inline):
+    session.url = inline("""
+        <style>
+        input {
+          position: absolute;
+          margin-top: -100vh;
+          background: red;
+        }
+        </style>
+
+        <input>
+        """)
+    element = session.find.css("input", all=False)
+    response = element_click(session, element)
+    assert_error(response, "element not interactable")
+
+
+@pytest.mark.parametrize("tag_name", ["div", "span"])
+def test_zero_sized_element(session, inline, tag_name):
+    session.url = inline("<{0}></{0}>".format(tag_name))
+    element = session.find.css(tag_name, all=False)
+
+    response = element_click(session, element)
+    assert_error(response, "element not interactable")
+
+
+def test_element_intercepted(session, inline):
+    session.url = inline("""
+        <style>
+        div {
+          position: absolute;
+          height: 100vh;
+          width: 100vh;
+          background: blue;
+          top: 0;
+          left: 0;
+        }
+        </style>
+
+        <input type=button value=Roger>
+        <div></div>
+        """)
+    element = session.find.css("input", all=False)
+    response = element_click(session, element)
+    assert_error(response, "element click intercepted")
+
+
+def test_element_intercepted_no_pointer_events(session, inline):
+    session.url = inline("""<input type=button value=Roger style="pointer-events: none">""")
+    element = session.find.css("input", all=False)
+    response = element_click(session, element)
+    assert_error(response, "element click intercepted")
+
+
+def test_element_not_visible_overflow_hidden(session, inline):
+    session.url = inline("""
+        <style>
+        div {
+          overflow: hidden;
+          height: 50px;
+          background: green;
+        }
+
+        input {
+          margin-top: 100px;
+          background: red;
+        }
+        </style>
+
+        <div><input></div>
+        """)
+    element = session.find.css("input", all=False)
+    response = element_click(session, element)
+    assert_error(response, "element not interactable")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/navigate.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/navigate.py
similarity index 96%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/navigate.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/navigate.py
index 4927182..4d1c4823 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/navigate.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/navigate.py
@@ -15,7 +15,7 @@
 
 
 def test_numbers_link(session, server_config, inline):
-    link = "/webdriver/tests/element_click/support/input.html"
+    link = "/webdriver/tests/classic/element_click/support/input.html"
     session.url = inline("<a href={url}>123456</a>".format(url=link))
     element = session.find.css("a", all=False)
     response = element_click(session, element)
@@ -27,7 +27,7 @@
 
 
 def test_multi_line_link(session, server_config, inline):
-    link = "/webdriver/tests/element_click/support/input.html"
+    link = "/webdriver/tests/classic/element_click/support/input.html"
     session.url = inline("""
         <p style="background-color: yellow; width: 50px;">
             <a href={url}>Helloooooooooooooooooooo Worlddddddddddddddd</a>
@@ -42,7 +42,7 @@
 
 
 def test_link_unload_event(session, server_config, inline):
-    link = "/webdriver/tests/element_click/support/input.html"
+    link = "/webdriver/tests/classic/element_click/support/input.html"
     session.url = inline("""
         <body onunload="checkUnload()">
             <a href={url}>click here</a>
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/scroll_into_view.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/scroll_into_view.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/scroll_into_view.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/select.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/select.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/select.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/select.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/shadow_dom.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/shadow_dom.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/shadow_dom.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/shadow_dom.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/support/input.html b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/support/input.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/support/input.html
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/support/input.html
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/support/test_click_wdspec.html b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/support/test_click_wdspec.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/support/test_click_wdspec.html
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/support/test_click_wdspec.html
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_click/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/conftest.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/conftest.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/conftest.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/content_editable.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/content_editable.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/content_editable.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/content_editable.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/events.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/events.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/events.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/events.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/file_upload.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/file_upload.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/file_upload.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/form_controls.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/form_controls.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/form_controls.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/form_controls.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/interactability.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/interactability.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/interactability.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/interactability.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/scroll_into_view.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/scroll_into_view.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/scroll_into_view.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/scroll_into_view.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/send_keys.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/send_keys.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/send_keys.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/element_send_keys/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/arguments.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/arguments.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/arguments.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/arguments.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/collections.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/collections.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/collections.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/collections.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/cyclic.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/cyclic.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/cyclic.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/cyclic.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/execute_async.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/execute_async.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/execute_async.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/node.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/node.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/node.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/node.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/objects.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/objects.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/objects.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/objects.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/promise.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/promise.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/promise.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/promise.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/properties.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/properties.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/properties.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/properties.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_async_script/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_async_script/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/arguments.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/arguments.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/arguments.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/arguments.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/collections.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/collections.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/collections.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/collections.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/cyclic.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/cyclic.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/cyclic.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/cyclic.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/execute.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/execute.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/execute.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/execute.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/json_serialize_windowproxy.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/json_serialize_windowproxy.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/node.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/node.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/node.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/node.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/objects.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/objects.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/objects.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/objects.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/promise.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/promise.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/promise.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/promise.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/properties.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/properties.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/properties.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/properties.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/execute_script/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/execute_script/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_element/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_element/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element/find.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element/find.py
new file mode 100644
index 0000000..50de9255
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element/find.py
@@ -0,0 +1,121 @@
+import pytest
+
+from webdriver.transport import Response
+
+from tests.support.asserts import assert_error, assert_same_element, assert_success
+
+
+def find_element(session, using, value):
+    return session.transport.send(
+        "POST", "session/{session_id}/element".format(**vars(session)),
+        {"using": using, "value": value})
+
+
+def test_null_parameter_value(session, http):
+    path = "/session/{session_id}/element".format(**vars(session))
+    with http.post(path, None) as response:
+        assert_error(Response.from_http(response), "invalid argument")
+
+
+def test_no_top_browsing_context(session, closed_window):
+    response = find_element(session, "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_browsing_context(session, closed_frame):
+    response = find_element(session, "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+@pytest.mark.parametrize(
+    "selector",
+    ["#same1", "#in-frame", "#in-shadow-root"],
+    ids=["not-existent", "existent-other-frame", "existent-inside-shadow-root"],
+)
+def test_no_such_element_with_unknown_selector(session, get_test_page, selector):
+    session.url = get_test_page()
+
+    response = find_element(session, "css selector", selector)
+    assert_error(response, "no such element")
+
+
+@pytest.mark.parametrize("using", ["a", True, None, 1, [], {}])
+def test_invalid_using_argument(session, using):
+    response = find_element(session, using, "value")
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("value", [None, [], {}])
+def test_invalid_selector_argument(session, value):
+    response = find_element(session, "css selector", value)
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//a")])
+def test_find_element(session, inline, using, value):
+    session.url = inline("<a href=# id=linkText>full link text</a>")
+
+    response = find_element(session, using, value)
+    assert_success(response)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>link text</a>", "link text"),
+    ("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
+    ("<a href=#>link<br>text</a>", "link\ntext"),
+    ("<a href=#>link&amp;text</a>", "link&text"),
+    ("<a href=#>LINK TEXT</a>", "LINK TEXT"),
+    ("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
+])
+def test_find_element_link_text(session, inline, document, value):
+    session.url = inline(document)
+
+    response = find_element(session, "link text", value)
+    assert_success(response)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>partial link text</a>", "link"),
+    ("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
+    ("<a href=#>partial link text</a>", "k t"),
+    ("<a href=#>partial link<br>text</a>", "k\nt"),
+    ("<a href=#>partial link&amp;text</a>", "k&t"),
+    ("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
+    ("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
+])
+def test_find_element_partial_link_text(session, inline, document, value):
+    session.url = inline(document)
+
+    response = find_element(session, "partial link text", value)
+    assert_success(response)
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//*[name()='a']")])
+def test_xhtml_namespace(session, inline, using, value):
+    session.url = inline("""<a href="#" id="linkText">full link text</a>""",
+                         doctype="xhtml")
+    expected = session.execute_script("return document.links[0]")
+
+    response = find_element(session, using, value)
+    value = assert_success(response)
+    assert_same_element(session, value, expected)
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", ":root"),
+                          ("tag name", "html"),
+                          ("xpath", "/html")])
+def test_htmldocument(session, inline, using, value):
+    session.url = inline("")
+    response = find_element(session, using, value)
+    assert_success(response)
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_element/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_element/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_element_from_element/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_element/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_element_from_element/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_element/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_element/find.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_element/find.py
new file mode 100644
index 0000000..102704c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_element/find.py
@@ -0,0 +1,179 @@
+import pytest
+
+from webdriver.transport import Response
+
+from tests.support.asserts import assert_error, assert_same_element, assert_success
+
+
+def find_element(session, element_id, using, value):
+    return session.transport.send(
+        "POST", "session/{session_id}/element/{element_id}/element".format(
+            session_id=session.session_id,
+            element_id=element_id),
+        {"using": using, "value": value})
+
+
+def test_null_parameter_value(session, http, inline):
+    session.url = inline("<div><a href=# id=linkText>full link text</a></div>")
+    element = session.find.css("div", all=False)
+
+    path = "/session/{session_id}/element/{element_id}/element".format(
+        session_id=session.session_id, element_id=element.id)
+    with http.post(path, None) as response:
+        assert_error(Response.from_http(response), "invalid argument")
+
+
+def test_no_top_browsing_context(session, closed_window):
+    response = find_element(session, "notReal", "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_browsing_context(session, closed_frame):
+    response = find_element(session, "notReal", "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_such_element_with_shadow_root(session, get_test_page):
+    session.url = get_test_page()
+
+    element = session.find.css("custom-element", all=False)
+
+    result = find_element(session, element.shadow_root.id, "css selector", "#in-shadow-dom")
+    assert_error(result, "no such element")
+
+
+@pytest.mark.parametrize(
+    "selector",
+    ["#same1", "#in-frame", "#in-shadow-dom"],
+    ids=["not-existent", "existent-other-frame", "existent-inside-shadow-root"],
+)
+def test_no_such_element_with_unknown_selector(session, get_test_page, selector):
+    session.url = get_test_page()
+
+    from_element = session.find.css(":root", all=False)
+    response = find_element(session, from_element.id, "css selector", selector)
+    assert_error(response, "no such element")
+
+
+def test_no_such_element_with_startnode_from_other_window_handle(session, inline):
+    session.url = inline("<div id='parent'><p/>")
+    from_element = session.find.css("#parent", all=False)
+
+    new_handle = session.new_window()
+    session.window_handle = new_handle
+
+    response = find_element(session, from_element.id, "css selector", "p")
+    assert_error(response, "no such element")
+
+
+def test_no_such_element_with_startnode_from_other_frame(session, iframe, inline):
+    session.url = inline(iframe("<div id='parent'><p/>"))
+
+    session.switch_frame(0)
+    from_element = session.find.css("#parent", all=False)
+    session.switch_frame("parent")
+
+    response = find_element(session, from_element.id, "css selector", "p")
+    assert_error(response, "no such element")
+
+
+@pytest.mark.parametrize("as_frame", [False, True], ids=["top_context", "child_context"])
+def test_stale_element_reference(session, stale_element, as_frame):
+    element = stale_element("div#with-children", as_frame=as_frame)
+
+    response = find_element(session, element.id, "css selector", "p")
+    assert_error(response, "stale element reference")
+
+
+@pytest.mark.parametrize("using", ["a", True, None, 1, [], {}])
+def test_invalid_using_argument(session, using):
+    response = find_element(session, "notReal", using, "value")
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("value", [None, [], {}])
+def test_invalid_selector_argument(session, value):
+    response = find_element(session, "notReal", "css selector", value)
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//a")])
+def test_find_element(session, inline, using, value):
+    session.url = inline("<div><a href=# id=linkText>full link text</a></div>")
+    element = session.find.css("div", all=False)
+    response = find_element(session, element.id, using, value)
+    assert_success(response)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>link text</a>", "link text"),
+    ("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
+    ("<a href=#>link<br>text</a>", "link\ntext"),
+    ("<a href=#>link&amp;text</a>", "link&text"),
+    ("<a href=#>LINK TEXT</a>", "LINK TEXT"),
+    ("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
+])
+def test_find_element_link_text(session, inline, document, value):
+    # Step 8 - 9
+    session.url = inline("<div>{0}</div>".format(document))
+    element = session.find.css("div", all=False)
+
+    response = find_element(session, element.id, "link text", value)
+    assert_success(response)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>partial link text</a>", "link"),
+    ("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
+    ("<a href=#>partial link text</a>", "k t"),
+    ("<a href=#>partial link<br>text</a>", "k\nt"),
+    ("<a href=#>partial link&amp;text</a>", "k&t"),
+    ("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
+    ("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
+])
+def test_find_element_partial_link_text(session, inline, document, value):
+    session.url = inline("<div>{0}</div>".format(document))
+    element = session.find.css("div", all=False)
+
+    response = find_element(session, element.id, "partial link text", value)
+    assert_success(response)
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//*[name()='a']")])
+def test_xhtml_namespace(session, inline, using, value):
+    session.url = inline("""<p><a href="#" id="linkText">full link text</a></p>""",
+                         doctype="xhtml")
+    from_element = session.execute_script("""return document.querySelector("p")""")
+    expected = session.execute_script("return document.links[0]")
+
+    response = find_element(session, from_element.id, using, value)
+    value = assert_success(response)
+    assert_same_element(session, value, expected)
+
+
+def test_parent_htmldocument(session, inline):
+    session.url = inline("")
+    from_element = session.execute_script("""return document.querySelector("body")""")
+    expected = session.execute_script("return document.documentElement")
+
+    response = find_element(session, from_element.id, "xpath", "..")
+    value = assert_success(response)
+    assert_same_element(session, value, expected)
+
+
+def test_parent_of_document_node_errors(session, inline):
+    session.url = inline("")
+    from_element = session.execute_script("return document.documentElement")
+
+    response = find_element(session, from_element.id, "xpath", "..")
+    assert_error(response, "invalid selector")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_element_from_element/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_element/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_element_from_element/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_element/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_element_from_shadow_root/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_shadow_root/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_element_from_shadow_root/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_shadow_root/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py
new file mode 100644
index 0000000..62a5bc60
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_shadow_root/find.py
@@ -0,0 +1,228 @@
+import pytest
+from webdriver.client import ShadowRoot
+from webdriver.transport import Response
+
+from tests.support.asserts import assert_error, assert_same_element, assert_success
+
+
+def find_element(session, shadow_id, using, value):
+    return session.transport.send(
+        "POST", "session/{session_id}/shadow/{shadow_id}/element".format(
+            session_id=session.session_id,
+            shadow_id=shadow_id),
+        {"using": using, "value": value})
+
+
+def test_null_parameter_value(session, http, get_test_page):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    path = "/session/{session_id}/shadow/{shadow_id}/element".format(
+        session_id=session.session_id, shadow_id=shadow_root.id)
+    with http.post(path, None) as response:
+        assert_error(Response.from_http(response), "invalid argument")
+
+
+def test_no_top_browsing_context(session, closed_window):
+    response = find_element(session, "notReal", "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_browsing_context(session, closed_frame):
+    response = find_element(session, "notReal", "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_such_shadow_root_with_element(session, get_test_page):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+
+    result = find_element(session, host.id, "css selector", "input")
+    assert_error(result, "no such shadow root")
+
+
+def test_no_such_shadow_root_with_unknown_shadow_root(session):
+    shadow_root = ShadowRoot(session, "foo")
+
+    result = find_element(session, shadow_root.id, "css selector", "input")
+    assert_error(result, "no such shadow root")
+
+
+def test_no_such_shadow_root_with_shadow_root_from_other_window_handle(
+    session, get_test_page
+):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    new_handle = session.new_window()
+    session.window_handle = new_handle
+
+    response = find_element(session, shadow_root.id, "css selector", "div")
+    assert_error(response, "no such shadow root")
+
+
+def test_no_such_shadow_root_with_shadow_root_from_other_frame(
+    session, get_test_page
+):
+    session.url = get_test_page(as_frame=True)
+    session.switch_frame(0)
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    session.switch_frame("parent")
+
+    response = find_element(session, shadow_root.id, "css selector", "div")
+    assert_error(response, "no such shadow root")
+
+
+@pytest.mark.parametrize("as_frame", [False, True], ids=["top_context", "child_context"])
+def test_detached_shadow_root(session, get_test_page, as_frame):
+    session.url = get_test_page(as_frame=as_frame)
+
+    if as_frame:
+        frame = session.find.css("iframe", all=False)
+        session.switch_frame(frame)
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    session.execute_script("arguments[0].remove();", args=[host])
+
+    response = find_element(session, shadow_root.id, "css selector", "input")
+    assert_error(response, "detached shadow root")
+
+
+@pytest.mark.parametrize(
+    "selector",
+    ["#same1", "#in-frame", "#with-children"],
+    ids=["not-existent", "existent-other-frame", "existent-outside-shadow-root"],
+)
+def test_no_such_element_with_unknown_selector(session, get_test_page, selector):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    response = find_element(session, shadow_root.id, "css selector", selector)
+    assert_error(response, "no such element")
+
+
+@pytest.mark.parametrize("shadow_root_id", [True, None, 1, [], {}])
+def test_invalid_shadow_root_id_argument(session, get_test_page, shadow_root_id):
+    session.url = get_test_page()
+
+    response = find_element(session, shadow_root_id, "css selector", "input")
+    assert_error(response, "no such shadow root")
+
+
+@pytest.mark.parametrize("using", ["a", True, None, 1, [], {}])
+def test_invalid_using_argument(session, get_test_page, using):
+    session.url = get_test_page()
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    response = find_element(session, shadow_root.id, using, "input")
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("value", [None, [], {}])
+def test_invalid_selector_argument(session, get_test_page, value):
+    session.url = get_test_page()
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    response = find_element(session, shadow_root.id, "css selector", value)
+    assert_error(response, "invalid argument")
+
+
+def test_found_element_equivalence(session, get_test_page):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    expected = session.execute_script("""
+        return arguments[0].shadowRoot.querySelector('input')
+        """, args=(host,))
+
+    response = find_element(session, shadow_root.id, "css selector", "input")
+    value = assert_success(response)
+    assert_same_element(session, value, expected)
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//a")])
+@pytest.mark.parametrize("mode", ["open", "closed"])
+def test_find_element(session, get_test_page, using, value, mode):
+    session.url = get_test_page(
+        shadow_doc="<div><a href=# id=linkText>full link text</a></div>",
+        shadow_root_mode=mode,
+    )
+    shadow_root = session.find.css("custom-element", all=False).shadow_root
+
+    response = find_element(session, shadow_root.id, using, value)
+    response_value = assert_success(response)
+
+    # Script evaluation cannot use the DOM within a closed shadow root,
+    # that's why we assert on the copy of the shadow root on window.
+    expected = session.execute_script("""
+            return window._shadowRoot.querySelector('#linkText')
+        """)
+    assert_same_element(session, response_value, expected)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>link text</a>", "link text"),
+    ("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
+    ("<a href=#>link<br>text</a>", "link\ntext"),
+    ("<a href=#>link&amp;text</a>", "link&text"),
+    ("<a href=#>LINK TEXT</a>", "LINK TEXT"),
+    ("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
+])
+def test_find_element_link_text(session, get_test_page, document, value):
+    session.url = get_test_page(shadow_doc=f"<div>{document}</div>")
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    expected = session.execute_script("""
+        return arguments[0].shadowRoot.querySelectorAll('a')[0]
+        """,  args=(host,))
+
+    response = find_element(session, shadow_root.id, "link text", value)
+    value = assert_success(response)
+    assert_same_element(session, value, expected)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>partial link text</a>", "link"),
+    ("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
+    ("<a href=#>partial link text</a>", "k t"),
+    ("<a href=#>partial link<br>text</a>", "k\nt"),
+    ("<a href=#>partial link&amp;text</a>", "k&t"),
+    ("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
+    ("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
+])
+def test_find_element_partial_link_text(session, get_test_page, document, value):
+    session.url = get_test_page(shadow_doc=f"<div>{document}</div>")
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    expected = session.execute_script("""
+        return arguments[0].shadowRoot.querySelectorAll('a')[0]
+        """, args=(host,))
+
+    response = find_element(session, shadow_root.id, "partial link text", value)
+    value = assert_success(response)
+    assert_same_element(session, value, expected)
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_element_from_shadow_root/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_shadow_root/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_element_from_shadow_root/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_element_from_shadow_root/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements/find.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements/find.py
new file mode 100644
index 0000000..0d9ce21
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements/find.py
@@ -0,0 +1,141 @@
+import pytest
+
+from webdriver.transport import Response
+
+from tests.support.asserts import assert_error, assert_same_element, assert_success
+
+
+def find_elements(session, using, value):
+    return session.transport.send(
+        "POST", "session/{session_id}/elements".format(**vars(session)),
+        {"using": using, "value": value})
+
+
+def test_null_parameter_value(session, http):
+    path = "/session/{session_id}/elements".format(**vars(session))
+    with http.post(path, None) as response:
+        assert_error(Response.from_http(response), "invalid argument")
+
+
+def test_no_top_browsing_context(session, closed_window):
+    response = find_elements(session, "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_browsing_context(session, closed_frame):
+    response = find_elements(session, "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+@pytest.mark.parametrize(
+    "selector",
+    ["#same1", "#in-frame", "#in-shadow-dom"],
+    ids=["not-existent", "existent-other-frame", "existent-inside-shadow-root"],
+)
+def test_no_elements_with_unknown_selector(session, get_test_page,selector):
+    session.url = get_test_page()
+
+    response = find_elements(session, "css selector", selector)
+    elements = assert_success(response)
+    assert elements == []
+
+
+@pytest.mark.parametrize("using", ["a", True, None, 1, [], {}])
+def test_invalid_using_argument(session, using):
+    response = find_elements(session, using, "value")
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("value", [None, [], {}])
+def test_invalid_selector_argument(session, value):
+    response = find_elements(session, "css selector", value)
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//a")])
+def test_find_elements(session, inline, using, value):
+    session.url = inline("<a href=# id=linkText>full link text</a>")
+
+    response = find_elements(session, using, value)
+    assert_success(response)
+    assert len(response.body["value"]) == 1
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>link text</a>", "link text"),
+    ("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
+    ("<a href=#>link<br>text</a>", "link\ntext"),
+    ("<a href=#>link&amp;text</a>", "link&text"),
+    ("<a href=#>LINK TEXT</a>", "LINK TEXT"),
+    ("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
+])
+def test_find_elements_link_text(session, inline, document, value):
+    session.url = inline("<a href=#>not wanted</a><br/>{0}".format(document))
+    expected = session.execute_script("return document.links[1];")
+
+    response = find_elements(session, "link text", value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    found_element = value[0]
+    assert_same_element(session, found_element, expected)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>partial link text</a>", "link"),
+    ("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
+    ("<a href=#>partial link text</a>", "k t"),
+    ("<a href=#>partial link<br>text</a>", "k\nt"),
+    ("<a href=#>partial link&amp;text</a>", "k&t"),
+    ("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
+    ("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
+])
+def test_find_elements_partial_link_text(session, inline, document, value):
+    session.url = inline("<a href=#>not wanted</a><br/>{0}".format(document))
+    expected = session.execute_script("return document.links[1];")
+
+    response = find_elements(session, "partial link text", value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    found_element = value[0]
+    assert_same_element(session, found_element, expected)
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//*[name()='a']")])
+def test_xhtml_namespace(session, inline, using, value):
+    session.url = inline("""<a href="#" id="linkText">full link text</a>""",
+                         doctype="xhtml")
+    expected = session.execute_script("return document.links[0];")
+
+    response = find_elements(session, using, value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    found_element = value[0]
+    assert_same_element(session, found_element, expected)
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", ":root"),
+                          ("tag name", "html"),
+                          ("xpath", "/html")])
+def test_htmldocument(session, inline, using, value):
+    session.url = inline("")
+    response = find_elements(session, using, value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements_from_element/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_element/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements_from_element/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_element/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_element/find.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_element/find.py
new file mode 100644
index 0000000..fc898bc9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_element/find.py
@@ -0,0 +1,199 @@
+import pytest
+
+from webdriver.transport import Response
+
+from tests.support.asserts import assert_error, assert_same_element, assert_success
+
+
+def find_elements(session, element_id, using, value):
+    return session.transport.send(
+        "POST", "session/{session_id}/element/{element_id}/elements".format(
+            session_id=session.session_id,
+            element_id=element_id),
+        {"using": using, "value": value})
+
+
+def test_null_parameter_value(session, http, inline):
+    session.url = inline("<div><a href=# id=linkText>full link text</a></div>")
+    element = session.find.css("div", all=False)
+
+    path = "/session/{session_id}/element/{element_id}/elements".format(
+        session_id=session.session_id, element_id=element.id)
+    with http.post(path, None) as response:
+        assert_error(Response.from_http(response), "invalid argument")
+
+
+def test_no_top_browsing_context(session, closed_window):
+    response = find_elements(session, "notReal", "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_browsing_context(session, closed_frame):
+    response = find_elements(session, "notReal", "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_such_element_with_shadow_root(session, get_test_page):
+    session.url = get_test_page()
+
+    element = session.find.css("custom-element", all=False)
+
+    result = find_elements(session, element.shadow_root.id, "css selector", "#in-shadow-dom")
+    assert_error(result, "no such element")
+
+
+@pytest.mark.parametrize(
+    "selector",
+    ["#same1", "#in-frame", "#in-shadow-dom"],
+    ids=["not-existent", "existent-other-frame", "existent-inside-shadow-root"],
+)
+def test_no_elements_with_unknown_selector(session, get_test_page,selector):
+    session.url = get_test_page()
+
+    element = session.find.css(":root", all=False)
+    response = find_elements(session, element.id, "css selector", selector)
+    elements = assert_success(response)
+    assert elements == []
+
+
+def test_no_such_element_with_startnode_from_other_window_handle(session, inline):
+    session.url = inline("<div id='parent'><p/>")
+    from_element = session.find.css("#parent", all=False)
+
+    new_handle = session.new_window()
+    session.window_handle = new_handle
+
+    response = find_elements(session, from_element.id, "css selector", "p")
+    assert_error(response, "no such element")
+
+
+def test_no_such_element_with_startnode_from_other_frame(session, iframe, inline):
+    session.url = inline(iframe("<div id='parent'><p/>"))
+
+    session.switch_frame(0)
+    from_element = session.find.css("#parent", all=False)
+    session.switch_frame("parent")
+
+    response = find_elements(session, from_element.id, "css selector", "p")
+    assert_error(response, "no such element")
+
+
+@pytest.mark.parametrize("as_frame", [False, True], ids=["top_context", "child_context"])
+def test_stale_element_reference(session, stale_element, as_frame):
+    element = stale_element("div#with-children", as_frame=as_frame)
+
+    response = find_elements(session, element.id, "css selector", "p")
+    assert_error(response, "stale element reference")
+
+
+@pytest.mark.parametrize("using", [("a"), (True), (None), (1), ([]), ({})])
+def test_invalid_using_argument(session, using):
+    response = find_elements(session, "notReal", using, "value")
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("value", [None, [], {}])
+def test_invalid_selector_argument(session, value):
+    response = find_elements(session, "notReal", "css selector", value)
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//a")])
+def test_find_elements(session, inline, using, value):
+    session.url = inline("<div><a href=# id=linkText>full link text</a></div>")
+    element = session.find.css("div", all=False)
+    response = find_elements(session, element.id, using, value)
+    assert_success(response)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>link text</a>", "link text"),
+    ("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
+    ("<a href=#>link<br>text</a>", "link\ntext"),
+    ("<a href=#>link&amp;text</a>", "link&text"),
+    ("<a href=#>LINK TEXT</a>", "LINK TEXT"),
+    ("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
+])
+def test_find_elements_link_text(session, inline, document, value):
+    session.url = inline("<div><a href=#>not wanted</a><br/>{0}</div>".format(document))
+    element = session.find.css("div", all=False)
+    expected = session.execute_script("return document.links[1];")
+
+    response = find_elements(session, element.id, "link text", value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    found_element = value[0]
+    assert_same_element(session, found_element, expected)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>partial link text</a>", "link"),
+    ("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
+    ("<a href=#>partial link text</a>", "k t"),
+    ("<a href=#>partial link<br>text</a>", "k\nt"),
+    ("<a href=#>partial link&amp;text</a>", "k&t"),
+    ("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
+    ("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
+])
+def test_find_elements_partial_link_text(session, inline, document, value):
+    session.url = inline("<div><a href=#>not wanted</a><br/>{0}</div>".format(document))
+    element = session.find.css("div", all=False)
+    expected = session.execute_script("return document.links[1];")
+
+    response = find_elements(session, element.id, "partial link text", value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    found_element = value[0]
+    assert_same_element(session, found_element, expected)
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//*[name()='a']")])
+def test_xhtml_namespace(session, inline, using, value):
+    session.url = inline("""<p><a href="#" id="linkText">full link text</a></p>""",
+                         doctype="xhtml")
+    from_element = session.execute_script("""return document.querySelector("p")""")
+    expected = session.execute_script("return document.links[0]")
+
+    response = find_elements(session, from_element.id, using, value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    found_element = value[0]
+    assert_same_element(session, found_element, expected)
+
+
+def test_parent_htmldocument(session, inline):
+    session.url = inline("")
+    from_element = session.execute_script("""return document.querySelector("body")""")
+    expected = session.execute_script("return document.documentElement")
+
+    response = find_elements(session, from_element.id, "xpath", "..")
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    found_element = value[0]
+    assert_same_element(session, found_element, expected)
+
+
+def test_parent_of_document_node_errors(session, inline):
+    session.url = inline("")
+    from_element = session.execute_script("return document.documentElement")
+
+    response = find_elements(session, from_element.id, "xpath", "..")
+    assert_error(response, "invalid selector")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements_from_element/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_element/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements_from_element/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_element/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements_from_shadow_root/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements_from_shadow_root/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py
new file mode 100644
index 0000000..db739fd4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/find.py
@@ -0,0 +1,237 @@
+import pytest
+from webdriver.client import ShadowRoot
+from webdriver.transport import Response
+
+from tests.support.asserts import assert_error, assert_same_element, assert_success
+
+
+def find_elements(session, shadow_id, using, value):
+    return session.transport.send(
+        "POST", "session/{session_id}/shadow/{shadow_id}/elements".format(
+            session_id=session.session_id,
+            shadow_id=shadow_id),
+        {"using": using, "value": value})
+
+
+def test_null_parameter_value(session, http, get_test_page):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    path = "/session/{session_id}/shadow/{shadow_id}/elements".format(
+        session_id=session.session_id, shadow_id=shadow_root.id)
+    with http.post(path, None) as response:
+        assert_error(Response.from_http(response), "invalid argument")
+
+
+def test_no_top_browsing_context(session, closed_window):
+    response = find_elements(session, "notReal", "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_browsing_context(session, closed_frame):
+    response = find_elements(session, "notReal", "css selector", "foo")
+    assert_error(response, "no such window")
+
+
+def test_no_such_shadow_root_with_element(session, get_test_page):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+
+    result = find_elements(session, host.id, "css selector", "input")
+    assert_error(result, "no such shadow root")
+
+
+def test_no_such_shadow_root_with_unknown_shadow_root(session):
+    shadow_root = ShadowRoot(session, "foo")
+
+    result = find_elements(session, shadow_root.id, "css selector", "input")
+    assert_error(result, "no such shadow root")
+
+
+def test_no_such_shadow_root_with_shadow_root_from_other_window_handle(
+    session, get_test_page
+):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    new_handle = session.new_window()
+    session.window_handle = new_handle
+
+    response = find_elements(session, shadow_root.id, "css selector", "div")
+    assert_error(response, "no such shadow root")
+
+
+def test_no_such_shadow_root_with_shadow_root_from_other_frame(
+    session, get_test_page
+):
+    session.url = get_test_page(as_frame=True)
+    session.switch_frame(0)
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    session.switch_frame("parent")
+
+    response = find_elements(session, shadow_root.id, "css selector", "div")
+    assert_error(response, "no such shadow root")
+
+
+@pytest.mark.parametrize("as_frame", [False, True], ids=["top_context", "child_context"])
+def test_detached_shadow_root(session, get_test_page, as_frame):
+    session.url = get_test_page(as_frame=as_frame)
+
+    if as_frame:
+        frame = session.find.css("iframe", all=False)
+        session.switch_frame(frame)
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    session.execute_script("arguments[0].remove();", args=[host])
+
+    response = find_elements(session, shadow_root.id, "css selector", "input")
+    assert_error(response, "detached shadow root")
+
+
+@pytest.mark.parametrize(
+    "selector",
+    ["#same1", "#in-frame", "#with-children"],
+    ids=["not-existent", "existent-other-frame", "existent-outside-shadow-root"],
+)
+def test_no_elements_with_unknown_selector(session, get_test_page,selector):
+    session.url = get_test_page()
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    response = find_elements(session, shadow_root.id, "css selector", selector)
+    elements = assert_success(response)
+    assert elements == []
+
+
+@pytest.mark.parametrize("shadow_root_id", [True, None, 1, [], {}])
+def test_invalid_shadow_root_id_argument(session, get_test_page, shadow_root_id):
+    session.url = get_test_page()
+
+    response = find_elements(session, shadow_root_id, ("css selector"), "input")
+    assert_error(response, "no such shadow root")
+
+
+@pytest.mark.parametrize("using", [("a"), (True), (None), (1), ([]), ({})])
+def test_invalid_using_argument(session, get_test_page, using):
+    session.url = get_test_page()
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    response = find_elements(session, shadow_root.id, using, "input")
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("value", [None, [], {}])
+def test_invalid_selector_argument(session, get_test_page, value):
+    session.url = get_test_page()
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    response = find_elements(session, shadow_root.id, "css selector", value)
+    assert_error(response, "invalid argument")
+
+
+def test_find_elements_equivalence(session, get_test_page):
+    session.url = get_test_page(
+        shadow_doc="<div><input id='check' type='checkbox'/><input id='text'/></div>")
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    expected = session.execute_script("""
+        return arguments[0].shadowRoot.querySelector('input')
+        """, args=(host,))
+
+    response = find_elements(session, shadow_root.id, "css selector", "input")
+    assert_success(response)
+
+
+@pytest.mark.parametrize("using,value",
+                         [("css selector", "#linkText"),
+                          ("link text", "full link text"),
+                          ("partial link text", "link text"),
+                          ("tag name", "a"),
+                          ("xpath", "//a")])
+@pytest.mark.parametrize("mode", ["open", "closed"])
+def test_find_elements(session, get_test_page, using, value, mode):
+    session.url = get_test_page(
+        shadow_doc="<div><a href=# id=linkText>full link text</a></div>",
+        shadow_root_mode=mode,
+    )
+    shadow_root = session.find.css("custom-element", all=False).shadow_root
+
+    response = find_elements(session, shadow_root.id, using, value)
+    response_value = assert_success(response)
+
+    assert len(response_value) == 1
+
+    # Script evaluation cannot use the DOM within a closed shadow root,
+    # that's why we assert on the copy of the shadow root on window.
+    expected = session.execute_script("""
+            return window._shadowRoot.querySelector('#linkText')
+        """)
+    assert_same_element(session, response_value[0], expected)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>link text</a>", "link text"),
+    ("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
+    ("<a href=#>link<br>text</a>", "link\ntext"),
+    ("<a href=#>link&amp;text</a>", "link&text"),
+    ("<a href=#>LINK TEXT</a>", "LINK TEXT"),
+    ("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
+])
+def test_find_elements_link_text(session, get_test_page, document, value):
+    session.url = get_test_page(shadow_doc=f"<div><a href=#>not wanted</a><br/>{document}</div>")
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    expected = session.execute_script("""
+        return arguments[0].shadowRoot.querySelectorAll('a')[1]
+        """, args=(host,))
+
+    response = find_elements(session, shadow_root.id, "link text", value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    assert_same_element(session, value[0], expected)
+
+
+@pytest.mark.parametrize("document,value", [
+    ("<a href=#>partial link text</a>", "link"),
+    ("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
+    ("<a href=#>partial link text</a>", "k t"),
+    ("<a href=#>partial link<br>text</a>", "k\nt"),
+    ("<a href=#>partial link&amp;text</a>", "k&t"),
+    ("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
+    ("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
+])
+def test_find_elements_partial_link_text(session, get_test_page, document, value):
+    session.url = get_test_page(shadow_doc=f"<div><a href=#>not wanted</a><br/>{document}</div>")
+
+    host = session.find.css("custom-element", all=False)
+    shadow_root = host.shadow_root
+
+    expected = session.execute_script("""
+        return arguments[0].shadowRoot.querySelectorAll('a')[1]
+        """, args=(host,))
+
+    response = find_elements(session, shadow_root.id, "partial link text", value)
+    value = assert_success(response)
+    assert isinstance(value, list)
+    assert len(value) == 1
+
+    assert_same_element(session, value[0], expected)
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements_from_shadow_root/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/find_elements_from_shadow_root/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/find_elements_from_shadow_root/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/forward/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/forward/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/forward/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/forward/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/forward/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/forward/conftest.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/forward/conftest.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/forward/conftest.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/forward/forward.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/forward/forward.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/forward/forward.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/forward/forward.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/forward/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/forward/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/forward/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/forward/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/fullscreen_window/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/fullscreen_window/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/fullscreen_window/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/fullscreen_window/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/fullscreen_window/fullscreen.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/fullscreen_window/fullscreen.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/fullscreen_window/fullscreen.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/fullscreen_window/fullscreen.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/fullscreen_window/stress.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/fullscreen_window/stress.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/fullscreen_window/stress.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/fullscreen_window/stress.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/fullscreen_window/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/fullscreen_window/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/fullscreen_window/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/fullscreen_window/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_active_element/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_active_element/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_active_element/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_active_element/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_active_element/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_active_element/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_active_element/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_active_element/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_active_element/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_active_element/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_active_element/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_active_element/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_alert_text/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_alert_text/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_alert_text/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_alert_text/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_alert_text/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_alert_text/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_alert_text/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_alert_text/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_computed_label/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_computed_label/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_computed_label/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_computed_label/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_computed_role/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_computed_role/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_computed_role/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_computed_role/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/file.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/file.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/file.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/file.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/iframe.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/iframe.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/iframe.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/iframe.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_current_url/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_current_url/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_attribute/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_attribute/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_attribute/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_attribute/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_attribute/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_attribute/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_css_value/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_css_value/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_css_value/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_css_value/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_css_value/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_css_value/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_property/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_property/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_property/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_property/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_property/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_property/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_rect/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_rect/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_rect/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_rect/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_rect/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_rect/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_shadow_root/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_shadow_root/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_shadow_root/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_shadow_root/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_shadow_root/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_shadow_root/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_shadow_root/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_shadow_root/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_shadow_root/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_shadow_root/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_shadow_root/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_shadow_root/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_tag_name/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_tag_name/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_tag_name/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_tag_name/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_tag_name/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_tag_name/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_text/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_text/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_text/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_text/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_text/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_element_text/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_named_cookie/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_named_cookie/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_named_cookie/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_named_cookie/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_named_cookie/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_named_cookie/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_named_cookie/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_named_cookie/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_named_cookie/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_named_cookie/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_named_cookie/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_named_cookie/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_page_source/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_page_source/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_page_source/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_page_source/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_page_source/source.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_page_source/source.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_page_source/source.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_page_source/source.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_page_source/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_page_source/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_page_source/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_page_source/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_timeouts/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_timeouts/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_timeouts/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_timeouts/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_timeouts/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_timeouts/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_timeouts/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_timeouts/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_title/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_title/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_title/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_title/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_title/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_title/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_title/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_title/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_title/iframe.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_title/iframe.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_title/iframe.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_title/iframe.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_title/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_title/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_title/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_title/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handle/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handle/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handle/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handle/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handle/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handle/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handle/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handle/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handle/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handle/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handle/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handle/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handles/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handles/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handles/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handles/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handles/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handles/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handles/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handles/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handles/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handles/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_handles/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_handles/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_rect/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_rect/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_rect/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_rect/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_rect/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_rect/get.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_rect/get.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_rect/get.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_rect/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_rect/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_rect/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/get_window_rect/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/idlharness.window.js b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/idlharness.window.js
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/idlharness.window.js
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/idlharness.window.js
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/interface/interface.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/interface/interface.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/interface/interface.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/interface/interface.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_enabled/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_enabled/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/enabled.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/enabled.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_enabled/enabled.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_enabled/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_selected/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_selected/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/selected.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_selected/selected.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/selected.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_selected/selected.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_selected/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/is_element_selected/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/maximize_window/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/maximize_window/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/maximize_window/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/maximize_window/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/maximize_window/maximize.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/maximize_window/maximize.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/maximize_window/maximize.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/maximize_window/maximize.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/maximize_window/stress.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/maximize_window/stress.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/maximize_window/stress.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/maximize_window/stress.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/maximize_window/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/maximize_window/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/maximize_window/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/minimize_window/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/minimize_window/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/minimize_window/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/minimize_window/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/minimize_window/minimize.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/minimize_window/minimize.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/minimize_window/minimize.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/minimize_window/minimize.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/minimize_window/stress.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/minimize_window/stress.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/minimize_window/stress.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/minimize_window/stress.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/minimize_window/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/minimize_window/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/minimize_window/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/minimize_window/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/navigate_to/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/navigate_to/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/navigate_to/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/navigate_to/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/navigate_to/file.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/navigate_to/file.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/navigate_to/file.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/navigate_to/file.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/navigate_to/navigate.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/navigate_to/navigate.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/navigate_to/navigate.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/navigate_to/navigate.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/navigate_to/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/navigate_to/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/navigate_to/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/navigate_to/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/conftest.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/conftest.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/conftest.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/create_alwaysMatch.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/create_alwaysMatch.py
similarity index 86%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/create_alwaysMatch.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/create_alwaysMatch.py
index a4cc9efc..64fd0a74 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/create_alwaysMatch.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/create_alwaysMatch.py
@@ -5,7 +5,7 @@
 from .conftest import product, flatten
 
 from tests.support.asserts import assert_success
-from tests.new_session.support.create import valid_data
+from tests.classic.new_session.support.create import valid_data
 
 
 @pytest.mark.parametrize("key,value", flatten(product(*item) for item in valid_data))
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/create_firstMatch.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/create_firstMatch.py
similarity index 86%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/create_firstMatch.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/create_firstMatch.py
index ec671530..d4523f4 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/create_firstMatch.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/create_firstMatch.py
@@ -6,7 +6,7 @@
 
 
 from tests.support.asserts import assert_success
-from tests.new_session.support.create import valid_data
+from tests.classic.new_session.support.create import valid_data
 
 
 @pytest.mark.parametrize("key,value", flatten(product(*item) for item in valid_data))
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/default_values.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/default_values.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/default_values.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/default_values.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/invalid_capabilities.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/invalid_capabilities.py
new file mode 100644
index 0000000..be397ed
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/invalid_capabilities.py
@@ -0,0 +1,56 @@
+import pytest
+
+from .conftest import product, flatten
+
+from tests.classic.new_session.support.create import invalid_data, invalid_extensions
+from tests.support.asserts import assert_error
+
+
+@pytest.mark.parametrize("value", [None, 1, "{}", []])
+def test_invalid_capabilites(new_session, value):
+    response, _ = new_session({"capabilities": value})
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("value", [None, 1, "{}", []])
+def test_invalid_always_match(new_session, add_browser_capabilities, value):
+    capabilities = {"alwaysMatch": value, "firstMatch": [add_browser_capabilities({})]}
+
+    response, _ = new_session({"capabilities": capabilities})
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("value", [None, 1, "[]", {}])
+def test_invalid_first_match(new_session, add_browser_capabilities, value):
+    capabilities = {"alwaysMatch": add_browser_capabilities({}), "firstMatch": value}
+
+    response, _ = new_session({"capabilities": capabilities})
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("body", [lambda key, value: {"alwaysMatch": {key: value}},
+                                  lambda key, value: {"firstMatch": [{key: value}]}])
+@pytest.mark.parametrize("key,value", flatten(product(*item) for item in invalid_data))
+def test_invalid_values(new_session, add_browser_capabilities, body, key, value):
+    capabilities = body(key, value)
+    if "alwaysMatch" in capabilities:
+        capabilities["alwaysMatch"] = add_browser_capabilities(capabilities["alwaysMatch"])
+    else:
+        capabilities["firstMatch"][0] = add_browser_capabilities(capabilities["firstMatch"][0])
+
+    response, _ = new_session({"capabilities": capabilities})
+    assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("body", [lambda key, value: {"alwaysMatch": {key: value}},
+                                  lambda key, value: {"firstMatch": [{key: value}]}])
+@pytest.mark.parametrize("key", invalid_extensions)
+def test_invalid_extensions(new_session, add_browser_capabilities, body, key):
+    capabilities = body(key, {})
+    if "alwaysMatch" in capabilities:
+        capabilities["alwaysMatch"] = add_browser_capabilities(capabilities["alwaysMatch"])
+    else:
+        capabilities["firstMatch"][0] = add_browser_capabilities(capabilities["firstMatch"][0])
+
+    response, _ = new_session({"capabilities": capabilities})
+    assert_error(response, "invalid argument")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/merge.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/merge.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/merge.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/merge.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/page_load_strategy.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/page_load_strategy.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/page_load_strategy.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/page_load_strategy.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/platform_name.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/platform_name.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/platform_name.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/platform_name.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/response.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/response.py
new file mode 100644
index 0000000..43a8d579
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/response.py
@@ -0,0 +1,44 @@
+import uuid
+import pytest
+
+from tests.support.asserts import assert_success
+
+
+def test_sessionid(new_session, add_browser_capabilities):
+    response, _ = new_session({"capabilities": {"alwaysMatch": add_browser_capabilities({})}})
+    value = assert_success(response)
+    assert isinstance(value["sessionId"], str)
+    uuid.UUID(hex=value["sessionId"])
+
+
+@pytest.mark.parametrize("capability, type", [
+    ("browserName", str),
+    ("browserVersion", str),
+    ("platformName", str),
+    ("acceptInsecureCerts", bool),
+    ("pageLoadStrategy", str),
+    ("proxy", dict),
+    ("setWindowRect", bool),
+    ("timeouts", dict),
+    ("strictFileInteractability", bool),
+    ("unhandledPromptBehavior", str),
+])
+def test_capability_type(session, capability, type):
+    assert isinstance(session.capabilities, dict)
+    assert capability in session.capabilities
+    assert isinstance(session.capabilities[capability], type)
+
+
+@pytest.mark.parametrize("capability, default_value", [
+    ("acceptInsecureCerts", False),
+    ("pageLoadStrategy", "normal"),
+    ("proxy", {}),
+    ("setWindowRect", True),
+    ("timeouts", {"implicit": 0, "pageLoad": 300000, "script": 30000}),
+    ("strictFileInteractability", False),
+    ("unhandledPromptBehavior", "dismiss and notify"),
+])
+def test_capability_default_value(session, capability, default_value):
+    assert isinstance(session.capabilities, dict)
+    assert capability in session.capabilities
+    assert session.capabilities[capability] == default_value
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/support/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/support/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/support/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/support/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/support/create.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/support/create.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/support/create.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/support/create.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/timeouts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/timeouts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/timeouts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/timeouts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/websocket_url.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/websocket_url.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_session/websocket_url.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_session/websocket_url.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/new.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/new.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/new.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/new.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/new_tab.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/new_tab.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/new_tab.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/new_tab.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/new_window.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/new_window.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/new_window.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/new_window.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/new_window/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/new_window/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/conftest.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/conftest.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/conftest.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key.py
similarity index 93%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key.py
index 6730b1c..6c34452 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key.py
@@ -2,7 +2,7 @@
 
 from webdriver.error import NoSuchWindowException
 
-from tests.perform_actions.support.refine import get_keys
+from tests.classic.perform_actions.support.refine import get_keys
 from tests.support.keys import Keys
 
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_events.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_events.py
similarity index 98%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_events.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_events.py
index 472fb54c..a1cd9ce 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_events.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_events.py
@@ -4,7 +4,7 @@
 
 import pytest
 
-from tests.perform_actions.support.refine import get_events, get_keys
+from tests.classic.perform_actions.support.refine import get_events, get_keys
 from tests.support.helpers import filter_dict, filter_supported_key_events
 from tests.support.keys import ALL_EVENTS, ALTERNATIVE_KEY_NAMES, Keys
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_modifiers.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_modifiers.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_modifiers.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_modifiers.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_shortcuts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_shortcuts.py
similarity index 95%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_shortcuts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_shortcuts.py
index 46bc3c4..a5e15156 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_shortcuts.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_shortcuts.py
@@ -1,4 +1,4 @@
-from tests.perform_actions.support.refine import get_keys
+from tests.classic.perform_actions.support.refine import get_keys
 from tests.support.keys import Keys
 
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_special_keys.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_special_keys.py
similarity index 93%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_special_keys.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_special_keys.py
index 003bba42..c55f3a1 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/key_special_keys.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/key_special_keys.py
@@ -2,7 +2,7 @@
 
 from webdriver import error
 
-from tests.perform_actions.support.refine import get_keys
+from tests.classic.perform_actions.support.refine import get_keys
 
 
 @pytest.mark.parametrize("value", [
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/none.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/none.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/none.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/none.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_contextmenu.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_contextmenu.py
similarity index 97%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_contextmenu.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_contextmenu.py
index 2e06e8ca5..4a48ea0 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_contextmenu.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_contextmenu.py
@@ -1,6 +1,6 @@
 import pytest
 
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.refine import get_events
 from tests.support.helpers import filter_dict
 from tests.support.keys import Keys
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_dblclick.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_dblclick.py
similarity index 93%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_dblclick.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_dblclick.py
index 5be635a..659e27bd 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_dblclick.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_dblclick.py
@@ -1,6 +1,6 @@
 import pytest
 
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.refine import get_events
 from tests.support.asserts import assert_move_to_coordinates
 from tests.support.helpers import filter_dict
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_modifier_click.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_modifier_click.py
similarity index 96%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_modifier_click.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_modifier_click.py
index ffba6fc3..f3e54288 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_modifier_click.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_modifier_click.py
@@ -1,6 +1,6 @@
 import pytest
 
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.refine import get_events
 from tests.support.helpers import filter_dict
 from tests.support.keys import Keys
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_mouse.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_mouse.py
similarity index 97%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_mouse.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_mouse.py
index 14da987..31d0849 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_mouse.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_mouse.py
@@ -4,8 +4,11 @@
 
 from webdriver.error import InvalidArgumentException, NoSuchWindowException, StaleElementReferenceException
 
-from tests.perform_actions.support.mouse import get_inview_center, get_viewport_rect
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.mouse import (
+    get_inview_center,
+    get_viewport_rect,
+)
+from tests.classic.perform_actions.support.refine import get_events
 from tests.support.asserts import assert_move_to_coordinates
 from tests.support.helpers import filter_dict
 from tests.support.sync import Poll
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_origin.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_origin.py
similarity index 97%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_origin.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_origin.py
index 8d4dc90..33b8a259 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_origin.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_origin.py
@@ -2,7 +2,10 @@
 
 from webdriver import MoveTargetOutOfBoundsException
 
-from tests.perform_actions.support.mouse import get_inview_center, get_viewport_rect
+from tests.classic.perform_actions.support.mouse import (
+    get_inview_center,
+    get_viewport_rect,
+)
 
 
 def get_click_coordinates(session):
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_pause_dblclick.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_pause_dblclick.py
similarity index 91%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_pause_dblclick.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_pause_dblclick.py
index d46178a..209de727 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_pause_dblclick.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_pause_dblclick.py
@@ -1,5 +1,8 @@
-from tests.perform_actions.support.mouse import get_inview_center, get_viewport_rect
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.mouse import (
+    get_inview_center,
+    get_viewport_rect,
+)
+from tests.classic.perform_actions.support.refine import get_events
 from tests.support.helpers import filter_dict
 
 _DBLCLICK_INTERVAL = 640
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_pen.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_pen.py
similarity index 94%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_pen.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_pen.py
index 29d40276..e9cd103 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_pen.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_pen.py
@@ -4,8 +4,11 @@
 
 from webdriver.error import NoSuchWindowException, StaleElementReferenceException
 
-from tests.perform_actions.support.mouse import get_inview_center, get_viewport_rect
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.mouse import (
+    get_inview_center,
+    get_viewport_rect,
+)
+from tests.classic.perform_actions.support.refine import get_events
 
 
 def test_null_response_value(session, pen_chain):
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_touch.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_touch.py
similarity index 95%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_touch.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_touch.py
index 03f32af..7f940f6 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_touch.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_touch.py
@@ -3,8 +3,11 @@
 import pytest
 
 from webdriver.error import NoSuchWindowException, StaleElementReferenceException
-from tests.perform_actions.support.mouse import get_inview_center, get_viewport_rect
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.mouse import (
+    get_inview_center,
+    get_viewport_rect,
+)
+from tests.classic.perform_actions.support.refine import get_events
 
 
 def test_null_response_value(session, touch_chain):
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_tripleclick.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_tripleclick.py
similarity index 94%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_tripleclick.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_tripleclick.py
index fff70b8..b45709d 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/pointer_tripleclick.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/pointer_tripleclick.py
@@ -1,6 +1,6 @@
 import math
 
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.refine import get_events
 from tests.support.asserts import assert_move_to_coordinates
 from tests.support.helpers import filter_dict
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/sequence.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/sequence.py
similarity index 72%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/sequence.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/sequence.py
index 3536abe..f6c12220 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/sequence.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/sequence.py
@@ -1,6 +1,6 @@
 # META: timeout=long
 
-from tests.perform_actions.support.refine import get_events, get_keys
+from tests.classic.perform_actions.support.refine import get_events, get_keys
 
 
 def test_perform_no_actions_send_no_events(session, key_reporter, key_chain):
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/support/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/support/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/support/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/support/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/support/mouse.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/support/mouse.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/support/mouse.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/support/mouse.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/support/refine.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/support/refine.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/support/refine.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/support/refine.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py
similarity index 98%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py
index 6bbd22a..820edbe 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/user_prompts.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/user_prompts.py
@@ -2,7 +2,7 @@
 
 import pytest
 
-from tests.perform_actions.support.refine import get_keys
+from tests.classic.perform_actions.support.refine import get_keys
 from tests.support.asserts import assert_error, assert_success, assert_dialog_handled
 
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/validity.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/validity.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/validity.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/validity.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/wheel.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/wheel.py
similarity index 97%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/wheel.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/wheel.py
index 59da29fe..7ee0ae7 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/wheel.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/perform_actions/wheel.py
@@ -2,7 +2,7 @@
 
 from webdriver.error import InvalidArgumentException, NoSuchWindowException
 
-from tests.perform_actions.support.refine import get_events
+from tests.classic.perform_actions.support.refine import get_events
 from tests.support.asserts import assert_move_to_coordinates
 from tests.support.helpers import filter_dict
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/permissions/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/permissions/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/permissions/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/permissions/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/permissions/set.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/permissions/set.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/permissions/set.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/permissions/set.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/print/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/print/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/print/background.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/background.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/print/background.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/background.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/print/orientation.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/orientation.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/print/orientation.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/orientation.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/print/printcmd.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/printcmd.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/print/printcmd.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/printcmd.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/print/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/print/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/print/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/refresh/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/refresh/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/refresh/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/refresh/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/refresh/refresh.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/refresh/refresh.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/refresh/refresh.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/refresh/refresh.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/refresh/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/refresh/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/refresh/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/refresh/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/conftest.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/conftest.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/conftest.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/release.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/release.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/release.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/release.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/sequence.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/sequence.py
similarity index 96%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/sequence.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/sequence.py
index 24ca16c86..78912d8b 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/sequence.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/sequence.py
@@ -1,6 +1,6 @@
 # META: timeout=long
 
-from tests.release_actions.support.refine import get_events, get_keys
+from tests.classic.release_actions.support.refine import get_events, get_keys
 from tests.support.helpers import filter_dict, filter_supported_key_events
 
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/support/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/support/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/refine.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/support/refine.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/refine.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/release_actions/support/refine.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/send_alert_text/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/send_alert_text/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/send_alert_text/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/send_alert_text/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/send_alert_text/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/send_alert_text/conftest.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/send_alert_text/conftest.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/send_alert_text/conftest.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/send_alert_text/send.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/send_alert_text/send.py
new file mode 100644
index 0000000..df218c80
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/send_alert_text/send.py
@@ -0,0 +1,94 @@
+import pytest
+
+from webdriver.error import NoSuchAlertException
+from webdriver.transport import Response
+
+from tests.support.asserts import assert_error, assert_success
+from tests.support.sync import Poll
+
+
+@pytest.fixture
+def page(session, inline):
+    session.url = inline("""
+        <script>window.result = window.prompt('Enter Your Name: ', 'Name');</script>
+    """)
+
+
+def send_alert_text(session, text=None):
+    return session.transport.send(
+        "POST", "session/{session_id}/alert/text".format(**vars(session)),
+        {"text": text})
+
+
+def test_null_parameter_value(session, http):
+    path = "/session/{session_id}/alert/text".format(**vars(session))
+    with http.post(path, None) as response:
+        assert_error(Response.from_http(response), "invalid argument")
+
+
+def test_null_response_value(session, page):
+    response = send_alert_text(session, "Federer")
+    value = assert_success(response)
+    assert value is None
+
+
+@pytest.mark.parametrize("text", [None, {}, [], 42, True])
+def test_invalid_input(session, page, text):
+    response = send_alert_text(session, text)
+    assert_error(response, "invalid argument")
+
+
+def test_no_top_browsing_context(session, closed_window):
+    response = send_alert_text(session, "Federer")
+    assert_error(response, "no such window")
+
+
+def test_no_browsing_context(session, closed_frame):
+    response = send_alert_text(session, "Federer")
+    assert_error(response, "no such alert")
+
+
+def test_no_user_prompt(session):
+    response = send_alert_text(session, "Federer")
+    assert_error(response, "no such alert")
+
+
+@pytest.mark.parametrize("dialog_type", ["alert", "confirm"])
+def test_alert_element_not_interactable(session, inline, dialog_type):
+    session.url = inline("<script>window.{}('Hello');</script>".format(dialog_type))
+
+    response = send_alert_text(session, "Federer")
+    assert_error(response, "element not interactable")
+
+
+@pytest.mark.parametrize("dialog_type", ["alert", "confirm"])
+def test_chained_alert_element_not_interactable(session, inline, dialog_type):
+    session.url = inline("<script>window.{}('Hello');</script>".format(dialog_type))
+    session.alert.accept()
+
+    session.url = inline("<script>window.{}('Hello');</script>".format(dialog_type))
+    response = send_alert_text(session, "Federer")
+    assert_error(response, "element not interactable")
+
+
+@pytest.mark.parametrize("text", ["", "Federer", " Fed erer ", "Fed\terer"])
+def test_send_alert_text(session, page, text):
+    send_response = send_alert_text(session, text)
+    assert_success(send_response)
+
+    session.alert.accept()
+
+    assert session.execute_script("return window.result") == text
+
+
+def test_unexpected_alert(session):
+    session.execute_script("setTimeout(function() { prompt('Hello'); }, 100);")
+    wait = Poll(
+        session,
+        timeout=5,
+        ignored_exceptions=NoSuchAlertException,
+        message="No user prompt with text 'Hello' detected")
+    wait.until(lambda s: s.alert.text == "Hello")
+
+    response = send_alert_text(session, "Federer")
+    assert_success(response)
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_timeouts/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_timeouts/__init__.py
similarity index 100%
copy from third_party/blink/web_tests/external/wpt/webdriver/tests/get_timeouts/__init__.py
copy to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_timeouts/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/set_timeouts/set.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_timeouts/set.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/set_timeouts/set.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_timeouts/set.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/set_timeouts/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_timeouts/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/set_timeouts/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_timeouts/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_rect/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_window_rect/__init__.py
similarity index 100%
copy from third_party/blink/web_tests/external/wpt/webdriver/tests/get_window_rect/__init__.py
copy to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_window_rect/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/set_window_rect/set.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_window_rect/set.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/set_window_rect/set.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_window_rect/set.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/set_window_rect/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_window_rect/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/set_window_rect/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/set_window_rect/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/status/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/status/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/status/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/status/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/status/status.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/status/status.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/status/status.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/status/status.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/cross_origin.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/cross_origin.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/cross_origin.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/cross_origin.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/switch.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/switch.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/switch.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/switch.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/switch_number.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/switch_number.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/switch_number.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/switch_number.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/switch_webelement.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/switch_webelement.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_frame/switch_webelement.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_frame/switch_webelement.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_parent_frame/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_parent_frame/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_parent_frame/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_parent_frame/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_parent_frame/switch.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_parent_frame/switch.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_parent_frame/switch.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_parent_frame/switch.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_window/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_window/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/alerts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_window/alerts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/alerts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_window/alerts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/switch.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_window/switch.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/switch.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/switch_to_window/switch.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/take_element_screenshot/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_element_screenshot/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/take_element_screenshot/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_element_screenshot/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/take_element_screenshot/iframe.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_element_screenshot/iframe.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/take_element_screenshot/iframe.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_element_screenshot/iframe.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/take_element_screenshot/screenshot.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_element_screenshot/screenshot.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/take_element_screenshot/screenshot.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_element_screenshot/screenshot.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/take_element_screenshot/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_element_screenshot/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/take_screenshot/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_screenshot/__init__.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/take_screenshot/__init__.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_screenshot/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/take_screenshot/iframe.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_screenshot/iframe.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/take_screenshot/iframe.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_screenshot/iframe.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/take_screenshot/screenshot.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_screenshot/screenshot.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/take_screenshot/screenshot.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_screenshot/screenshot.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/take_screenshot/user_prompts.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/webdriver/tests/take_screenshot/user_prompts.py
rename to third_party/blink/web_tests/external/wpt/webdriver/tests/classic/take_screenshot/user_prompts.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/set_timeouts/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/set_timeouts/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/set_timeouts/__init__.py
+++ /dev/null
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/set_window_rect/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/set_window_rect/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/set_window_rect/__init__.py
+++ /dev/null
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-svg-image-expected.html b/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-svg-image-expected.html
index a18476a..76dbc8d9 100644
--- a/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-svg-image-expected.html
+++ b/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-svg-image-expected.html
@@ -20,6 +20,7 @@
   <image id="img4" href="invalid" x="0" y="0" width="20px" height="20px" />
 </svg>
 <svg id="s5" width="20px" height="20px">
+  <image id="img1" href="resources/pattern.png" x="0" y="0" width="20px" height="20px" />
 </svg>
 <svg id="s6" width="20px" height="20px">
   <image id="img1" href="resources/pattern.png" x="0" y="0" width="10px" height="10px" />
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-svg-image.html b/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-svg-image.html
index 6780ef2..a9fab70 100644
--- a/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-svg-image.html
+++ b/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-svg-image.html
@@ -24,21 +24,35 @@
 <canvas id="c6" width="20" height="20"></canvas>
 
 <script>
-var draw = function(target, img, x, y, opts) {
-  document.getElementById(img).addEventListener("load", function() {
-    createImageBitmap(this, opts).then((ib) => {
+function draw(target, img, x, y, opts) {
+  return new Promise((resolve)=> {
+    createImageBitmap(document.getElementById(img), opts).then((ib) => {
       document.getElementById(target).getContext("2d").drawImage(
         ib, x || 0, y || 0);
-    });
+      resolve();
+    },
+      resolve // createImageBitmap rejection forwarded to resolve
+    );
   });
 }
 
-draw("c1", "img1");
-draw("c2", "img2", 10, 10);
-draw("c3", "img3");
-draw("c4", "img4");
-document.getElementById("c5").getContext("2d").drawImage(
-  document.getElementById("img5"), 0, 0);
-draw("c6", "img2", 0, 0, {resizeWidth: 10, resizeHeight: 10});
+if (window.testRunner) {
+  testRunner.waitUntilDone();
+}
 
+window.onload = async () => {
+  await Promise.all([
+    draw("c1", "img1"),
+    draw("c2", "img2", 10, 10),
+    draw("c3", "img3"),
+    draw("c4", "img4"),
+    draw("c6", "img2", 0, 0, {resizeWidth: 10, resizeHeight: 10})
+  ]);
+  document.getElementById("c5").getContext("2d").drawImage(
+    document.getElementById("img5"), 0, 0);
+
+  if (window.testRunner) {
+    testRunner.notifyDone();
+  }
+}
 </script>
diff --git a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
index f2ad8576..432a8bc 100644
--- a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
+++ b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
@@ -321,6 +321,7 @@
 scroll-timeline-attachment: local
 scroll-timeline-axis: block
 scroll-timeline-name: none
+scrollbar-color: auto
 scrollbar-gutter: auto
 scrollbar-width: auto
 shape-image-threshold: 0
diff --git a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
index 1b84785..433f342d 100644
--- a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
+++ b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
@@ -321,6 +321,7 @@
 scroll-timeline-attachment: local
 scroll-timeline-axis: block
 scroll-timeline-name: none
+scrollbar-color: auto
 scrollbar-gutter: auto
 scrollbar-width: auto
 shape-image-threshold: 0
diff --git "a/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
index e5b3b70..ab62516 100644
--- "a/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 348 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 355 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1-expected.txt
index c229e9a..2bbb3b4 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1-expected.txt
@@ -3,44 +3,44 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) errorCallback (async-callstack-async-await1.js:64)
-    1) doTestSettledPromisesRejected (async-callstack-async-await1.js:96)
+    0) errorCallback (async-callstack-async-await1.js:67)
+    1) doTestSettledPromisesRejected (async-callstack-async-await1.js:99)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await1.js:54)
+    0) testFunctionTimeout (async-callstack-async-await1.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await1.js:47)
+    0) testFunction (async-callstack-async-await1.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) promiseCallback (async-callstack-async-await1.js:72)
-    1) doTestPromiseConstructor (async-callstack-async-await1.js:70)
-    2) testFunctionTimeout (async-callstack-async-await1.js:54)
+    0) promiseCallback (async-callstack-async-await1.js:75)
+    1) doTestPromiseConstructor (async-callstack-async-await1.js:73)
+    2) testFunctionTimeout (async-callstack-async-await1.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await1.js:47)
+    0) testFunction (async-callstack-async-await1.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-async-await1.js:59)
-    1) doTestPromiseConstructor (async-callstack-async-await1.js:74)
+    0) thenCallback (async-callstack-async-await1.js:62)
+    1) doTestPromiseConstructor (async-callstack-async-await1.js:77)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await1.js:54)
+    0) testFunctionTimeout (async-callstack-async-await1.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await1.js:47)
+    0) testFunction (async-callstack-async-await1.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-async-await1.js:59)
-    1) doTestSettledPromisesResolved (async-callstack-async-await1.js:84)
+    0) thenCallback (async-callstack-async-await1.js:62)
+    1) doTestSettledPromisesResolved (async-callstack-async-await1.js:87)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await1.js:54)
+    0) testFunctionTimeout (async-callstack-async-await1.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await1.js:47)
+    0) testFunction (async-callstack-async-await1.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1.js
index 1340787..45a19110 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1.js
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for async functions.\n`);
 
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
     function timeoutPromise(value, ms)
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await2-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await2-expected.txt
index eaffab8..eb12b80 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await2-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await2-expected.txt
@@ -3,63 +3,63 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) doTestChainedPromises (async-callstack-async-await2.js:71)
+    0) doTestChainedPromises (async-callstack-async-await2.js:74)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await2.js:54)
+    0) testFunctionTimeout (async-callstack-async-await2.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await2.js:47)
+    0) testFunction (async-callstack-async-await2.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) doTestChainedPromises (async-callstack-async-await2.js:73)
+    0) doTestChainedPromises (async-callstack-async-await2.js:76)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await2.js:54)
+    0) testFunctionTimeout (async-callstack-async-await2.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await2.js:47)
+    0) testFunction (async-callstack-async-await2.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) doTestChainedPromises (async-callstack-async-await2.js:75)
+    0) doTestChainedPromises (async-callstack-async-await2.js:78)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await2.js:54)
+    0) testFunctionTimeout (async-callstack-async-await2.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await2.js:47)
+    0) testFunction (async-callstack-async-await2.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) doTestChainedPromises (async-callstack-async-await2.js:77)
+    0) doTestChainedPromises (async-callstack-async-await2.js:80)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await2.js:54)
+    0) testFunctionTimeout (async-callstack-async-await2.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await2.js:47)
+    0) testFunction (async-callstack-async-await2.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-async-await2.js:59)
-    1) doTestChainedPromises (async-callstack-async-await2.js:78)
+    0) thenCallback (async-callstack-async-await2.js:62)
+    1) doTestChainedPromises (async-callstack-async-await2.js:81)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await2.js:54)
+    0) testFunctionTimeout (async-callstack-async-await2.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await2.js:47)
+    0) testFunction (async-callstack-async-await2.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-async-await2.js:59)
-    1) doTestChainedPromisesJSON (async-callstack-async-await2.js:90)
+    0) thenCallback (async-callstack-async-await2.js:62)
+    1) doTestChainedPromisesJSON (async-callstack-async-await2.js:93)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await2.js:54)
+    0) testFunctionTimeout (async-callstack-async-await2.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await2.js:47)
+    0) testFunction (async-callstack-async-await2.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await2.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await2.js
index b7d9e68..b4bf5a44 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await2.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await2.js
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for async functions.\n`);
 
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
     function timeoutPromise(value, ms)
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3-expected.txt
index aa06f00..1ef3860 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3-expected.txt
@@ -3,56 +3,56 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) errorCallback (async-callstack-async-await3.js:64)
-    1) doTestPromiseReject (async-callstack-async-await3.js:133)
+    0) errorCallback (async-callstack-async-await3.js:67)
+    1) doTestPromiseReject (async-callstack-async-await3.js:136)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await3.js:54)
+    0) testFunctionTimeout (async-callstack-async-await3.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await3.js:47)
+    0) testFunction (async-callstack-async-await3.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) errorCallback (async-callstack-async-await3.js:64)
-    1) doTestRejectFromChain (async-callstack-async-await3.js:113)
+    0) errorCallback (async-callstack-async-await3.js:67)
+    1) doTestRejectFromChain (async-callstack-async-await3.js:116)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await3.js:54)
+    0) testFunctionTimeout (async-callstack-async-await3.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await3.js:47)
+    0) testFunction (async-callstack-async-await3.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) errorCallback (async-callstack-async-await3.js:64)
-    1) doTestThrowFromChain (async-callstack-async-await3.js:93)
+    0) errorCallback (async-callstack-async-await3.js:67)
+    1) doTestThrowFromChain (async-callstack-async-await3.js:96)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await3.js:54)
+    0) testFunctionTimeout (async-callstack-async-await3.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await3.js:47)
+    0) testFunction (async-callstack-async-await3.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-async-await3.js:59)
-    1) doTestPromiseAll (async-callstack-async-await3.js:71)
+    0) thenCallback (async-callstack-async-await3.js:62)
+    1) doTestPromiseAll (async-callstack-async-await3.js:74)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await3.js:54)
+    0) testFunctionTimeout (async-callstack-async-await3.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await3.js:47)
+    0) testFunction (async-callstack-async-await3.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-async-await3.js:59)
-    1) doTestPromiseResolve (async-callstack-async-await3.js:121)
+    0) thenCallback (async-callstack-async-await3.js:62)
+    1) doTestPromiseResolve (async-callstack-async-await3.js:124)
     [await]
-    0) testFunctionTimeout (async-callstack-async-await3.js:54)
+    0) testFunctionTimeout (async-callstack-async-await3.js:57)
     [setTimeout]
-    0) testFunction (async-callstack-async-await3.js:47)
+    0) testFunction (async-callstack-async-await3.js:50)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3.js
index 663d3cf5..bc5d0c3 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3.js
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for async functions.\n`);
 
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
     function timeoutPromise(value, ms)
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception-expected.txt
index 810f2c2..bbb2d1a 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception-expected.txt
@@ -3,7 +3,7 @@
 === Pausing only on uncaught exceptions ===
 Set timer for test function.
 Call stack:
-    0) testFunction (async-pause-on-exception.js:41)
+    0) testFunction (async-pause-on-exception.js:44)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
@@ -12,13 +12,13 @@
 === Pausing on all exceptions ===
 Set timer for test function.
 Call stack:
-    0) testFunction (async-pause-on-exception.js:40)
+    0) testFunction (async-pause-on-exception.js:43)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 Paused on promise rejectionError: caught
 Call stack:
-    0) testFunction (async-pause-on-exception.js:41)
+    0) testFunction (async-pause-on-exception.js:44)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js
index 29a9d340..80a1332 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests that pause on promise rejection works.\n`);
 
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
     function createPromise()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-events-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-events-expected.txt
index edc18fc..49c0d33 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-events-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-events-expected.txt
@@ -3,38 +3,38 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) onHashChange1 (async-callstack-events.js:61)
+    0) onHashChange1 (async-callstack-events.js:64)
     [hashchange]
-    0) doTestHashChange (async-callstack-events.js:55)
-    1) testFunction (async-callstack-events.js:20)
+    0) doTestHashChange (async-callstack-events.js:58)
+    1) testFunction (async-callstack-events.js:23)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onHashChange2 (async-callstack-events.js:67)
+    0) onHashChange2 (async-callstack-events.js:70)
     [hashchange]
-    0) doTestHashChange (async-callstack-events.js:55)
-    1) testFunction (async-callstack-events.js:20)
+    0) doTestHashChange (async-callstack-events.js:58)
+    1) testFunction (async-callstack-events.js:23)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onSelectionChange (async-callstack-events.js:48)
+    0) onSelectionChange (async-callstack-events.js:51)
     [selectionchange]
-    0) setSelection (async-callstack-events.js:33)
-    1) doTestSelectionChange (async-callstack-events.js:40)
-    2) testFunction (async-callstack-events.js:20)
+    0) setSelection (async-callstack-events.js:36)
+    1) doTestSelectionChange (async-callstack-events.js:43)
+    2) testFunction (async-callstack-events.js:23)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onVideoPlay (async-callstack-events.js:80)
+    0) onVideoPlay (async-callstack-events.js:83)
     [play]
-    0) doTestMediaEvents (async-callstack-events.js:74)
-    1) testFunction (async-callstack-events.js:20)
+    0) doTestMediaEvents (async-callstack-events.js:77)
+    1) testFunction (async-callstack-events.js:23)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-events.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-events.js
index deea698..a04f57b7 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-events.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-events.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for various DOM events.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.loadHTML(`
       <video id="video" src="../../../media/resources/test.ogv"></video>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-expected.txt
index 49c7392..55c3986 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-expected.txt
@@ -3,66 +3,66 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) animFrame1 (async-callstack.js:34)
+    0) animFrame1 (async-callstack.js:37)
     [requestAnimationFrame]
-    0) timeout1 (async-callstack.js:22)
-    1) innerTestFunction (async-callstack.js:14)
+    0) timeout1 (async-callstack.js:25)
+    1) innerTestFunction (async-callstack.js:17)
     [setTimeout]
-    0) testFunction (async-callstack.js:16)
+    0) testFunction (async-callstack.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) animFrame2 (async-callstack.js:51)
+    0) animFrame2 (async-callstack.js:54)
     [requestAnimationFrame]
-    0) animFrame1 (async-callstack.js:36)
+    0) animFrame1 (async-callstack.js:39)
     [requestAnimationFrame]
-    0) timeout1 (async-callstack.js:22)
-    1) innerTestFunction (async-callstack.js:14)
+    0) timeout1 (async-callstack.js:25)
+    1) innerTestFunction (async-callstack.js:17)
     [setTimeout]
-    0) testFunction (async-callstack.js:16)
+    0) testFunction (async-callstack.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) interval1 (async-callstack.js:41)
-    1) innerInterval1 (async-callstack.js:27)
+    0) interval1 (async-callstack.js:44)
+    1) innerInterval1 (async-callstack.js:30)
     [setInterval]
-    0) timeout1 (async-callstack.js:23)
-    1) innerTestFunction (async-callstack.js:14)
+    0) timeout1 (async-callstack.js:26)
+    1) innerTestFunction (async-callstack.js:17)
     [setTimeout]
-    0) testFunction (async-callstack.js:16)
+    0) testFunction (async-callstack.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) timeout1 (async-callstack.js:21)
-    1) innerTestFunction (async-callstack.js:14)
+    0) timeout1 (async-callstack.js:24)
+    1) innerTestFunction (async-callstack.js:17)
     [setTimeout]
-    0) testFunction (async-callstack.js:16)
+    0) testFunction (async-callstack.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) timeout2 (async-callstack.js:46)
+    0) timeout2 (async-callstack.js:49)
     [setTimeout]
-    0) animFrame1 (async-callstack.js:35)
+    0) animFrame1 (async-callstack.js:38)
     [requestAnimationFrame]
-    0) timeout1 (async-callstack.js:22)
-    1) innerTestFunction (async-callstack.js:14)
+    0) timeout1 (async-callstack.js:25)
+    1) innerTestFunction (async-callstack.js:17)
     [setTimeout]
-    0) testFunction (async-callstack.js:16)
+    0) testFunction (async-callstack.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) timeout3 (async-callstack.js:65)
-    1) longTail0 (async-callstack.js:54)
+    0) timeout3 (async-callstack.js:68)
+    1) longTail0 (async-callstack.js:57)
     [setTimeout]
     0) longTail1 (:1)
     [setTimeout]
@@ -105,14 +105,14 @@
     0) longTail20 (:20)
     [setTimeout]
     0) eval (:21)
-    1) animFrame2 (async-callstack.js:60)
+    1) animFrame2 (async-callstack.js:63)
     [requestAnimationFrame]
-    0) animFrame1 (async-callstack.js:36)
+    0) animFrame1 (async-callstack.js:39)
     [requestAnimationFrame]
-    0) timeout1 (async-callstack.js:22)
-    1) innerTestFunction (async-callstack.js:14)
+    0) timeout1 (async-callstack.js:25)
+    1) innerTestFunction (async-callstack.js:17)
     [setTimeout]
-    0) testFunction (async-callstack.js:16)
+    0) testFunction (async-callstack.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-get-as-string-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-get-as-string-expected.txt
index cf25873..830759fc 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-get-as-string-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-get-as-string-expected.txt
@@ -3,21 +3,21 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) onGetAsString (async-callstack-get-as-string.js:44)
+    0) onGetAsString (async-callstack-get-as-string.js:47)
     [DataTransferItem.getAsString]
-    0) onPaste (async-callstack-get-as-string.js:39)
-    1) timeout (async-callstack-get-as-string.js:30)
+    0) onPaste (async-callstack-get-as-string.js:42)
+    1) timeout (async-callstack-get-as-string.js:33)
     [setTimeout]
-    0) testFunction (async-callstack-get-as-string.js:15)
+    0) testFunction (async-callstack-get-as-string.js:18)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onPaste (async-callstack-get-as-string.js:35)
-    1) timeout (async-callstack-get-as-string.js:30)
+    0) onPaste (async-callstack-get-as-string.js:38)
+    1) timeout (async-callstack-get-as-string.js:33)
     [setTimeout]
-    0) testFunction (async-callstack-get-as-string.js:15)
+    0) testFunction (async-callstack-get-as-string.js:18)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-get-as-string.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-get-as-string.js
index b4974b0..406895b1 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-get-as-string.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-get-as-string.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for DataTransferItem.getAsString.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.loadHTML(`
       <input type="text" id="input">
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console-expected.txt
index 375ec463..f3217c7 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console-expected.txt
@@ -1,56 +1,56 @@
 Tests asynchronous call stacks printed in console.
 
 Set timer for test function.
-async-callstack-in-console.js:18 Console was cleared
-async-callstack-in-console.js:24 console.trace
+async-callstack-in-console.js:22 Console was cleared
+async-callstack-in-console.js:28 console.trace
 
-timeout1 @ async-callstack-in-console.js:24
+timeout1 @ async-callstack-in-console.js:28
 
 setTimeout (async)
 
-testFunction @ async-callstack-in-console.js:19
-async-callstack-in-console.js:31 Uncaught Error: foo
-    at timeout2 (async-callstack-in-console.js:31:17)
+testFunction @ async-callstack-in-console.js:23
+async-callstack-in-console.js:35 Uncaught Error: foo
+    at timeout2 (async-callstack-in-console.js:35:17)
 
-timeout2 @ async-callstack-in-console.js:31
+timeout2 @ async-callstack-in-console.js:35
 
 setTimeout (async)
 
-timeout1 @ async-callstack-in-console.js:25
+timeout1 @ async-callstack-in-console.js:29
 
 setTimeout (async)
 
-testFunction @ async-callstack-in-console.js:19
-async-callstack-in-console.js:36 console.trace
+testFunction @ async-callstack-in-console.js:23
+async-callstack-in-console.js:40 console.trace
 
-timeout3 @ async-callstack-in-console.js:36
+timeout3 @ async-callstack-in-console.js:40
 
 setTimeout (async)
 
-timeout2 @ async-callstack-in-console.js:30
+timeout2 @ async-callstack-in-console.js:34
 
 setTimeout (async)
 
-timeout1 @ async-callstack-in-console.js:25
+timeout1 @ async-callstack-in-console.js:29
 
 setTimeout (async)
 
-testFunction @ async-callstack-in-console.js:19
-async-callstack-in-console.js:44 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://www.example.com') does not match the recipient window's origin ('http://127.0.0.1:8000').
+testFunction @ async-callstack-in-console.js:23
+async-callstack-in-console.js:48 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://www.example.com') does not match the recipient window's origin ('http://127.0.0.1:8000').
 
-tryPostMessage @ async-callstack-in-console.js:44
+tryPostMessage @ async-callstack-in-console.js:48
 
-timeout3 @ async-callstack-in-console.js:38
+timeout3 @ async-callstack-in-console.js:42
 
 setTimeout (async)
 
-timeout2 @ async-callstack-in-console.js:30
+timeout2 @ async-callstack-in-console.js:34
 
 setTimeout (async)
 
-timeout1 @ async-callstack-in-console.js:25
+timeout1 @ async-callstack-in-console.js:29
 
 setTimeout (async)
 
-testFunction @ async-callstack-in-console.js:19
+testFunction @ async-callstack-in-console.js:23
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console.js
index b0b114d..35f33aa 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console.js
@@ -2,10 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+import {ConsoleTestRunner} from 'console_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks printed in console.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
-  await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner');
+  await TestRunner.loadLegacyModule('sources');
+  await TestRunner.loadLegacyModule('console');
   await TestRunner.showPanel('sources');
   await TestRunner.loadHTML(`
       <div><iframe src="../debugger/resources/post-message-listener.html" id="iframe" width="800" height="100" style="border: 1px solid black;">
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-indexed-db-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-indexed-db-expected.txt
index 0dc595c..a8ec079 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-indexed-db-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-indexed-db-expected.txt
@@ -3,91 +3,91 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) onSuccessCursorRequest (async-callstack-indexed-db.js:81)
+    0) onSuccessCursorRequest (async-callstack-indexed-db.js:84)
     [IndexedDB]
-    0) getAllItems (async-callstack-indexed-db.js:74)
-    1) onSuccessStorePut (async-callstack-indexed-db.js:66)
+    0) getAllItems (async-callstack-indexed-db.js:77)
+    1) onSuccessStorePut (async-callstack-indexed-db.js:69)
     [IndexedDB]
-    0) populateDB (async-callstack-indexed-db.js:58)
-    1) onSuccessOpenDB (async-callstack-indexed-db.js:51)
+    0) populateDB (async-callstack-indexed-db.js:61)
+    1) onSuccessOpenDB (async-callstack-indexed-db.js:54)
     [IndexedDB]
-    0) openDB (async-callstack-indexed-db.js:29)
+    0) openDB (async-callstack-indexed-db.js:32)
     [setTimeout]
-    0) testFunction (async-callstack-indexed-db.js:18)
+    0) testFunction (async-callstack-indexed-db.js:21)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onSuccessDeleteDatabase (async-callstack-indexed-db.js:110)
+    0) onSuccessDeleteDatabase (async-callstack-indexed-db.js:113)
     [IndexedDB]
-    0) deleteDB (async-callstack-indexed-db.js:103)
-    1) onSuccessDeleteItem (async-callstack-indexed-db.js:97)
+    0) deleteDB (async-callstack-indexed-db.js:106)
+    1) onSuccessDeleteItem (async-callstack-indexed-db.js:100)
     [IndexedDB]
-    0) deleteItem (async-callstack-indexed-db.js:89)
-    1) onSuccessCursorRequest (async-callstack-indexed-db.js:82)
+    0) deleteItem (async-callstack-indexed-db.js:92)
+    1) onSuccessCursorRequest (async-callstack-indexed-db.js:85)
     [IndexedDB]
-    0) getAllItems (async-callstack-indexed-db.js:74)
-    1) onSuccessStorePut (async-callstack-indexed-db.js:66)
+    0) getAllItems (async-callstack-indexed-db.js:77)
+    1) onSuccessStorePut (async-callstack-indexed-db.js:69)
     [IndexedDB]
-    0) populateDB (async-callstack-indexed-db.js:58)
-    1) onSuccessOpenDB (async-callstack-indexed-db.js:51)
+    0) populateDB (async-callstack-indexed-db.js:61)
+    1) onSuccessOpenDB (async-callstack-indexed-db.js:54)
     [IndexedDB]
-    0) openDB (async-callstack-indexed-db.js:29)
+    0) openDB (async-callstack-indexed-db.js:32)
     [setTimeout]
-    0) testFunction (async-callstack-indexed-db.js:18)
+    0) testFunction (async-callstack-indexed-db.js:21)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onSuccessDeleteItem (async-callstack-indexed-db.js:96)
+    0) onSuccessDeleteItem (async-callstack-indexed-db.js:99)
     [IndexedDB]
-    0) deleteItem (async-callstack-indexed-db.js:89)
-    1) onSuccessCursorRequest (async-callstack-indexed-db.js:82)
+    0) deleteItem (async-callstack-indexed-db.js:92)
+    1) onSuccessCursorRequest (async-callstack-indexed-db.js:85)
     [IndexedDB]
-    0) getAllItems (async-callstack-indexed-db.js:74)
-    1) onSuccessStorePut (async-callstack-indexed-db.js:66)
+    0) getAllItems (async-callstack-indexed-db.js:77)
+    1) onSuccessStorePut (async-callstack-indexed-db.js:69)
     [IndexedDB]
-    0) populateDB (async-callstack-indexed-db.js:58)
-    1) onSuccessOpenDB (async-callstack-indexed-db.js:51)
+    0) populateDB (async-callstack-indexed-db.js:61)
+    1) onSuccessOpenDB (async-callstack-indexed-db.js:54)
     [IndexedDB]
-    0) openDB (async-callstack-indexed-db.js:29)
+    0) openDB (async-callstack-indexed-db.js:32)
     [setTimeout]
-    0) testFunction (async-callstack-indexed-db.js:18)
+    0) testFunction (async-callstack-indexed-db.js:21)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onSuccessOpenDB (async-callstack-indexed-db.js:49)
+    0) onSuccessOpenDB (async-callstack-indexed-db.js:52)
     [IndexedDB]
-    0) openDB (async-callstack-indexed-db.js:29)
+    0) openDB (async-callstack-indexed-db.js:32)
     [setTimeout]
-    0) testFunction (async-callstack-indexed-db.js:18)
+    0) testFunction (async-callstack-indexed-db.js:21)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onSuccessStorePut (async-callstack-indexed-db.js:65)
+    0) onSuccessStorePut (async-callstack-indexed-db.js:68)
     [IndexedDB]
-    0) populateDB (async-callstack-indexed-db.js:58)
-    1) onSuccessOpenDB (async-callstack-indexed-db.js:51)
+    0) populateDB (async-callstack-indexed-db.js:61)
+    1) onSuccessOpenDB (async-callstack-indexed-db.js:54)
     [IndexedDB]
-    0) openDB (async-callstack-indexed-db.js:29)
+    0) openDB (async-callstack-indexed-db.js:32)
     [setTimeout]
-    0) testFunction (async-callstack-indexed-db.js:18)
+    0) testFunction (async-callstack-indexed-db.js:21)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onUpgradeNeeded (async-callstack-indexed-db.js:37)
+    0) onUpgradeNeeded (async-callstack-indexed-db.js:40)
     [IndexedDB]
-    0) openDB (async-callstack-indexed-db.js:29)
+    0) openDB (async-callstack-indexed-db.js:32)
     [setTimeout]
-    0) testFunction (async-callstack-indexed-db.js:18)
+    0) testFunction (async-callstack-indexed-db.js:21)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-indexed-db.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-indexed-db.js
index 715c32a..75e639d 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-indexed-db.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-indexed-db.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for IndexedDB.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.loadHTML(`
       <input type="button" onclick="testFunction()" value="Test">
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-middle-run-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-middle-run-expected.txt
index 5ac3ed9e..5386af878 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-middle-run-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-middle-run-expected.txt
@@ -3,11 +3,11 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) timeoutOffCapturing2 (async-callstack-middle-run.js:25)
+    0) timeoutOffCapturing2 (async-callstack-middle-run.js:28)
 
 Call stack:
-    0) timeoutOnCapturing (async-callstack-middle-run.js:30)
+    0) timeoutOnCapturing (async-callstack-middle-run.js:33)
     [setTimeout]
-    0) timeoutOffCapturing (async-callstack-middle-run.js:20)
+    0) timeoutOffCapturing (async-callstack-middle-run.js:23)
 
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-middle-run.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-middle-run.js
index c92ed08..9f8e87e 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-middle-run.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-middle-run.js
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(
       `Tests that capturing asynchronous call stacks in debugger works if started after some time since the page loads.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
       function testFunction()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-mutation-observer-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-mutation-observer-expected.txt
index 8bc750b..a803f46 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-mutation-observer-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-mutation-observer-expected.txt
@@ -3,87 +3,87 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) mutationCallback (async-callstack-mutation-observer.js:24)
+    0) mutationCallback (async-callstack-mutation-observer.js:27)
     [attributes]
-    0) doMutations1 (async-callstack-mutation-observer.js:53)
-    1) timeout1 (async-callstack-mutation-observer.js:47)
+    0) doMutations1 (async-callstack-mutation-observer.js:56)
+    1) timeout1 (async-callstack-mutation-observer.js:50)
     [setTimeout]
-    0) testFunction (async-callstack-mutation-observer.js:38)
+    0) testFunction (async-callstack-mutation-observer.js:41)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) mutationCallback (async-callstack-mutation-observer.js:24)
+    0) mutationCallback (async-callstack-mutation-observer.js:27)
     [childList]
-    0) doMutations2 (async-callstack-mutation-observer.js:67)
-    1) timeout2 (async-callstack-mutation-observer.js:60)
+    0) doMutations2 (async-callstack-mutation-observer.js:70)
+    1) timeout2 (async-callstack-mutation-observer.js:63)
     [setTimeout]
-    0) timeout1 (async-callstack-mutation-observer.js:46)
+    0) timeout1 (async-callstack-mutation-observer.js:49)
     [setTimeout]
-    0) testFunction (async-callstack-mutation-observer.js:38)
+    0) testFunction (async-callstack-mutation-observer.js:41)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) nestedMutationCallback (async-callstack-mutation-observer.js:31)
+    0) nestedMutationCallback (async-callstack-mutation-observer.js:34)
     [attributes]
-    0) doMutations1 (async-callstack-mutation-observer.js:53)
-    1) mutationCallback (async-callstack-mutation-observer.js:23)
+    0) doMutations1 (async-callstack-mutation-observer.js:56)
+    1) mutationCallback (async-callstack-mutation-observer.js:26)
     [attributes]
-    0) doMutations1 (async-callstack-mutation-observer.js:53)
-    1) timeout1 (async-callstack-mutation-observer.js:47)
+    0) doMutations1 (async-callstack-mutation-observer.js:56)
+    1) timeout1 (async-callstack-mutation-observer.js:50)
     [setTimeout]
-    0) testFunction (async-callstack-mutation-observer.js:38)
+    0) testFunction (async-callstack-mutation-observer.js:41)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) nestedMutationCallback (async-callstack-mutation-observer.js:31)
+    0) nestedMutationCallback (async-callstack-mutation-observer.js:34)
     [childList]
-    0) doMutations2 (async-callstack-mutation-observer.js:67)
-    1) timeoutFromNestedMutation (async-callstack-mutation-observer.js:79)
+    0) doMutations2 (async-callstack-mutation-observer.js:70)
+    1) timeoutFromNestedMutation (async-callstack-mutation-observer.js:82)
     [setTimeout]
-    0) nestedMutationCallback (async-callstack-mutation-observer.js:33)
+    0) nestedMutationCallback (async-callstack-mutation-observer.js:36)
     [attributes]
-    0) doMutations1 (async-callstack-mutation-observer.js:53)
-    1) mutationCallback (async-callstack-mutation-observer.js:23)
+    0) doMutations1 (async-callstack-mutation-observer.js:56)
+    1) mutationCallback (async-callstack-mutation-observer.js:26)
     [attributes]
-    0) doMutations1 (async-callstack-mutation-observer.js:53)
-    1) timeout1 (async-callstack-mutation-observer.js:47)
+    0) doMutations1 (async-callstack-mutation-observer.js:56)
+    1) timeout1 (async-callstack-mutation-observer.js:50)
     [setTimeout]
-    0) testFunction (async-callstack-mutation-observer.js:38)
+    0) testFunction (async-callstack-mutation-observer.js:41)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) timeoutFromMutation (async-callstack-mutation-observer.js:73)
+    0) timeoutFromMutation (async-callstack-mutation-observer.js:76)
     [setTimeout]
-    0) mutationCallback (async-callstack-mutation-observer.js:26)
+    0) mutationCallback (async-callstack-mutation-observer.js:29)
     [attributes]
-    0) doMutations1 (async-callstack-mutation-observer.js:53)
-    1) timeout1 (async-callstack-mutation-observer.js:47)
+    0) doMutations1 (async-callstack-mutation-observer.js:56)
+    1) timeout1 (async-callstack-mutation-observer.js:50)
     [setTimeout]
-    0) testFunction (async-callstack-mutation-observer.js:38)
+    0) testFunction (async-callstack-mutation-observer.js:41)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) timeoutFromNestedMutation (async-callstack-mutation-observer.js:78)
+    0) timeoutFromNestedMutation (async-callstack-mutation-observer.js:81)
     [setTimeout]
-    0) nestedMutationCallback (async-callstack-mutation-observer.js:33)
+    0) nestedMutationCallback (async-callstack-mutation-observer.js:36)
     [attributes]
-    0) doMutations1 (async-callstack-mutation-observer.js:53)
-    1) mutationCallback (async-callstack-mutation-observer.js:23)
+    0) doMutations1 (async-callstack-mutation-observer.js:56)
+    1) mutationCallback (async-callstack-mutation-observer.js:26)
     [attributes]
-    0) doMutations1 (async-callstack-mutation-observer.js:53)
-    1) timeout1 (async-callstack-mutation-observer.js:47)
+    0) doMutations1 (async-callstack-mutation-observer.js:56)
+    1) timeout1 (async-callstack-mutation-observer.js:50)
     [setTimeout]
-    0) testFunction (async-callstack-mutation-observer.js:38)
+    0) testFunction (async-callstack-mutation-observer.js:41)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-mutation-observer.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-mutation-observer.js
index 065034c..546c9f2 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-mutation-observer.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-mutation-observer.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for MutationObserver.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
       var node = document.createElement("div");
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-post-message-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-post-message-expected.txt
index f9ae734..c8b7fde 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-post-message-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-post-message-expected.txt
@@ -5,16 +5,16 @@
 Call stack:
     0) onMessageReceivedInFrame (post-message-listener.html:7)
     [postMessage]
-    0) postMessageToFrame (async-callstack-post-message.js:42)
-    1) onMessageReceivedInParent (async-callstack-post-message.js:30)
+    0) postMessageToFrame (async-callstack-post-message.js:45)
+    1) onMessageReceivedInParent (async-callstack-post-message.js:33)
     [postMessage]
     0) postMessageToParent (post-message-listener.html:13)
     1) onMessageReceivedInFrame (post-message-listener.html:8)
     [postMessage]
-    0) postMessageToFrame (async-callstack-post-message.js:42)
-    1) timeout (async-callstack-post-message.js:23)
+    0) postMessageToFrame (async-callstack-post-message.js:45)
+    1) timeout (async-callstack-post-message.js:26)
     [setTimeout]
-    0) testFunction (async-callstack-post-message.js:16)
+    0) testFunction (async-callstack-post-message.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
@@ -22,55 +22,55 @@
 Call stack:
     0) onMessageReceivedInFrame (post-message-listener.html:7)
     [postMessage]
-    0) postMessageToFrame (async-callstack-post-message.js:42)
-    1) timeout (async-callstack-post-message.js:23)
+    0) postMessageToFrame (async-callstack-post-message.js:45)
+    1) timeout (async-callstack-post-message.js:26)
     [setTimeout]
-    0) testFunction (async-callstack-post-message.js:16)
+    0) testFunction (async-callstack-post-message.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onMessageReceivedInParent (async-callstack-post-message.js:28)
+    0) onMessageReceivedInParent (async-callstack-post-message.js:31)
     [postMessage]
     0) postMessageToParent (post-message-listener.html:13)
     1) onMessageReceivedInFrame (post-message-listener.html:8)
     [postMessage]
-    0) postMessageToFrame (async-callstack-post-message.js:42)
-    1) onMessageReceivedInParent (async-callstack-post-message.js:30)
+    0) postMessageToFrame (async-callstack-post-message.js:45)
+    1) onMessageReceivedInParent (async-callstack-post-message.js:33)
     [postMessage]
     0) postMessageToParent (post-message-listener.html:13)
     1) onMessageReceivedInFrame (post-message-listener.html:8)
     [postMessage]
-    0) postMessageToFrame (async-callstack-post-message.js:42)
-    1) timeout (async-callstack-post-message.js:23)
+    0) postMessageToFrame (async-callstack-post-message.js:45)
+    1) timeout (async-callstack-post-message.js:26)
     [setTimeout]
-    0) testFunction (async-callstack-post-message.js:16)
+    0) testFunction (async-callstack-post-message.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onMessageReceivedInParent (async-callstack-post-message.js:28)
+    0) onMessageReceivedInParent (async-callstack-post-message.js:31)
     [postMessage]
     0) postMessageToParent (post-message-listener.html:13)
     1) onMessageReceivedInFrame (post-message-listener.html:8)
     [postMessage]
-    0) postMessageToFrame (async-callstack-post-message.js:42)
-    1) timeout (async-callstack-post-message.js:23)
+    0) postMessageToFrame (async-callstack-post-message.js:45)
+    1) timeout (async-callstack-post-message.js:26)
     [setTimeout]
-    0) testFunction (async-callstack-post-message.js:16)
+    0) testFunction (async-callstack-post-message.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onMessageReceivedInParent (async-callstack-post-message.js:28)
+    0) onMessageReceivedInParent (async-callstack-post-message.js:31)
     [postMessage]
-    0) postMessageToSelf (async-callstack-post-message.js:35)
-    1) timeout (async-callstack-post-message.js:22)
+    0) postMessageToSelf (async-callstack-post-message.js:38)
+    1) timeout (async-callstack-post-message.js:25)
     [setTimeout]
-    0) testFunction (async-callstack-post-message.js:16)
+    0) testFunction (async-callstack-post-message.js:19)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-post-message.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-post-message.js
index aa7f7b1..6ed440d90 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-post-message.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-post-message.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for window.postMessage.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.loadHTML(`
       <div><iframe src="../debugger/resources/post-message-listener.html" id="iframe" width="800" height="100" style="border: 1px solid black;">
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-promises-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-promises-expected.txt
index 7259d97..f5124d5d 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-promises-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-promises-expected.txt
@@ -3,154 +3,154 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) afterJSONStringifyAndParse (async-callstack-promises.js:100)
+    0) afterJSONStringifyAndParse (async-callstack-promises.js:103)
     [Promise.then]
-    0) doTestChainedPromises (async-callstack-promises.js:99)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    0) doTestChainedPromises (async-callstack-promises.js:102)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) catchCallback (async-callstack-promises.js:121)
+    0) catchCallback (async-callstack-promises.js:124)
     [Promise.catch]
-    0) doTestThrowFromChain (async-callstack-promises.js:120)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    0) doTestThrowFromChain (async-callstack-promises.js:123)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) catchCallback (async-callstack-promises.js:133)
+    0) catchCallback (async-callstack-promises.js:136)
     [Promise.catch]
-    0) doTestThrowFromChain (async-callstack-promises.js:132)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    0) doTestThrowFromChain (async-callstack-promises.js:135)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) chained1 (async-callstack-promises.js:83)
-    [Promise.then]
-    0) doTestChainedPromises (async-callstack-promises.js:82)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
-    [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
-    [setTimeout]
-    0) scheduleTestFunction <omitted>
-    <... skipped remaining frames ...>
-
-Call stack:
-    0) chained2 (async-callstack-promises.js:86)
+    0) chained1 (async-callstack-promises.js:86)
     [Promise.then]
     0) doTestChainedPromises (async-callstack-promises.js:85)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) chained3 (async-callstack-promises.js:89)
+    0) chained2 (async-callstack-promises.js:89)
     [Promise.then]
     0) doTestChainedPromises (async-callstack-promises.js:88)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) chained4 (async-callstack-promises.js:92)
+    0) chained3 (async-callstack-promises.js:92)
     [Promise.then]
     0) doTestChainedPromises (async-callstack-promises.js:91)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) errorCallback (async-callstack-promises.js:63)
-    [Promise.then]
-    0) doTestPromiseResolveAndReject (async-callstack-promises.js:140)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
-    [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
-    [setTimeout]
-    0) scheduleTestFunction <omitted>
-    <... skipped remaining frames ...>
-
-Call stack:
-    0) errorCallback (async-callstack-promises.js:63)
-    [Promise.then]
-    0) doTestSettledPromises (async-callstack-promises.js:77)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
-    [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
-    [setTimeout]
-    0) scheduleTestFunction <omitted>
-    <... skipped remaining frames ...>
-
-Call stack:
-    0) promiseCallback (async-callstack-promises.js:70)
-    1) doTestPromiseConstructor (async-callstack-promises.js:68)
-    2) testFunctionTimeout (async-callstack-promises.js:53)
-    [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
-    [setTimeout]
-    0) scheduleTestFunction <omitted>
-    <... skipped remaining frames ...>
-
-Call stack:
-    0) thenCallback (async-callstack-promises.js:58)
+    0) chained4 (async-callstack-promises.js:95)
     [Promise.then]
     0) doTestChainedPromises (async-callstack-promises.js:94)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-promises.js:58)
+    0) errorCallback (async-callstack-promises.js:66)
     [Promise.then]
-    0) doTestPromiseAll (async-callstack-promises.js:107)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    0) doTestPromiseResolveAndReject (async-callstack-promises.js:143)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-promises.js:58)
+    0) errorCallback (async-callstack-promises.js:66)
     [Promise.then]
-    0) doTestPromiseResolveAndReject (async-callstack-promises.js:139)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    0) doTestSettledPromises (async-callstack-promises.js:80)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) thenCallback (async-callstack-promises.js:58)
-    [Promise.then]
-    0) doTestSettledPromises (async-callstack-promises.js:76)
-    1) testFunctionTimeout (async-callstack-promises.js:53)
+    0) promiseCallback (async-callstack-promises.js:73)
+    1) doTestPromiseConstructor (async-callstack-promises.js:71)
+    2) testFunctionTimeout (async-callstack-promises.js:56)
     [setTimeout]
-    0) testFunction (async-callstack-promises.js:46)
+    0) testFunction (async-callstack-promises.js:49)
+    [setTimeout]
+    0) scheduleTestFunction <omitted>
+    <... skipped remaining frames ...>
+
+Call stack:
+    0) thenCallback (async-callstack-promises.js:61)
+    [Promise.then]
+    0) doTestChainedPromises (async-callstack-promises.js:97)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
+    [setTimeout]
+    0) testFunction (async-callstack-promises.js:49)
+    [setTimeout]
+    0) scheduleTestFunction <omitted>
+    <... skipped remaining frames ...>
+
+Call stack:
+    0) thenCallback (async-callstack-promises.js:61)
+    [Promise.then]
+    0) doTestPromiseAll (async-callstack-promises.js:110)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
+    [setTimeout]
+    0) testFunction (async-callstack-promises.js:49)
+    [setTimeout]
+    0) scheduleTestFunction <omitted>
+    <... skipped remaining frames ...>
+
+Call stack:
+    0) thenCallback (async-callstack-promises.js:61)
+    [Promise.then]
+    0) doTestPromiseResolveAndReject (async-callstack-promises.js:142)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
+    [setTimeout]
+    0) testFunction (async-callstack-promises.js:49)
+    [setTimeout]
+    0) scheduleTestFunction <omitted>
+    <... skipped remaining frames ...>
+
+Call stack:
+    0) thenCallback (async-callstack-promises.js:61)
+    [Promise.then]
+    0) doTestSettledPromises (async-callstack-promises.js:79)
+    1) testFunctionTimeout (async-callstack-promises.js:56)
+    [setTimeout]
+    0) testFunction (async-callstack-promises.js:49)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-promises.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-promises.js
index cb97127e..32aa488 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-promises.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-promises.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for Promises.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
       function timeoutPromise(value, ms)
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-reload-no-crash.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-reload-no-crash.js
index eadf52ba..cfe9c95 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-reload-no-crash.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-reload-no-crash.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests that page reload with async stacks turned on does not crash. Bug 441223.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
       function testFunction()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-scripted-scroll-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-scripted-scroll-expected.txt
index b4fe8ce7..4f7be45 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-scripted-scroll-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-scripted-scroll-expected.txt
@@ -3,21 +3,21 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) onScroll1 (async-callstack-scripted-scroll.js:35)
+    0) onScroll1 (async-callstack-scripted-scroll.js:38)
     [scroll]
-    0) timeout (async-callstack-scripted-scroll.js:27)
+    0) timeout (async-callstack-scripted-scroll.js:30)
     [setTimeout]
-    0) testFunction (async-callstack-scripted-scroll.js:18)
+    0) testFunction (async-callstack-scripted-scroll.js:21)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onScroll2 (async-callstack-scripted-scroll.js:42)
+    0) onScroll2 (async-callstack-scripted-scroll.js:45)
     [scroll]
-    0) timeout (async-callstack-scripted-scroll.js:27)
+    0) timeout (async-callstack-scripted-scroll.js:30)
     [setTimeout]
-    0) testFunction (async-callstack-scripted-scroll.js:18)
+    0) testFunction (async-callstack-scripted-scroll.js:21)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-scripted-scroll.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-scripted-scroll.js
index 4ac2d47..a05d5c4 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-scripted-scroll.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-scripted-scroll.js
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(
       `Tests asynchronous call stacks for scripted scroll events.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.loadHTML(`
       <div id="outer" style="width: 100px; height: 100px; overflow:auto">
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-set-interval-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-set-interval-expected.txt
index 296949ce..cd7334b 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-set-interval-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-set-interval-expected.txt
@@ -3,17 +3,9 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) callback (async-callstack-set-interval.js:21)
+    0) callback (async-callstack-set-interval.js:24)
     [setInterval]
-    0) testFunction (async-callstack-set-interval.js:15)
-    [setTimeout]
-    0) scheduleTestFunction <omitted>
-    <... skipped remaining frames ...>
-
-Call stack:
-    0) callback (async-callstack-set-interval.js:23)
-    [setInterval]
-    0) testFunction (async-callstack-set-interval.js:15)
+    0) testFunction (async-callstack-set-interval.js:18)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
@@ -21,7 +13,15 @@
 Call stack:
     0) callback (async-callstack-set-interval.js:26)
     [setInterval]
-    0) testFunction (async-callstack-set-interval.js:15)
+    0) testFunction (async-callstack-set-interval.js:18)
+    [setTimeout]
+    0) scheduleTestFunction <omitted>
+    <... skipped remaining frames ...>
+
+Call stack:
+    0) callback (async-callstack-set-interval.js:29)
+    [setInterval]
+    0) testFunction (async-callstack-set-interval.js:18)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-set-interval.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-set-interval.js
index a5dd94e..e50f245 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-set-interval.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-set-interval.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for setInterval.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
       var intervalId;
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-web-sql-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-web-sql-expected.txt
index 0db895a1..d764529f 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-web-sql-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-web-sql-expected.txt
@@ -3,57 +3,57 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) onCreateTableSQLTransactionCallback (async-callstack-web-sql.js:45)
-    [SQLTransaction]
-    0) openDB (async-callstack-web-sql.js:33)
-    [setTimeout]
-    0) testFunction (async-callstack-web-sql.js:15)
-    [setTimeout]
-    0) scheduleTestFunction <omitted>
-    <... skipped remaining frames ...>
-
-Call stack:
-    0) onDropTable (async-callstack-web-sql.js:53)
-    [SQLStatement]
     0) onCreateTableSQLTransactionCallback (async-callstack-web-sql.js:48)
     [SQLTransaction]
-    0) openDB (async-callstack-web-sql.js:33)
+    0) openDB (async-callstack-web-sql.js:36)
     [setTimeout]
-    0) testFunction (async-callstack-web-sql.js:15)
+    0) testFunction (async-callstack-web-sql.js:18)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onSuccess (async-callstack-web-sql.js:20)
+    0) onDropTable (async-callstack-web-sql.js:56)
     [SQLStatement]
-    0) onCreateTableSQLTransactionCallback (async-callstack-web-sql.js:46)
+    0) onCreateTableSQLTransactionCallback (async-callstack-web-sql.js:51)
     [SQLTransaction]
-    0) openDB (async-callstack-web-sql.js:33)
+    0) openDB (async-callstack-web-sql.js:36)
     [setTimeout]
-    0) testFunction (async-callstack-web-sql.js:15)
+    0) testFunction (async-callstack-web-sql.js:18)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onSuccess (async-callstack-web-sql.js:20)
+    0) onSuccess (async-callstack-web-sql.js:23)
     [SQLStatement]
-    0) onCreateTableSQLTransactionCallback (async-callstack-web-sql.js:47)
+    0) onCreateTableSQLTransactionCallback (async-callstack-web-sql.js:49)
     [SQLTransaction]
-    0) openDB (async-callstack-web-sql.js:33)
+    0) openDB (async-callstack-web-sql.js:36)
     [setTimeout]
-    0) testFunction (async-callstack-web-sql.js:15)
+    0) testFunction (async-callstack-web-sql.js:18)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) onSuccess (async-callstack-web-sql.js:20)
+    0) onSuccess (async-callstack-web-sql.js:23)
+    [SQLStatement]
+    0) onCreateTableSQLTransactionCallback (async-callstack-web-sql.js:50)
     [SQLTransaction]
-    0) openDB (async-callstack-web-sql.js:33)
+    0) openDB (async-callstack-web-sql.js:36)
     [setTimeout]
-    0) testFunction (async-callstack-web-sql.js:15)
+    0) testFunction (async-callstack-web-sql.js:18)
+    [setTimeout]
+    0) scheduleTestFunction <omitted>
+    <... skipped remaining frames ...>
+
+Call stack:
+    0) onSuccess (async-callstack-web-sql.js:23)
+    [SQLTransaction]
+    0) openDB (async-callstack-web-sql.js:36)
+    [setTimeout]
+    0) testFunction (async-callstack-web-sql.js:18)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-web-sql.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-web-sql.js
index 8408efe..b0ebf64 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-web-sql.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-web-sql.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for Web SQL.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.loadHTML(`
       <input type="button" onclick="testFunction()" value="Test">
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-xhrs-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-xhrs-expected.txt
index e6142aad..f3e7595 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-xhrs-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-xhrs-expected.txt
@@ -3,106 +3,106 @@
 Set timer for test function.
 Captured call stacks in no particular order:
 Call stack:
-    0) downloadEnd1 (async-callstack-xhrs.js:39)
-    1) sendXHR (async-callstack-xhrs.js:69)
-    2) sendSyncXHR (async-callstack-xhrs.js:24)
-    3) timeout (async-callstack-xhrs.js:19)
+    0) downloadEnd1 (async-callstack-xhrs.js:42)
+    1) sendXHR (async-callstack-xhrs.js:72)
+    2) sendSyncXHR (async-callstack-xhrs.js:27)
+    3) timeout (async-callstack-xhrs.js:22)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) downloadEnd1 (async-callstack-xhrs.js:39)
+    0) downloadEnd1 (async-callstack-xhrs.js:42)
     [XMLHttpRequest.send]
-    0) sendXHR (async-callstack-xhrs.js:69)
-    1) sendAsyncXHR (async-callstack-xhrs.js:23)
-    2) timeout (async-callstack-xhrs.js:20)
+    0) sendXHR (async-callstack-xhrs.js:72)
+    1) sendAsyncXHR (async-callstack-xhrs.js:26)
+    2) timeout (async-callstack-xhrs.js:23)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) downloadEnd2 (async-callstack-xhrs.js:44)
-    1) sendXHR (async-callstack-xhrs.js:69)
-    2) sendSyncXHR (async-callstack-xhrs.js:24)
-    3) timeout (async-callstack-xhrs.js:19)
+    0) downloadEnd2 (async-callstack-xhrs.js:47)
+    1) sendXHR (async-callstack-xhrs.js:72)
+    2) sendSyncXHR (async-callstack-xhrs.js:27)
+    3) timeout (async-callstack-xhrs.js:22)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) downloadEnd2 (async-callstack-xhrs.js:44)
+    0) downloadEnd2 (async-callstack-xhrs.js:47)
     [XMLHttpRequest.send]
-    0) sendXHR (async-callstack-xhrs.js:69)
-    1) sendAsyncXHR (async-callstack-xhrs.js:23)
-    2) timeout (async-callstack-xhrs.js:20)
+    0) sendXHR (async-callstack-xhrs.js:72)
+    1) sendAsyncXHR (async-callstack-xhrs.js:26)
+    2) timeout (async-callstack-xhrs.js:23)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) downloadProgress (async-callstack-xhrs.js:53)
+    0) downloadProgress (async-callstack-xhrs.js:56)
     [XMLHttpRequest.send]
-    0) sendXHR (async-callstack-xhrs.js:69)
-    1) sendAsyncXHR (async-callstack-xhrs.js:23)
-    2) timeout (async-callstack-xhrs.js:20)
+    0) sendXHR (async-callstack-xhrs.js:72)
+    1) sendAsyncXHR (async-callstack-xhrs.js:26)
+    2) timeout (async-callstack-xhrs.js:23)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) uploadEnd (async-callstack-xhrs.js:49)
+    0) uploadEnd (async-callstack-xhrs.js:52)
     [XMLHttpRequest.send]
-    0) sendXHR (async-callstack-xhrs.js:69)
-    1) sendAsyncXHR (async-callstack-xhrs.js:23)
-    2) timeout (async-callstack-xhrs.js:20)
+    0) sendXHR (async-callstack-xhrs.js:72)
+    1) sendAsyncXHR (async-callstack-xhrs.js:26)
+    2) timeout (async-callstack-xhrs.js:23)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) uploadProgress (async-callstack-xhrs.js:58)
+    0) uploadProgress (async-callstack-xhrs.js:61)
     [XMLHttpRequest.send]
-    0) sendXHR (async-callstack-xhrs.js:69)
-    1) sendAsyncXHR (async-callstack-xhrs.js:23)
-    2) timeout (async-callstack-xhrs.js:20)
+    0) sendXHR (async-callstack-xhrs.js:72)
+    1) sendAsyncXHR (async-callstack-xhrs.js:26)
+    2) timeout (async-callstack-xhrs.js:23)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) xhr.onreadystatechange (async-callstack-xhrs.js:33)
-    1) sendXHR (async-callstack-xhrs.js:69)
-    2) sendSyncXHR (async-callstack-xhrs.js:24)
-    3) timeout (async-callstack-xhrs.js:19)
+    0) xhr.onreadystatechange (async-callstack-xhrs.js:36)
+    1) sendXHR (async-callstack-xhrs.js:72)
+    2) sendSyncXHR (async-callstack-xhrs.js:27)
+    3) timeout (async-callstack-xhrs.js:22)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
 
 Call stack:
-    0) xhr.onreadystatechange (async-callstack-xhrs.js:33)
+    0) xhr.onreadystatechange (async-callstack-xhrs.js:36)
     [XMLHttpRequest.send]
-    0) sendXHR (async-callstack-xhrs.js:69)
-    1) sendAsyncXHR (async-callstack-xhrs.js:23)
-    2) timeout (async-callstack-xhrs.js:20)
+    0) sendXHR (async-callstack-xhrs.js:72)
+    1) sendAsyncXHR (async-callstack-xhrs.js:26)
+    2) timeout (async-callstack-xhrs.js:23)
     [setTimeout]
-    0) testFunction (async-callstack-xhrs.js:14)
+    0) testFunction (async-callstack-xhrs.js:17)
     [setTimeout]
     0) scheduleTestFunction <omitted>
     <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-xhrs.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-xhrs.js
index b11ec5d..1b91067 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-xhrs.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-xhrs.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks for XHRs.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
       var xhrCount = 0;
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack.js
index eeb9f66..1a080db 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack.js
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {TestRunner} from 'test_runner';
+import {SourcesTestRunner} from 'sources_test_runner';
+
 (async function() {
   TestRunner.addResult(`Tests asynchronous call stacks in debugger.\n`);
-  await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner');
+  await TestRunner.loadLegacyModule('sources');
   await TestRunner.showPanel('sources');
   await TestRunner.evaluateInPagePromise(`
       function testFunction()
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-expected.txt
index 5b670bdd..617f3aca 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 350 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 353 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-xhtml-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-xhtml-expected.txt
index 5b670bdd..617f3aca 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-xhtml-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 350 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 353 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git "a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
index e5b3b70..ab62516 100644
--- "a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 348 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 355 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
index e5b3b70..ab62516 100644
--- "a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 348 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 355 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
index 7f9ae15..65d411a3 100644
--- "a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 483 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 490 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -635,6 +635,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git "a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
index 7f9ae15..65d411a3 100644
--- "a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 483 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 490 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -635,6 +635,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any-expected.txt
index 27fc06d..37374fb 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 347 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 350 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any.worker-expected.txt
index 27fc06d..37374fb 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 347 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 350 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-origin-expected.txt
index c0397ff..73ffd2e 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-origin-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-origin-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 349 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 352 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-origin-xhtml-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-origin-xhtml-expected.txt
index c0397ff..73ffd2e 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-origin-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-origin-xhtml-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 349 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 352 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git "a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
index e943c6b3..46d6e39e 100644
--- "a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 347 PASS, 315 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 354 PASS, 315 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
index e943c6b3..46d6e39e 100644
--- "a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 347 PASS, 315 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 354 PASS, 315 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
index c50bb1f..b6188ce6 100644
--- "a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 482 PASS, 181 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 489 PASS, 181 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -635,6 +635,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git "a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
index c50bb1f..b6188ce6 100644
--- "a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 482 PASS, 181 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 489 PASS, 181 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -635,6 +635,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-origin.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-origin.any-expected.txt
index 6932c2f..7b87d4e 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-origin.any-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-origin.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 346 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 349 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-origin.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-origin.any.worker-expected.txt
index 6932c2f..7b87d4e 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-origin.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/idna-2008/external/wpt/url/url-origin.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 346 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 349 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-origin-expected.txt
index 5b670bdd..617f3aca 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-origin-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-origin-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 350 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 353 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-origin-xhtml-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-origin-xhtml-expected.txt
index 5b670bdd..617f3aca 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-origin-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-origin-xhtml-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 350 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 353 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git "a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
index 4ba61a7..2f31f4b 100644
--- "a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 348 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 355 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
index 4ba61a7..2f31f4b 100644
--- "a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 348 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 355 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
index 328e740..0127aa0 100644
--- "a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 487 PASS, 176 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 494 PASS, 176 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -627,6 +627,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git "a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
index 328e740..0127aa0 100644
--- "a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 487 PASS, 176 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 494 PASS, 176 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -627,6 +627,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-origin.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-origin.any-expected.txt
index 27fc06d..37374fb 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-origin.any-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-origin.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 347 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 350 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-origin.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-origin.any.worker-expected.txt
index 27fc06d..37374fb 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-origin.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/strict-ipv4-embedded-ipv6/external/wpt/url/url-origin.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 347 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 350 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git "a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
index e5b3b70..ab62516 100644
--- "a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 348 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 355 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
index e5b3b70..ab62516 100644
--- "a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 348 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 355 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-expected.txt
index 5b670bdd..617f3aca 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 350 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 353 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-xhtml-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-xhtml-expected.txt
index 5b670bdd..617f3aca 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-xhtml-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 350 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 353 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git "a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
index e5b3b70..ab62516 100644
--- "a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 348 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 355 PASS, 314 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
index 7f9ae15..65d411a3 100644
--- "a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 483 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 490 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -635,6 +635,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git "a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
index 7f9ae15..65d411a3 100644
--- "a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 483 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 490 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -635,6 +635,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any-expected.txt
index 27fc06d..37374fb 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 347 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 350 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any.worker-expected.txt
index 27fc06d..37374fb 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 347 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 350 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-expected.txt
index 7434769..bb11d00f 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 346 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 349 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-xhtml-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-xhtml-expected.txt
index 7434769..bb11d00f 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-xhtml-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 346 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 349 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing origin: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:> against <about:blank>
+PASS Parsing origin: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing origin: <blob:about:blank> against <about:blank>
+FAIL Parsing origin: <blob:file://host/path> against <about:blank> assert_equals: origin expected "null" but got "file://"
+FAIL Parsing origin: <blob:ftp://host/path> against <about:blank> assert_equals: origin expected "null" but got "ftp://host"
+FAIL Parsing origin: <blob:ws://example.org/> against <about:blank> assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Parsing origin: <blob:wss://example.org/> against <about:blank> assert_equals: origin expected "null" but got "wss://example.org"
 PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
 PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
 PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
diff --git "a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
index e15318cc..dd6f449 100644
--- "a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-xhtml_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 343 PASS, 319 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 350 PASS, 319 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
index e15318cc..dd6f449 100644
--- "a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 662 tests; 343 PASS, 319 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 669 tests; 350 PASS, 319 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -543,6 +543,13 @@
 PASS Parsing: <blob:https://example.com:443/> against <about:blank>
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
 PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <blob:blob:> against <about:blank>
+PASS Parsing: <blob:blob:https://example.org/> against <about:blank>
+PASS Parsing: <blob:about:blank> against <about:blank>
+PASS Parsing: <blob:file://host/path> against <about:blank>
+PASS Parsing: <blob:ftp://host/path> against <about:blank>
+PASS Parsing: <blob:ws://example.org/> against <about:blank>
+PASS Parsing: <blob:wss://example.org/> against <about:blank>
 PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
 PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
 FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
diff --git "a/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
index 8b06aea..c584aab40 100644
--- "a/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any.worker_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 474 PASS, 189 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 481 PASS, 189 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -639,6 +639,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git "a/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt" "b/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
index 8b06aea..c584aab40 100644
--- "a/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
+++ "b/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any_exclude=\050file_javascript_mailto\051-expected.txt"
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 663 tests; 474 PASS, 189 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 670 tests; 481 PASS, 189 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -639,6 +639,13 @@
 PASS Parsing: <blob:https://example.com:443/> without base
 PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Parsing: <blob:> without base
+PASS Parsing: <blob:blob:> without base
+PASS Parsing: <blob:blob:https://example.org/> without base
+PASS Parsing: <blob:about:blank> without base
+PASS Parsing: <blob:file://host/path> without base
+PASS Parsing: <blob:ftp://host/path> without base
+PASS Parsing: <blob:ws://example.org/> without base
+PASS Parsing: <blob:wss://example.org/> without base
 PASS Parsing: <http://0x7f.0.0.0x7g> without base
 PASS Parsing: <http://0X7F.0.0.0X7G> without base
 PASS Parsing: <http://[::127.0.0.0.1]> without base
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any-expected.txt
index 9eebec4..aee7d04 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 343 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 346 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any.worker-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any.worker-expected.txt
index 9eebec4..aee7d04 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 354 tests; 343 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 361 tests; 346 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Origin parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -325,6 +325,13 @@
 PASS Origin parsing: <blob:https://example.com:443/> without base
 PASS Origin parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> without base
 PASS Origin parsing: <blob:> without base
+PASS Origin parsing: <blob:blob:> without base
+PASS Origin parsing: <blob:blob:https://example.org/> without base
+PASS Origin parsing: <blob:about:blank> without base
+FAIL Origin parsing: <blob:file://host/path> without base assert_equals: origin expected "null" but got "file://"
+FAIL Origin parsing: <blob:ftp://host/path> without base assert_equals: origin expected "null" but got "ftp://host"
+FAIL Origin parsing: <blob:ws://example.org/> without base assert_equals: origin expected "null" but got "ws://example.org"
+FAIL Origin parsing: <blob:wss://example.org/> without base assert_equals: origin expected "null" but got "wss://example.org"
 PASS Origin parsing: <non-special:cannot-be-a-base-url-\0~€> without base
 PASS Origin parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> without base
 PASS Origin parsing: <https://user:pass[@foo/bar> against <http://example.org>
diff --git a/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt b/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
index e06db1d..28d5f490 100644
--- a/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
+++ b/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
@@ -321,6 +321,7 @@
 scroll-timeline-attachment: local
 scroll-timeline-axis: block
 scroll-timeline-name: none
+scrollbar-color: auto
 scrollbar-gutter: auto
 scrollbar-width: auto
 shape-image-threshold: 0
diff --git a/third_party/blink/web_tests/virtual/view-transition-mpa-serialization/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt b/third_party/blink/web_tests/virtual/view-transition-mpa-serialization/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt
new file mode 100644
index 0000000..fd1429b
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/view-transition-mpa-serialization/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt
@@ -0,0 +1,3606 @@
+The test verifies functionality of querying style information for view-transition pseudo elements
+{
+    id : <number>
+    result : {
+        cssKeyframesRules : [
+        ]
+        cssPositionFallbackRules : [
+        ]
+        inherited : [
+        ]
+        inheritedPseudoElements : [
+        ]
+        inlineStyle : {
+            cssProperties : [
+            ]
+            cssText : 
+            range : {
+                endColumn : 0
+                endLine : 0
+                startColumn : 0
+                startLine : 0
+            }
+            shorthandEntries : [
+            ]
+            styleSheetId : <string>
+        }
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html
+                            }
+                        ]
+                        text : html
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : display
+                                value : block
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 0
+                                }
+                                text : :root
+                            }
+                        ]
+                        text : :root
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : view-transition-name
+                                value : root
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+        ]
+        parentLayoutNodeId : 1
+        pseudoElements : [
+            [0] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition
+                                    }
+                                ]
+                                text : html::view-transition
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : fixed
+                                    }
+                                    [1] : {
+                                        name : top
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : right
+                                        value : 0px
+                                    }
+                                    [3] : {
+                                        name : bottom
+                                        value : 0px
+                                    }
+                                    [4] : {
+                                        name : left
+                                        value : 0px
+                                    }
+                                ]
+                                shorthandEntries : [
+                                    [0] : {
+                                        name : inset
+                                        value : 0px
+                                    }
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoType : view-transition
+            }
+            [1] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-group()
+                                    }
+                                ]
+                                text : html::view-transition-group()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : absolute
+                                    }
+                                    [1] : {
+                                        name : top
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : left
+                                        value : 0px
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [1] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-group()
+                                    }
+                                ]
+                                text : html::view-transition-group()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-duration
+                                        value : 0.25s
+                                    }
+                                    [1] : {
+                                        name : animation-fill-mode
+                                        value : both
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [2] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-group(root)
+                                    }
+                                ]
+                                text : html::view-transition-group(root)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : right
+                                        value : 0px
+                                    }
+                                    [1] : {
+                                        name : bottom
+                                        value : 0px
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoIdentifier : root
+                pseudoType : view-transition-group
+            }
+            [2] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-group()
+                                    }
+                                ]
+                                text : html::view-transition-group()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : absolute
+                                    }
+                                    [1] : {
+                                        name : top
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : left
+                                        value : 0px
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [1] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-group()
+                                    }
+                                ]
+                                text : html::view-transition-group()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-duration
+                                        value : 0.25s
+                                    }
+                                    [1] : {
+                                        name : animation-fill-mode
+                                        value : both
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [2] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-group(shared)
+                                    }
+                                ]
+                                text : html::view-transition-group(shared)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : width
+                                        value : 100px
+                                    }
+                                    [1] : {
+                                        name : height
+                                        value : 100px
+                                    }
+                                    [2] : {
+                                        name : transform
+                                        value : matrix(1, 0, 0, 1, 8, 8)
+                                    }
+                                    [3] : {
+                                        name : writing-mode
+                                        value : horizontal-tb
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [3] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-group(shared)
+                                    }
+                                ]
+                                text : html::view-transition-group(shared)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-name
+                                        value : -ua-view-transition-group-anim-shared
+                                    }
+                                    [1] : {
+                                        name : animation-timing-function
+                                        value : ease
+                                    }
+                                    [2] : {
+                                        name : animation-delay
+                                        value : 0s
+                                    }
+                                    [3] : {
+                                        name : animation-iteration-count
+                                        value : 1
+                                    }
+                                    [4] : {
+                                        name : animation-direction
+                                        value : normal
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoIdentifier : shared
+                pseudoType : view-transition-group
+            }
+            [3] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-image-pair()
+                                    }
+                                ]
+                                text : ::view-transition-image-pair()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : absolute
+                                    }
+                                    [1] : {
+                                        name : top
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : right
+                                        value : 0px
+                                    }
+                                    [3] : {
+                                        name : bottom
+                                        value : 0px
+                                    }
+                                    [4] : {
+                                        name : left
+                                        value : 0px
+                                    }
+                                ]
+                                shorthandEntries : [
+                                    [0] : {
+                                        name : inset
+                                        value : 0px
+                                    }
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [1] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-image-pair()
+                                    }
+                                ]
+                                text : html::view-transition-image-pair()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-duration
+                                        value : inherit
+                                    }
+                                    [1] : {
+                                        name : animation-fill-mode
+                                        value : inherit
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [2] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-image-pair(root)
+                                    }
+                                ]
+                                text : html::view-transition-image-pair(root)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : isolation
+                                        value : isolate
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoIdentifier : root
+                pseudoType : view-transition-image-pair
+            }
+            [4] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-image-pair()
+                                    }
+                                ]
+                                text : ::view-transition-image-pair()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : absolute
+                                    }
+                                    [1] : {
+                                        name : top
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : right
+                                        value : 0px
+                                    }
+                                    [3] : {
+                                        name : bottom
+                                        value : 0px
+                                    }
+                                    [4] : {
+                                        name : left
+                                        value : 0px
+                                    }
+                                ]
+                                shorthandEntries : [
+                                    [0] : {
+                                        name : inset
+                                        value : 0px
+                                    }
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [1] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-image-pair()
+                                    }
+                                ]
+                                text : html::view-transition-image-pair()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-duration
+                                        value : inherit
+                                    }
+                                    [1] : {
+                                        name : animation-fill-mode
+                                        value : inherit
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [2] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-image-pair(shared)
+                                    }
+                                ]
+                                text : html::view-transition-image-pair(shared)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : isolation
+                                        value : isolate
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoIdentifier : shared
+                pseudoType : view-transition-image-pair
+            }
+            [5] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 1
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-new()
+                                    }
+                                    [1] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-old()
+                                    }
+                                ]
+                                text : ::view-transition-new(), ::view-transition-old()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : absolute
+                                    }
+                                    [1] : {
+                                        name : inset-block-start
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : inline-size
+                                        value : 100%
+                                    }
+                                    [3] : {
+                                        name : block-size
+                                        value : auto
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [1] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-old()
+                                    }
+                                ]
+                                text : html::view-transition-old()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-name
+                                        value : -ua-view-transition-fade-out
+                                    }
+                                    [1] : {
+                                        name : animation-duration
+                                        value : inherit
+                                    }
+                                    [2] : {
+                                        name : animation-fill-mode
+                                        value : inherit
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [2] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-old(root)
+                                    }
+                                ]
+                                text : html::view-transition-old(root)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : mix-blend-mode
+                                        value : plus-lighter
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [3] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : regular
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        range : {
+                                            endColumn : 25
+                                            endLine : 0
+                                            startColumn : 1
+                                            startLine : 0
+                                        }
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-old(*)
+                                    }
+                                ]
+                                text : ::view-transition-old()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        disabled : false
+                                        implicit : false
+                                        longhandProperties : [
+                                            [0] : {
+                                                name : background-image
+                                                value : initial
+                                            }
+                                            [1] : {
+                                                name : background-position-x
+                                                value : initial
+                                            }
+                                            [2] : {
+                                                name : background-position-y
+                                                value : initial
+                                            }
+                                            [3] : {
+                                                name : background-size
+                                                value : initial
+                                            }
+                                            [4] : {
+                                                name : background-repeat-x
+                                                value : initial
+                                            }
+                                            [5] : {
+                                                name : background-repeat-y
+                                                value : initial
+                                            }
+                                            [6] : {
+                                                name : background-attachment
+                                                value : initial
+                                            }
+                                            [7] : {
+                                                name : background-origin
+                                                value : initial
+                                            }
+                                            [8] : {
+                                                name : background-clip
+                                                value : initial
+                                            }
+                                            [9] : {
+                                                name : background-color
+                                                value : red
+                                            }
+                                        ]
+                                        name : background
+                                        range : {
+                                            endColumn : 43
+                                            endLine : 0
+                                            startColumn : 27
+                                            startLine : 0
+                                        }
+                                        text : background: red;
+                                        value : red
+                                    }
+                                    [1] : {
+                                        name : background-image
+                                        value : initial
+                                    }
+                                    [2] : {
+                                        name : background-position-x
+                                        value : initial
+                                    }
+                                    [3] : {
+                                        name : background-position-y
+                                        value : initial
+                                    }
+                                    [4] : {
+                                        name : background-size
+                                        value : initial
+                                    }
+                                    [5] : {
+                                        name : background-repeat-x
+                                        value : initial
+                                    }
+                                    [6] : {
+                                        name : background-repeat-y
+                                        value : initial
+                                    }
+                                    [7] : {
+                                        name : background-attachment
+                                        value : initial
+                                    }
+                                    [8] : {
+                                        name : background-origin
+                                        value : initial
+                                    }
+                                    [9] : {
+                                        name : background-clip
+                                        value : initial
+                                    }
+                                    [10] : {
+                                        name : background-color
+                                        value : red
+                                    }
+                                ]
+                                cssText : background: red;
+                                range : {
+                                    endColumn : 43
+                                    endLine : 0
+                                    startColumn : 27
+                                    startLine : 0
+                                }
+                                shorthandEntries : [
+                                    [0] : {
+                                        name : background
+                                        value : red
+                                    }
+                                ]
+                                styleSheetId : <string>
+                            }
+                            styleSheetId : <string>
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoIdentifier : root
+                pseudoType : view-transition-old
+            }
+            [6] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 1
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-new()
+                                    }
+                                    [1] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-old()
+                                    }
+                                ]
+                                text : ::view-transition-new(), ::view-transition-old()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : absolute
+                                    }
+                                    [1] : {
+                                        name : inset-block-start
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : inline-size
+                                        value : 100%
+                                    }
+                                    [3] : {
+                                        name : block-size
+                                        value : auto
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [1] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-old()
+                                    }
+                                ]
+                                text : html::view-transition-old()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-name
+                                        value : -ua-view-transition-fade-out
+                                    }
+                                    [1] : {
+                                        name : animation-duration
+                                        value : inherit
+                                    }
+                                    [2] : {
+                                        name : animation-fill-mode
+                                        value : inherit
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [2] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-old(shared)
+                                    }
+                                ]
+                                text : html::view-transition-old(shared)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : mix-blend-mode
+                                        value : plus-lighter
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [3] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : regular
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        range : {
+                                            endColumn : 25
+                                            endLine : 0
+                                            startColumn : 1
+                                            startLine : 0
+                                        }
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-old(*)
+                                    }
+                                ]
+                                text : ::view-transition-old()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        disabled : false
+                                        implicit : false
+                                        longhandProperties : [
+                                            [0] : {
+                                                name : background-image
+                                                value : initial
+                                            }
+                                            [1] : {
+                                                name : background-position-x
+                                                value : initial
+                                            }
+                                            [2] : {
+                                                name : background-position-y
+                                                value : initial
+                                            }
+                                            [3] : {
+                                                name : background-size
+                                                value : initial
+                                            }
+                                            [4] : {
+                                                name : background-repeat-x
+                                                value : initial
+                                            }
+                                            [5] : {
+                                                name : background-repeat-y
+                                                value : initial
+                                            }
+                                            [6] : {
+                                                name : background-attachment
+                                                value : initial
+                                            }
+                                            [7] : {
+                                                name : background-origin
+                                                value : initial
+                                            }
+                                            [8] : {
+                                                name : background-clip
+                                                value : initial
+                                            }
+                                            [9] : {
+                                                name : background-color
+                                                value : red
+                                            }
+                                        ]
+                                        name : background
+                                        range : {
+                                            endColumn : 43
+                                            endLine : 0
+                                            startColumn : 27
+                                            startLine : 0
+                                        }
+                                        text : background: red;
+                                        value : red
+                                    }
+                                    [1] : {
+                                        name : background-image
+                                        value : initial
+                                    }
+                                    [2] : {
+                                        name : background-position-x
+                                        value : initial
+                                    }
+                                    [3] : {
+                                        name : background-position-y
+                                        value : initial
+                                    }
+                                    [4] : {
+                                        name : background-size
+                                        value : initial
+                                    }
+                                    [5] : {
+                                        name : background-repeat-x
+                                        value : initial
+                                    }
+                                    [6] : {
+                                        name : background-repeat-y
+                                        value : initial
+                                    }
+                                    [7] : {
+                                        name : background-attachment
+                                        value : initial
+                                    }
+                                    [8] : {
+                                        name : background-origin
+                                        value : initial
+                                    }
+                                    [9] : {
+                                        name : background-clip
+                                        value : initial
+                                    }
+                                    [10] : {
+                                        name : background-color
+                                        value : red
+                                    }
+                                ]
+                                cssText : background: red;
+                                range : {
+                                    endColumn : 43
+                                    endLine : 0
+                                    startColumn : 27
+                                    startLine : 0
+                                }
+                                shorthandEntries : [
+                                    [0] : {
+                                        name : background
+                                        value : red
+                                    }
+                                ]
+                                styleSheetId : <string>
+                            }
+                            styleSheetId : <string>
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoIdentifier : shared
+                pseudoType : view-transition-old
+            }
+            [7] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-new()
+                                    }
+                                    [1] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-old()
+                                    }
+                                ]
+                                text : ::view-transition-new(), ::view-transition-old()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : absolute
+                                    }
+                                    [1] : {
+                                        name : inset-block-start
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : inline-size
+                                        value : 100%
+                                    }
+                                    [3] : {
+                                        name : block-size
+                                        value : auto
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [1] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-new()
+                                    }
+                                ]
+                                text : html::view-transition-new()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-name
+                                        value : -ua-view-transition-fade-in
+                                    }
+                                    [1] : {
+                                        name : animation-duration
+                                        value : inherit
+                                    }
+                                    [2] : {
+                                        name : animation-fill-mode
+                                        value : inherit
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [2] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-new(root)
+                                    }
+                                ]
+                                text : html::view-transition-new(root)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : mix-blend-mode
+                                        value : plus-lighter
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoIdentifier : root
+                pseudoType : view-transition-new
+            }
+            [8] : {
+                matches : [
+                    [0] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-new()
+                                    }
+                                    [1] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 0
+                                        }
+                                        text : ::view-transition-old()
+                                    }
+                                ]
+                                text : ::view-transition-new(), ::view-transition-old()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : position
+                                        value : absolute
+                                    }
+                                    [1] : {
+                                        name : inset-block-start
+                                        value : 0px
+                                    }
+                                    [2] : {
+                                        name : inline-size
+                                        value : 100%
+                                    }
+                                    [3] : {
+                                        name : block-size
+                                        value : auto
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [1] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 0
+                                            c : 1
+                                        }
+                                        text : html::view-transition-new()
+                                    }
+                                ]
+                                text : html::view-transition-new()
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : animation-name
+                                        value : -ua-view-transition-fade-in
+                                    }
+                                    [1] : {
+                                        name : animation-duration
+                                        value : inherit
+                                    }
+                                    [2] : {
+                                        name : animation-fill-mode
+                                        value : inherit
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [2] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : user-agent
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 1
+                                        }
+                                        text : html::view-transition-new(shared)
+                                    }
+                                ]
+                                text : html::view-transition-new(shared)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        name : mix-blend-mode
+                                        value : plus-lighter
+                                    }
+                                ]
+                                shorthandEntries : [
+                                ]
+                            }
+                            supports : [
+                            ]
+                        }
+                    }
+                    [3] : {
+                        matchingSelectors : [
+                            [0] : 0
+                        ]
+                        rule : {
+                            containerQueries : [
+                            ]
+                            layers : [
+                            ]
+                            media : [
+                            ]
+                            origin : regular
+                            scopes : [
+                            ]
+                            selectorList : {
+                                selectors : [
+                                    [0] : {
+                                        range : {
+                                            endColumn : 30
+                                            endLine : 0
+                                            startColumn : 1
+                                            startLine : 0
+                                        }
+                                        specificity : {
+                                            a : 0
+                                            b : 1
+                                            c : 0
+                                        }
+                                        text : ::view-transition-new(shared)
+                                    }
+                                ]
+                                text : ::view-transition-new(shared)
+                            }
+                            style : {
+                                cssProperties : [
+                                    [0] : {
+                                        disabled : false
+                                        implicit : false
+                                        name : animation-duration
+                                        range : {
+                                            endColumn : 57
+                                            endLine : 0
+                                            startColumn : 32
+                                            startLine : 0
+                                        }
+                                        text : animation-duration: 300s;
+                                        value : 300s
+                                    }
+                                    [1] : {
+                                        name : animation-duration
+                                        value : 300s
+                                    }
+                                ]
+                                cssText : animation-duration: 300s;
+                                range : {
+                                    endColumn : 57
+                                    endLine : 0
+                                    startColumn : 32
+                                    startLine : 0
+                                }
+                                shorthandEntries : [
+                                ]
+                                styleSheetId : <string>
+                            }
+                            styleSheetId : <string>
+                            supports : [
+                            ]
+                        }
+                    }
+                ]
+                pseudoIdentifier : shared
+                pseudoType : view-transition-new
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition with id undefined{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition
+                            }
+                        ]
+                        text : html::view-transition
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : fixed
+                            }
+                            [1] : {
+                                name : top
+                                value : 0px
+                            }
+                            [2] : {
+                                name : right
+                                value : 0px
+                            }
+                            [3] : {
+                                name : bottom
+                                value : 0px
+                            }
+                            [4] : {
+                                name : left
+                                value : 0px
+                            }
+                        ]
+                        shorthandEntries : [
+                            [0] : {
+                                name : inset
+                                value : 0px
+                            }
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition-group with id root{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-group()
+                            }
+                        ]
+                        text : html::view-transition-group()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : absolute
+                            }
+                            [1] : {
+                                name : top
+                                value : 0px
+                            }
+                            [2] : {
+                                name : left
+                                value : 0px
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-group()
+                            }
+                        ]
+                        text : html::view-transition-group()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-duration
+                                value : 0.25s
+                            }
+                            [1] : {
+                                name : animation-fill-mode
+                                value : both
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [2] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-group(root)
+                            }
+                        ]
+                        text : html::view-transition-group(root)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : right
+                                value : 0px
+                            }
+                            [1] : {
+                                name : bottom
+                                value : 0px
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition-image-pair with id root{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-image-pair()
+                            }
+                        ]
+                        text : ::view-transition-image-pair()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : absolute
+                            }
+                            [1] : {
+                                name : top
+                                value : 0px
+                            }
+                            [2] : {
+                                name : right
+                                value : 0px
+                            }
+                            [3] : {
+                                name : bottom
+                                value : 0px
+                            }
+                            [4] : {
+                                name : left
+                                value : 0px
+                            }
+                        ]
+                        shorthandEntries : [
+                            [0] : {
+                                name : inset
+                                value : 0px
+                            }
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-image-pair()
+                            }
+                        ]
+                        text : html::view-transition-image-pair()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-duration
+                                value : inherit
+                            }
+                            [1] : {
+                                name : animation-fill-mode
+                                value : inherit
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [2] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-image-pair(root)
+                            }
+                        ]
+                        text : html::view-transition-image-pair(root)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : isolation
+                                value : isolate
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition-old with id root{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 1
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-new()
+                            }
+                            [1] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-old()
+                            }
+                        ]
+                        text : ::view-transition-new(), ::view-transition-old()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : absolute
+                            }
+                            [1] : {
+                                name : inset-block-start
+                                value : 0px
+                            }
+                            [2] : {
+                                name : inline-size
+                                value : 100%
+                            }
+                            [3] : {
+                                name : block-size
+                                value : auto
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-old()
+                            }
+                        ]
+                        text : html::view-transition-old()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-name
+                                value : -ua-view-transition-fade-out
+                            }
+                            [1] : {
+                                name : animation-duration
+                                value : inherit
+                            }
+                            [2] : {
+                                name : animation-fill-mode
+                                value : inherit
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [2] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-old(root)
+                            }
+                        ]
+                        text : html::view-transition-old(root)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : mix-blend-mode
+                                value : plus-lighter
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [3] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : regular
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                range : {
+                                    endColumn : 25
+                                    endLine : 0
+                                    startColumn : 1
+                                    startLine : 0
+                                }
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-old(*)
+                            }
+                        ]
+                        text : ::view-transition-old()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                disabled : false
+                                implicit : false
+                                longhandProperties : [
+                                    [0] : {
+                                        name : background-image
+                                        value : initial
+                                    }
+                                    [1] : {
+                                        name : background-position-x
+                                        value : initial
+                                    }
+                                    [2] : {
+                                        name : background-position-y
+                                        value : initial
+                                    }
+                                    [3] : {
+                                        name : background-size
+                                        value : initial
+                                    }
+                                    [4] : {
+                                        name : background-repeat-x
+                                        value : initial
+                                    }
+                                    [5] : {
+                                        name : background-repeat-y
+                                        value : initial
+                                    }
+                                    [6] : {
+                                        name : background-attachment
+                                        value : initial
+                                    }
+                                    [7] : {
+                                        name : background-origin
+                                        value : initial
+                                    }
+                                    [8] : {
+                                        name : background-clip
+                                        value : initial
+                                    }
+                                    [9] : {
+                                        name : background-color
+                                        value : red
+                                    }
+                                ]
+                                name : background
+                                range : {
+                                    endColumn : 43
+                                    endLine : 0
+                                    startColumn : 27
+                                    startLine : 0
+                                }
+                                text : background: red;
+                                value : red
+                            }
+                            [1] : {
+                                name : background-image
+                                value : initial
+                            }
+                            [2] : {
+                                name : background-position-x
+                                value : initial
+                            }
+                            [3] : {
+                                name : background-position-y
+                                value : initial
+                            }
+                            [4] : {
+                                name : background-size
+                                value : initial
+                            }
+                            [5] : {
+                                name : background-repeat-x
+                                value : initial
+                            }
+                            [6] : {
+                                name : background-repeat-y
+                                value : initial
+                            }
+                            [7] : {
+                                name : background-attachment
+                                value : initial
+                            }
+                            [8] : {
+                                name : background-origin
+                                value : initial
+                            }
+                            [9] : {
+                                name : background-clip
+                                value : initial
+                            }
+                            [10] : {
+                                name : background-color
+                                value : red
+                            }
+                        ]
+                        cssText : background: red;
+                        range : {
+                            endColumn : 43
+                            endLine : 0
+                            startColumn : 27
+                            startLine : 0
+                        }
+                        shorthandEntries : [
+                            [0] : {
+                                name : background
+                                value : red
+                            }
+                        ]
+                        styleSheetId : <string>
+                    }
+                    styleSheetId : <string>
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition-new with id root{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-new()
+                            }
+                            [1] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-old()
+                            }
+                        ]
+                        text : ::view-transition-new(), ::view-transition-old()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : absolute
+                            }
+                            [1] : {
+                                name : inset-block-start
+                                value : 0px
+                            }
+                            [2] : {
+                                name : inline-size
+                                value : 100%
+                            }
+                            [3] : {
+                                name : block-size
+                                value : auto
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-new()
+                            }
+                        ]
+                        text : html::view-transition-new()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-name
+                                value : -ua-view-transition-fade-in
+                            }
+                            [1] : {
+                                name : animation-duration
+                                value : inherit
+                            }
+                            [2] : {
+                                name : animation-fill-mode
+                                value : inherit
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [2] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-new(root)
+                            }
+                        ]
+                        text : html::view-transition-new(root)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : mix-blend-mode
+                                value : plus-lighter
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition-group with id shared{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-group()
+                            }
+                        ]
+                        text : html::view-transition-group()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : absolute
+                            }
+                            [1] : {
+                                name : top
+                                value : 0px
+                            }
+                            [2] : {
+                                name : left
+                                value : 0px
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-group()
+                            }
+                        ]
+                        text : html::view-transition-group()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-duration
+                                value : 0.25s
+                            }
+                            [1] : {
+                                name : animation-fill-mode
+                                value : both
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [2] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-group(shared)
+                            }
+                        ]
+                        text : html::view-transition-group(shared)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : width
+                                value : 100px
+                            }
+                            [1] : {
+                                name : height
+                                value : 100px
+                            }
+                            [2] : {
+                                name : transform
+                                value : matrix(1, 0, 0, 1, 8, 8)
+                            }
+                            [3] : {
+                                name : writing-mode
+                                value : horizontal-tb
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [3] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-group(shared)
+                            }
+                        ]
+                        text : html::view-transition-group(shared)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-name
+                                value : -ua-view-transition-group-anim-shared
+                            }
+                            [1] : {
+                                name : animation-timing-function
+                                value : ease
+                            }
+                            [2] : {
+                                name : animation-delay
+                                value : 0s
+                            }
+                            [3] : {
+                                name : animation-iteration-count
+                                value : 1
+                            }
+                            [4] : {
+                                name : animation-direction
+                                value : normal
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition-image-pair with id shared{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-image-pair()
+                            }
+                        ]
+                        text : ::view-transition-image-pair()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : absolute
+                            }
+                            [1] : {
+                                name : top
+                                value : 0px
+                            }
+                            [2] : {
+                                name : right
+                                value : 0px
+                            }
+                            [3] : {
+                                name : bottom
+                                value : 0px
+                            }
+                            [4] : {
+                                name : left
+                                value : 0px
+                            }
+                        ]
+                        shorthandEntries : [
+                            [0] : {
+                                name : inset
+                                value : 0px
+                            }
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-image-pair()
+                            }
+                        ]
+                        text : html::view-transition-image-pair()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-duration
+                                value : inherit
+                            }
+                            [1] : {
+                                name : animation-fill-mode
+                                value : inherit
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [2] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-image-pair(shared)
+                            }
+                        ]
+                        text : html::view-transition-image-pair(shared)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : isolation
+                                value : isolate
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition-old with id shared{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 1
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-new()
+                            }
+                            [1] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-old()
+                            }
+                        ]
+                        text : ::view-transition-new(), ::view-transition-old()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : absolute
+                            }
+                            [1] : {
+                                name : inset-block-start
+                                value : 0px
+                            }
+                            [2] : {
+                                name : inline-size
+                                value : 100%
+                            }
+                            [3] : {
+                                name : block-size
+                                value : auto
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-old()
+                            }
+                        ]
+                        text : html::view-transition-old()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-name
+                                value : -ua-view-transition-fade-out
+                            }
+                            [1] : {
+                                name : animation-duration
+                                value : inherit
+                            }
+                            [2] : {
+                                name : animation-fill-mode
+                                value : inherit
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [2] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-old(shared)
+                            }
+                        ]
+                        text : html::view-transition-old(shared)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : mix-blend-mode
+                                value : plus-lighter
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [3] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : regular
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                range : {
+                                    endColumn : 25
+                                    endLine : 0
+                                    startColumn : 1
+                                    startLine : 0
+                                }
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-old(*)
+                            }
+                        ]
+                        text : ::view-transition-old()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                disabled : false
+                                implicit : false
+                                longhandProperties : [
+                                    [0] : {
+                                        name : background-image
+                                        value : initial
+                                    }
+                                    [1] : {
+                                        name : background-position-x
+                                        value : initial
+                                    }
+                                    [2] : {
+                                        name : background-position-y
+                                        value : initial
+                                    }
+                                    [3] : {
+                                        name : background-size
+                                        value : initial
+                                    }
+                                    [4] : {
+                                        name : background-repeat-x
+                                        value : initial
+                                    }
+                                    [5] : {
+                                        name : background-repeat-y
+                                        value : initial
+                                    }
+                                    [6] : {
+                                        name : background-attachment
+                                        value : initial
+                                    }
+                                    [7] : {
+                                        name : background-origin
+                                        value : initial
+                                    }
+                                    [8] : {
+                                        name : background-clip
+                                        value : initial
+                                    }
+                                    [9] : {
+                                        name : background-color
+                                        value : red
+                                    }
+                                ]
+                                name : background
+                                range : {
+                                    endColumn : 43
+                                    endLine : 0
+                                    startColumn : 27
+                                    startLine : 0
+                                }
+                                text : background: red;
+                                value : red
+                            }
+                            [1] : {
+                                name : background-image
+                                value : initial
+                            }
+                            [2] : {
+                                name : background-position-x
+                                value : initial
+                            }
+                            [3] : {
+                                name : background-position-y
+                                value : initial
+                            }
+                            [4] : {
+                                name : background-size
+                                value : initial
+                            }
+                            [5] : {
+                                name : background-repeat-x
+                                value : initial
+                            }
+                            [6] : {
+                                name : background-repeat-y
+                                value : initial
+                            }
+                            [7] : {
+                                name : background-attachment
+                                value : initial
+                            }
+                            [8] : {
+                                name : background-origin
+                                value : initial
+                            }
+                            [9] : {
+                                name : background-clip
+                                value : initial
+                            }
+                            [10] : {
+                                name : background-color
+                                value : red
+                            }
+                        ]
+                        cssText : background: red;
+                        range : {
+                            endColumn : 43
+                            endLine : 0
+                            startColumn : 27
+                            startLine : 0
+                        }
+                        shorthandEntries : [
+                            [0] : {
+                                name : background
+                                value : red
+                            }
+                        ]
+                        styleSheetId : <string>
+                    }
+                    styleSheetId : <string>
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+Dumping styles for : ::view-transition-new with id shared{
+    id : <number>
+    result : {
+        inherited : [
+        ]
+        matchedCSSRules : [
+            [0] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-new()
+                            }
+                            [1] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 0
+                                }
+                                text : ::view-transition-old()
+                            }
+                        ]
+                        text : ::view-transition-new(), ::view-transition-old()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : position
+                                value : absolute
+                            }
+                            [1] : {
+                                name : inset-block-start
+                                value : 0px
+                            }
+                            [2] : {
+                                name : inline-size
+                                value : 100%
+                            }
+                            [3] : {
+                                name : block-size
+                                value : auto
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [1] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 0
+                                    c : 1
+                                }
+                                text : html::view-transition-new()
+                            }
+                        ]
+                        text : html::view-transition-new()
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : animation-name
+                                value : -ua-view-transition-fade-in
+                            }
+                            [1] : {
+                                name : animation-duration
+                                value : inherit
+                            }
+                            [2] : {
+                                name : animation-fill-mode
+                                value : inherit
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [2] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : user-agent
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 1
+                                }
+                                text : html::view-transition-new(shared)
+                            }
+                        ]
+                        text : html::view-transition-new(shared)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                name : mix-blend-mode
+                                value : plus-lighter
+                            }
+                        ]
+                        shorthandEntries : [
+                        ]
+                    }
+                    supports : [
+                    ]
+                }
+            }
+            [3] : {
+                matchingSelectors : [
+                    [0] : 0
+                ]
+                rule : {
+                    containerQueries : [
+                    ]
+                    layers : [
+                    ]
+                    media : [
+                    ]
+                    origin : regular
+                    scopes : [
+                    ]
+                    selectorList : {
+                        selectors : [
+                            [0] : {
+                                range : {
+                                    endColumn : 30
+                                    endLine : 0
+                                    startColumn : 1
+                                    startLine : 0
+                                }
+                                specificity : {
+                                    a : 0
+                                    b : 1
+                                    c : 0
+                                }
+                                text : ::view-transition-new(shared)
+                            }
+                        ]
+                        text : ::view-transition-new(shared)
+                    }
+                    style : {
+                        cssProperties : [
+                            [0] : {
+                                disabled : false
+                                implicit : false
+                                name : animation-duration
+                                range : {
+                                    endColumn : 57
+                                    endLine : 0
+                                    startColumn : 32
+                                    startLine : 0
+                                }
+                                text : animation-duration: 300s;
+                                value : 300s
+                            }
+                            [1] : {
+                                name : animation-duration
+                                value : 300s
+                            }
+                        ]
+                        cssText : animation-duration: 300s;
+                        range : {
+                            endColumn : 57
+                            endLine : 0
+                            startColumn : 32
+                            startLine : 0
+                        }
+                        shorthandEntries : [
+                        ]
+                        styleSheetId : <string>
+                    }
+                    styleSheetId : <string>
+                    supports : [
+                    ]
+                }
+            }
+        ]
+    }
+    sessionId : <string>
+}
+
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/__init__.py b/third_party/blink/web_tests/virtual/view-transition-mpa-serialization/view-transition/capture-callback-exception-expected.txt
similarity index 100%
copy from third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/__init__.py
copy to third_party/blink/web_tests/virtual/view-transition-mpa-serialization/view-transition/capture-callback-exception-expected.txt
diff --git a/third_party/blink/web_tests/webaudio/OWNERS b/third_party/blink/web_tests/webaudio/OWNERS
index a7db251..32f919a5 100644
--- a/third_party/blink/web_tests/webaudio/OWNERS
+++ b/third_party/blink/web_tests/webaudio/OWNERS
@@ -1,3 +1,4 @@
 hongchan@chromium.org
 mjwilson@chromium.org
-alvinji@chromium.org
\ No newline at end of file
+alvinji@chromium.org
+sinafirooz@chromium.org
\ No newline at end of file
diff --git a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
index 097c1c7..ad2f171 100644
--- a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
+++ b/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
@@ -401,6 +401,7 @@
 scrollTimelineAttachment
 scrollTimelineAxis
 scrollTimelineName
+scrollbarColor
 scrollbarGutter
 scrollbarWidth
 setProperty
diff --git a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt b/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
index 4fac666..64b26ea 100644
--- a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
@@ -353,6 +353,7 @@
     scroll-timeline-attachment
     scroll-timeline-axis
     scroll-timeline-name
+    scrollbar-color
     scrollbar-gutter
     scrollbar-width
     shape-image-threshold
diff --git a/third_party/blink/web_tests/wpt_internal/long-animation-frame/loaf-use-counter.html b/third_party/blink/web_tests/wpt_internal/long-animation-frame/loaf-use-counter.html
new file mode 100644
index 0000000..e1e36fe
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/long-animation-frame/loaf-use-counter.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+const kLongAnimationFrameObserver = 4577;
+const kLongAnimationFrameRequested = 4578;
+
+function clear() {
+  internals.clearUseCounter(document, kLongAnimationFrameObserver);
+  internals.clearUseCounter(document, kLongAnimationFrameRequested);
+}
+
+promise_test(async () => {
+  clear();
+  performance.getEntries();
+  performance.getEntriesByName("long-animation-frame");
+  performance.getEntriesByType("longtask");
+  new PerformanceObserver(() => {}).observe({entryTypes: ["resource"]});
+  assert_false(internals.isUseCounted(document, kLongAnimationFrameObserver));
+  assert_false(internals.isUseCounted(document, kLongAnimationFrameRequested));
+}, "UseCounter for LoAF should not be triggered for non-loaf types");
+
+promise_test(async () => {
+  clear();
+  performance.getEntriesByType("long-animation-frame");
+  assert_false(internals.isUseCounted(document, kLongAnimationFrameObserver));
+  assert_true(internals.isUseCounted(document, kLongAnimationFrameRequested));
+}, "UseCounter for LoAF requested should be triggered at appropriate times");
+
+promise_test(async () => {
+  clear();
+  new PerformanceObserver(() => {}).observe({type: "long-animation-frame"});
+  assert_true(internals.isUseCounted(document, kLongAnimationFrameObserver));
+  assert_false(internals.isUseCounted(document, kLongAnimationFrameRequested));
+}, "UseCounter for LoAF observer should be triggered at appropriate times");
+</script>
+<body>
+  <div id="log"></div>
+</body>
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/adapter_single_use.https.html b/third_party/blink/web_tests/wpt_internal/webgpu/adapter_single_use.https.html
index 164263ff..132f5ff 100644
--- a/third_party/blink/web_tests/wpt_internal/webgpu/adapter_single_use.https.html
+++ b/third_party/blink/web_tests/wpt_internal/webgpu/adapter_single_use.https.html
@@ -7,6 +7,24 @@
 <script>
   'use strict';
 
+  /**
+   * Takes a promise `p`, and returns a new one which rejects if `p` takes too long,
+   * and otherwise passes the result through.
+   * Borrowed from the WebGPU CTS common/util/util.ts
+   */
+  function raceWithRejectOnTimeout(p, ms, msg) {
+      // Setup a promise that will reject after `ms` milliseconds. We cancel this timeout when
+      // `p` is finalized, so the JavaScript VM doesn't hang around waiting for the timer to
+      // complete, once the test runner has finished executing the tests.
+      const timeoutPromise = new Promise((_resolve, reject) => {
+          const handle = setTimeout(() => {
+              reject(new PromiseTimeoutError(msg));
+          }, ms);
+          p = p.finally(() => clearTimeout(handle));
+      });
+      return Promise.race([p, timeoutPromise]);
+  }
+
   promise_test(async t => {
     const adapter = await navigator.gpu.requestAdapter();
     assert_true(adapter !== null);
@@ -14,13 +32,15 @@
     const device = await adapter.requestDevice();
     assert_true(device !== null);
 
-    // requestDevice was successful, so should fail from here on.
-    try {
-      await adapter.requestDevice();
-      assert_unreached('second requestDevice should have rejected');
-    } catch (e) {
-      assert_equals(e.name, 'InvalidStateError');
-    }
+    // requestDevice was successful, should begin returning lost devices from
+    // here on.
+    const staleDevice = await adapter.requestDevice();
+    assert_true(staleDevice !== null);
+
+    // Check to ensure the device is lost, and the loss is not due to it being explicitly destroyed.
+    const kTimeoutMS = 1000;
+    const lost = await raceWithRejectOnTimeout(staleDevice.lost, kTimeoutMS, 'device was not lost');
+    assert_true(lost.reason === 'unknown');
   }, 'invalid after successful requestDevice');
 
   promise_test(async t => {
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/web_platform/reftests/ref/canvas_complex-ref.html b/third_party/blink/web_tests/wpt_internal/webgpu/web_platform/reftests/ref/canvas_complex-ref.html
index 7454d1d..21ab75b 100644
--- a/third_party/blink/web_tests/wpt_internal/webgpu/web_platform/reftests/ref/canvas_complex-ref.html
+++ b/third_party/blink/web_tests/wpt_internal/webgpu/web_platform/reftests/ref/canvas_complex-ref.html
@@ -22,6 +22,6 @@
     draw(cvs0.getContext('2d'));
     draw(cvs1.getContext('2d'));
     draw(cvs2.getContext('2d'));
-    
+
   </script>
 </html>
diff --git a/third_party/fuchsia-gn-sdk/src/component.gni b/third_party/fuchsia-gn-sdk/src/component.gni
index 626aefa..2197739 100644
--- a/third_party/fuchsia-gn-sdk/src/component.gni
+++ b/third_party/fuchsia-gn-sdk/src/component.gni
@@ -48,7 +48,7 @@
 #     [list of strings] The set of protocols that each child must use.
 #
 #   include_coverage_shard (optional)
-#     Whether to include the `enable_coverage_data.cml` in a merged manifest.
+#     Whether to include the `coverage.shard.cml` in a merged manifest.
 #     Overrides the default based on `fuchsia_code_coverage`.
 #     Should only be used in rare exceptions that do not use CML-based routing.
 #
@@ -83,7 +83,7 @@
                                "testonly",
                              ])
       sources = [
-        "${fuchsia_sdk}/build/enable_coverage_data.cml",
+        "${fuchsia_sdk}/pkg/sys/testing/coverage.shard.cml",
         manifest,
       ]
       output_name = manifest_rel_path
diff --git a/third_party/polymer/v3_0/BUILD.gn b/third_party/polymer/v3_0/BUILD.gn
index 5f4b3b4c..5d11077 100644
--- a/third_party/polymer/v3_0/BUILD.gn
+++ b/third_party/polymer/v3_0/BUILD.gn
@@ -81,7 +81,8 @@
 
   if (optimize_webui) {
     deps = [ ":build_min_js" ]
-    manifest_files = [ "$target_gen_dir/minify_js_manifest.json" ]
+    manifest_files = filter_include(get_target_outputs(":build_min_js"),
+                                    [ "*_manifest.json" ])
   } else {
     input_files += js_files
   }
diff --git a/tools/android/modularization/gn/dep_operations.py b/tools/android/modularization/gn/dep_operations.py
index bd0aef8..1c58baa 100755
--- a/tools/android/modularization/gn/dep_operations.py
+++ b/tools/android/modularization/gn/dep_operations.py
@@ -13,7 +13,7 @@
 import pathlib
 import subprocess
 import sys
-from typing import List, Optional, Set, Tuple
+from typing import List, Optional, Set
 
 import json_gn_editor
 import utils
@@ -46,6 +46,11 @@
         return f'{dryrun}{msg}{ignore}{self.path}{skip}'
 
 
+def _add_deps(target: str, deps: List[str], root: pathlib.Path, path: str):
+    with json_gn_editor.BuildFile(path, root) as build_file:
+        build_file.add_deps(target, deps)
+
+
 def _search_deps(name_query: Optional[str], path_query: Optional[str],
                  root: pathlib.Path, path: str):
     with json_gn_editor.BuildFile(path, root) as build_file:
@@ -77,6 +82,17 @@
     return None
 
 
+def _add(args: argparse.Namespace, build_filepaths: List[str],
+         root: pathlib.Path):
+    deps = args.deps
+    target = args.target
+    with multiprocessing.Pool() as pool:
+        pool.map(
+            functools.partial(_add_deps, target, deps, root),
+            build_filepaths,
+        )
+
+
 def _search(args: argparse.Namespace, build_filepaths: List[str],
             root: pathlib.Path):
     name_query = args.name
@@ -262,8 +278,8 @@
                                     '--quiet',
                                     action='store_true',
                                     help='Used to print less logging.')
-    common_args_parser.add_argument(
-        '--file', help='Run on a specific build file (debugging).')
+    common_args_parser.add_argument('--file',
+                                    help='Run on a specific build file.')
     common_args_parser.add_argument(
         '--resume-from',
         help='Skip files before this build file path (debugging).')
@@ -271,6 +287,18 @@
     subparsers = parser.add_subparsers(
         help='Use subcommand -h to see full usage.')
 
+    add_parser = subparsers.add_parser(
+        'add',
+        parents=[common_args_parser],
+        help='Add one or more deps to a specific target (pass the path to the '
+        'BUILD.gn via --file for faster results). The target **must** '
+        'have a deps variable defined, even if it is an empty [].')
+    add_parser.add_argument('--target', help='The name of the target.')
+    add_parser.add_argument('--deps',
+                            nargs='+',
+                            help='The name(s) of the new dep(s).')
+    add_parser.set_defaults(command=_add)
+
     search_parser = subparsers.add_parser(
         'search',
         parents=[common_args_parser],
diff --git a/tools/android/modularization/gn/json_gn_editor.py b/tools/android/modularization/gn/json_gn_editor.py
index 807a850..522d0414 100644
--- a/tools/android/modularization/gn/json_gn_editor.py
+++ b/tools/android/modularization/gn/json_gn_editor.py
@@ -18,7 +18,7 @@
 import subprocess
 import sys
 
-from typing import Iterator, List, Optional, Tuple
+from typing import Dict, Iterator, List, Optional, Tuple
 
 _TOOLS_ANDROID_PATH = pathlib.Path(__file__).resolve().parents[2]
 if str(_TOOLS_ANDROID_PATH) not in sys.path:
@@ -262,6 +262,62 @@
                               variable_name=var_name,
                               child_nodes=node_list)
 
+    def _clone_replacing_value(self, node_to_copy: Dict, new_dep_name: str):
+        """Clone the existing node to preserve line numbers and update name.
+
+        It is easier to clone an existing node around the same location, as the
+        actual dict looks like this:
+        {
+            'location': {
+                'begin_column': 5,
+                'begin_line': 137,
+                'end_column': 27,
+                'end_line': 137
+            },
+            'type': 'LITERAL',
+            'value': '":anr_data_proto_java"'
+        }
+
+        Thus the new node to return should keep the same 'location' value (the
+        parser is tolerant as long as it's roughly in the correct spot) but
+        update the 'value' to the new dependency name.
+        """
+        new_dep = copy.deepcopy(node_to_copy)
+        # Any comments associated with the previous dep would not apply.
+        for comment_key in (BEFORE_COMMENT, AFTER_COMMENT, SUFFIX_COMMENT):
+            new_dep.pop(comment_key, None)  # Remove if exists.
+        new_dep[NODE_VALUE] = f'"{new_dep_name}"'
+        return new_dep
+
+    def add_deps(self, target: str, deps: List[str]) -> bool:
+        added_new_dep = False
+        normalized_target = self._normalize(target)
+        for dep_list in self._find_all_deps_lists():
+            if dep_list.target_name is None:
+                continue
+            full_target_name = f'{self._gn_rel_path}:{dep_list.target_name}'
+            # Support both the exact name and the absolute GN target names
+            # starting with //.
+            if (target != dep_list.target_name
+                    and normalized_target != full_target_name):
+                continue
+            if dep_list.variable_name != 'deps':
+                continue
+            existing_dep_names = set(
+                self._normalize(child.get(NODE_VALUE), abs_path=False)
+                for child in dep_list.child_nodes)
+            for new_dep_name in deps:
+                if new_dep_name in existing_dep_names:
+                    logging.info(
+                        f'Skipping existing {new_dep_name} in {target}.deps')
+                    continue
+                logging.info(f'Adding {new_dep_name} to {target}.deps')
+                new_dep = self._clone_replacing_value(dep_list.child_nodes[0],
+                                                      new_dep_name)
+                dep_list.child_nodes.append(new_dep)
+                added_new_dep = True
+        return added_new_dep
+
     def search_deps(self, name_query: Optional[str],
                     path_query: Optional[str]) -> bool:
         if path_query:
@@ -335,12 +391,8 @@
                     target_str = f'{self._gn_rel_path}:{dep_list.target_name}'
                 location = f"{target_str}'s {dep_list.variable_name} variable"
                 logging.info(f'Adding {new_dep_name} to {location}')
-                new_dep = copy.deepcopy(dep_list.child_nodes[original_dep_idx])
-                # Any comments associated with the previous dep would not apply.
-                for comment_key in (BEFORE_COMMENT, AFTER_COMMENT,
-                                    SUFFIX_COMMENT):
-                    new_dep.pop(comment_key, None)  # Remove if exists.
-                new_dep[NODE_VALUE] = f'"{new_dep_name}"'
+                new_dep = self._clone_replacing_value(
+                    dep_list.child_nodes[original_dep_idx], new_dep_name)
                 # Add the new dep after the existing dep to preserve comments
                 # before the existing dep.
                 dep_list.child_nodes.insert(original_dep_idx + 1, new_dep)
diff --git a/tools/cast3p/runtime.version b/tools/cast3p/runtime.version
index f8e1d940..4db38bfa 100644
--- a/tools/cast3p/runtime.version
+++ b/tools/cast3p/runtime.version
@@ -1 +1 @@
-362090
+362546
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py
index bdcbed1..d0d94ab 100755
--- a/tools/clang/scripts/build.py
+++ b/tools/clang/scripts/build.py
@@ -708,8 +708,6 @@
       '-DCLANG_ENABLE_STATIC_ANALYZER=OFF',
       '-DCLANG_ENABLE_ARCMT=OFF',
       '-DBUG_REPORT_URL=' + BUG_REPORT_URL,
-      # Don't run Go bindings tests; PGO makes them confused.
-      '-DLLVM_INCLUDE_GO_TESTS=OFF',
       # See crbug.com/1126219: Use native symbolizer instead of DIA
       '-DLLVM_ENABLE_DIA_SDK=OFF',
       # Link all binaries with lld. Effectively passes -fuse-ld=lld to the
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py
index 4fc4cf9..be0e2386 100755
--- a/tools/clang/scripts/package.py
+++ b/tools/clang/scripts/package.py
@@ -371,9 +371,10 @@
         'lib/clang/$V/lib/linux/libclang_rt.builtins-i686-android.a',
         'lib/clang/$V/lib/linux/libclang_rt.builtins-x86_64-android.a',
 
-        # Builtins for Lacros (and potentially Linux, but not used there atm).
+        # Builtins for Linux and Lacros.
         'lib/clang/$V/lib/aarch64-unknown-linux-gnu/libclang_rt.builtins.a',
         'lib/clang/$V/lib/armv7-unknown-linux-gnueabihf/libclang_rt.builtins.a',
+        'lib/clang/$V/lib/i386-unknown-linux-gnu/libclang_rt.builtins.a',
         'lib/clang/$V/lib/x86_64-unknown-linux-gnu/libclang_rt.builtins.a',
 
         # crtstart/crtend for Linux and Lacros.
@@ -435,31 +436,39 @@
     ])
   elif sys.platform == 'win32':
     want.extend([
-      # AddressSanitizer C runtime (pure C won't link with *_cxx).
-      'lib/clang/$V/lib/windows/clang_rt.asan-x86_64.lib',
+        # pylint: disable=line-too-long
 
-      # AddressSanitizer C++ runtime.
-      'lib/clang/$V/lib/windows/clang_rt.asan_cxx-x86_64.lib',
+        # AddressSanitizer C runtime (pure C won't link with *_cxx).
+        'lib/clang/$V/lib/windows/clang_rt.asan-x86_64.lib',
 
-      # Thunk for AddressSanitizer needed for static build of a shared lib.
-      'lib/clang/$V/lib/windows/clang_rt.asan_dll_thunk-x86_64.lib',
+        # AddressSanitizer C++ runtime.
+        'lib/clang/$V/lib/windows/clang_rt.asan_cxx-x86_64.lib',
 
-      # AddressSanitizer runtime for component build.
-      'lib/clang/$V/lib/windows/clang_rt.asan_dynamic-x86_64.dll',
-      'lib/clang/$V/lib/windows/clang_rt.asan_dynamic-x86_64.lib',
+        # Thunk for AddressSanitizer needed for static build of a shared lib.
+        'lib/clang/$V/lib/windows/clang_rt.asan_dll_thunk-x86_64.lib',
 
-      # Thunk for AddressSanitizer for component build of a shared lib.
-      'lib/clang/$V/lib/windows/clang_rt.asan_dynamic_runtime_thunk-x86_64.lib',
+        # AddressSanitizer runtime for component build.
+        'lib/clang/$V/lib/windows/clang_rt.asan_dynamic-x86_64.dll',
+        'lib/clang/$V/lib/windows/clang_rt.asan_dynamic-x86_64.lib',
 
-      # Profile runtime (used by profiler and code coverage).
-      'lib/clang/$V/lib/windows/clang_rt.profile-i386.lib',
-      'lib/clang/$V/lib/windows/clang_rt.profile-x86_64.lib',
+        # Thunk for AddressSanitizer for component build of a shared lib.
+        'lib/clang/$V/lib/windows/clang_rt.asan_dynamic_runtime_thunk-x86_64.lib',
 
-      # UndefinedBehaviorSanitizer C runtime (pure C won't link with *_cxx).
-      'lib/clang/$V/lib/windows/clang_rt.ubsan_standalone-x86_64.lib',
+        # Builtins for C/C++.
+        'lib/clang/$V/lib/windows/clang_rt.builtins-i386.lib',
+        'lib/clang/$V/lib/windows/clang_rt.builtins-x86_64.lib',
 
-      # UndefinedBehaviorSanitizer C++ runtime.
-      'lib/clang/$V/lib/windows/clang_rt.ubsan_standalone_cxx-x86_64.lib',
+        # Profile runtime (used by profiler and code coverage).
+        'lib/clang/$V/lib/windows/clang_rt.profile-i386.lib',
+        'lib/clang/$V/lib/windows/clang_rt.profile-x86_64.lib',
+
+        # UndefinedBehaviorSanitizer C runtime (pure C won't link with *_cxx).
+        'lib/clang/$V/lib/windows/clang_rt.ubsan_standalone-x86_64.lib',
+
+        # UndefinedBehaviorSanitizer C++ runtime.
+        'lib/clang/$V/lib/windows/clang_rt.ubsan_standalone_cxx-x86_64.lib',
+
+        # pylint: enable=line-too-long
     ])
 
   # reclient is a tool for executing programs remotely. When uploading the
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index b12c703..d963dd9 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -36,7 +36,7 @@
 # Reverting problematic clang rolls is safe, though.
 # This is the output of `git describe` and is usable as a commit-ish.
 CLANG_REVISION = 'llvmorg-17-init-12166-g7586aeab'
-CLANG_SUB_REVISION = 2
+CLANG_SUB_REVISION = 3
 
 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
 RELEASE_VERSION = '17'
@@ -62,7 +62,7 @@
   """Delete dir."""
   if sys.platform == 'win32':
     # Avoid problems with paths longer than MAX_PATH
-    # https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation 
+    # https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
     dir = f'\\\\?\\{dir}'
 
   def ChmodAndRetry(func, path, _):
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 62029d3..02541fee 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -37642,6 +37642,15 @@
   <affected-action name="Bookmarks.Added"/>
 </action-suffix>
 
+<action-suffix separator="." ordering="suffix">
+  <suffix name="AccountStorage" label="Folder added in account storage."/>
+  <suffix name="LocalStorage"
+      label="Folder added in local storage which is not being synced."/>
+  <suffix name="LocalStorageSyncing"
+      label="Folder added in local storage which is being synced."/>
+  <affected-action name="Bookmarks.FolderAdded"/>
+</action-suffix>
+
 <action-suffix separator="_" ordering="suffix">
   <suffix name="AdaptiveButtonInTopToolbarCustomization_AddToBookmarks"
       label="For AdaptiveButtonInTopToolbarCustomization add to bookmarks
diff --git a/tools/metrics/actions/extract_actions.py b/tools/metrics/actions/extract_actions.py
index b943c77..2902878 100755
--- a/tools/metrics/actions/extract_actions.py
+++ b/tools/metrics/actions/extract_actions.py
@@ -216,6 +216,10 @@
   actions.add('Bookmarks.Added.AccountStorage')
   actions.add('Bookmarks.Added.LocalStorage')
   actions.add('Bookmarks.Added.LocalStorageSyncing')
+  actions.add('Bookmarks.FolderAdded')
+  actions.add('Bookmarks.FolderAdded.AccountStorage')
+  actions.add('Bookmarks.FolderAdded.LocalStorage')
+  actions.add('Bookmarks.FolderAdded.LocalStorageSyncing')
 
 
 def AddChromeOSActions(actions):
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 4fba9c2..b12d583 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -1869,6 +1869,12 @@
   <int value="1" label="In Session Idle"/>
 </enum>
 
+<enum name="AmbientVideoSessionStatus">
+  <int value="0" label="Success"/>
+  <int value="1" label="Failed"/>
+  <int value="2" label="Loading"/>
+</enum>
+
 <enum name="AMDDeviceId">
   <int value="5592" label="0x15D8, Picasso"/>
   <int value="5597"
@@ -3810,6 +3816,8 @@
   <int value="5" label="Shelf Button With Shift"/>
   <int value="6" label="Assistant Entry Point"/>
   <int value="7" label="Scroll from the shelf"/>
+  <int value="8" label="Browser"/>
+  <int value="9" label="Welcome Tour"/>
 </enum>
 
 <enum name="AppListSortOrder">
@@ -24773,7 +24781,7 @@
   <int value="51"
       label="Side sheet animation EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR"/>
   <int value="52"
-      label="Side sheet animation
+      label="Rounded corners position
              EXTRA_ACTIVITY_SIDE_SHEET_ROUNDED_CORNERS_POSITION"/>
 </enum>
 
@@ -31206,6 +31214,7 @@
   <int value="17" label="Projector transcription error"/>
   <int value="18" label="Low DriveFS free space quota"/>
   <int value="19" label="Video encoder does not support reconfiguration"/>
+  <int value="20" label="Stop screen recording keyboard shortcut"/>
 </enum>
 
 <enum name="EnhancedBookmarkViewMode">
@@ -34397,6 +34406,7 @@
   <int value="516" label="SMART_CARD_PROVIDER_PRIVATE_ON_CONTROL_REQUESTED"/>
   <int value="517" label="OS_EVENTS_ON_POWER_EVENT"/>
   <int value="518" label="SMART_CARD_PROVIDER_PRIVATE_ON_GET_ATTRIB_REQUESTED"/>
+  <int value="519" label="OS_EVENTS_ON_KEYBOARD_DIAGNOSTIC_EVENT"/>
 </enum>
 
 <enum name="ExtensionFileWriteResult">
@@ -36282,6 +36292,7 @@
   <int value="1790" label="AUTOTESTPRIVATE_INSTALLBRUSCHETTA"/>
   <int value="1791" label="AUTOTESTPRIVATE_REMOVEBRUSCHETTA"/>
   <int value="1792" label="AUTOFILLPRIVATE_AUTHENTICATEUSERTOEDITLOCALCARD"/>
+  <int value="1793" label="AUTOTESTPRIVATE_ISFEATUREENABLED"/>
 </enum>
 
 <enum name="ExtensionIconState">
@@ -42588,7 +42599,8 @@
   <int value="4574" label="CriticalCHRestartNavigationTiming"/>
   <int value="4575" label="TopLevelDocumentWithEmbeddedCredentials"/>
   <int value="4576" label="V8Navigator_GetInterestGroupAdAuctionData_Method"/>
-  <int value="4577" label="WebSerialBluetooth"/>
+  <int value="4577" label="LongAnimationFrameObserver"/>
+  <int value="4578" label="LongAnimationFrameRequested"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
@@ -42902,6 +42914,21 @@
   <int value="5" label="kDbCleanOutdatedDataError"/>
 </enum>
 
+<enum name="FeedActivityBucket">
+  <int value="0" label="No Activity">
+    The user has no activity in the last 28 days.
+  </int>
+  <int value="1" label="Low Activity">
+    The user has 1-7 days of activity in the last 28 days.
+  </int>
+  <int value="2" label="Medium Activity">
+    The user has 8-15 days of activity in the last 28 days.
+  </int>
+  <int value="3" label="High Activity">
+    The user has 16+ days of activity in the last 28 days.
+  </int>
+</enum>
+
 <enum name="FeedAutoplayEvent">
   <obsolete>
     Removed as of 05/2021. Replaced by FeedVideoPlayEvent.
@@ -62716,7 +62743,6 @@
   <int value="-29847483" label="MemoryAblation:enabled"/>
   <int value="-29507521" label="ContextualNudges:disabled"/>
   <int value="-28295905" label="AutofillEnableAccountWalletStorage:enabled"/>
-  <int value="-28079219" label="UseFakeAudioCaptureTimestamps:enabled"/>
   <int value="-27287076" label="DesktopPWAsTabStripSettings:disabled"/>
   <int value="-27213807" label="GlobalMediaControls:enabled"/>
   <int value="-25726674" label="CompressionDictionaryTransport:enabled"/>
@@ -64126,7 +64152,6 @@
   <int value="723318188" label="EnableUniveralLinks:disabled"/>
   <int value="723385329" label="SystemEmojiPickerClipboard:enabled"/>
   <int value="723619383" label="TopSitesFromSiteEngagement:enabled"/>
-  <int value="723894144" label="UseFakeAudioCaptureTimestamps:disabled"/>
   <int value="724052572" label="EnableFilesystemInIncognito"/>
   <int value="724189703" label="OptimizeNetworkBuffers:disabled"/>
   <int value="724208771" label="TabsInCBD:enabled"/>
@@ -68414,6 +68439,7 @@
   <int value="760" label="scroll-start-target-y"/>
   <int value="761" label="scroll-start-target"/>
   <int value="762" label="timeline-scope"/>
+  <int value="763" label="scrollbar-color"/>
 </enum>
 
 <enum name="MappedEditingCommands">
@@ -91737,6 +91763,13 @@
       label="User pasted something on the page and the warning was shown."/>
 </enum>
 
+<enum name="SafeBrowsingEnhancedProtegoPingType">
+  <int value="0" label="UnknownType"/>
+  <int value="1" label="None"/>
+  <int value="2" label="WithToken"/>
+  <int value="3" label="WithoutToken"/>
+</enum>
+
 <enum name="SafeBrowsingHPRTOperationResult">
   <int value="0" label="Success"/>
   <int value="1" label="Parse response error"/>
@@ -114704,6 +114737,8 @@
   <int value="58" label="Password Manager"/>
   <int value="59" label="Translate Page"/>
   <int value="60" label="Show Chrome Labs"/>
+  <int value="61" label="Install PWA"/>
+  <int value="62" label="Open in PWA window"/>
 </enum>
 
 <enum name="WrongConfigurationMetric">
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index d06c46a..146706c 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -4585,7 +4585,7 @@
 </histogram>
 
 <histogram name="Android.WebView.RequestedWithHeader.CommittedHeaderMode"
-    enum="CommittedRequestedWithHeaderMode" expires_after="2023-07-01">
+    enum="CommittedRequestedWithHeaderMode" expires_after="2024-05-01">
   <owner>pbirk@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -4600,7 +4600,7 @@
 
 <histogram
     name="Android.WebView.RequestedWithHeader.HadWebContentsForPartitionOrigin"
-    enum="BooleanAvailable" expires_after="2023-07-01">
+    enum="BooleanAvailable" expires_after="2024-05-01">
   <owner>pbirk@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -4633,7 +4633,7 @@
 
 <histogram
     name="Android.WebView.RequestedWithHeader.OnNavigationRequestedWithHeaderAllowListSize"
-    units="entries" expires_after="2023-07-01">
+    units="entries" expires_after="2024-05-01">
   <owner>pbirk@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -4644,7 +4644,7 @@
 </histogram>
 
 <histogram name="Android.WebView.RequestedWithHeader.OriginTrialEnabled"
-    enum="BooleanEnabled" expires_after="2023-07-01">
+    enum="BooleanEnabled" expires_after="2024-05-01">
   <owner>pbirk@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -4655,7 +4655,7 @@
 </histogram>
 
 <histogram name="Android.WebView.RequestedWithHeader.PageSchemeIsCryptographic"
-    enum="BooleanSecure" expires_after="2023-07-01">
+    enum="BooleanSecure" expires_after="2024-05-01">
   <owner>pbirk@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -4685,7 +4685,7 @@
 
 <histogram
     name="Android.WebView.RequestedWithHeader.SetRequestedWithHeaderModeAllowListSize"
-    units="entries" expires_after="2023-07-01">
+    units="entries" expires_after="2024-05-01">
   <owner>pbirk@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -4714,7 +4714,7 @@
 
 <histogram
     name="Android.WebView.RequestedWithHeader.SetServiceWorkerRequestedWithHeaderModeAllowListSize"
-    units="entries" expires_after="2023-07-01">
+    units="entries" expires_after="2024-05-01">
   <owner>pbirk@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml
index 264d5b7..7bdb0b67 100644
--- a/tools/metrics/histograms/metadata/apps/histograms.xml
+++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -22,6 +22,15 @@
 
 <histograms>
 
+<variants name="AppDisplayModes">
+<!-- Should be kept in sync with variants DisplayModes in
+  tools/metrics/histograms/metadata/ash/histograms.xml.
+-->
+
+  <variant name="ClamshellMode" summary="Clamshell mode"/>
+  <variant name="TabletMode" summary="Tablet mode"/>
+</variants>
+
 <variants name="AppType">
   <variant name="Arc" summary="Android apps"/>
   <variant name="Borealis" summary="Borealis apps"/>
@@ -1218,7 +1227,7 @@
     sort nudge shows initially in tablet (or clamshell), then the discovery
     duration is reported using the histogram for tablet (or clamshell).
   </summary>
-  <token key="TabletOrClamshell" variants="DisplayModes"/>
+  <token key="TabletOrClamshell" variants="AppDisplayModes"/>
 </histogram>
 
 <histogram name="Apps.AppList.SortOrderOnSessionStart.{TabletOrClamshell}"
@@ -1229,7 +1238,7 @@
     The app list sort order preserved in the pref service. Triggered when the
     pref service for the new session is ready.
   </summary>
-  <token key="TabletOrClamshell" variants="DisplayModes"/>
+  <token key="TabletOrClamshell" variants="AppDisplayModes"/>
 </histogram>
 
 <histogram
@@ -2223,7 +2232,7 @@
     The events that reset the app list pref sort order. Triggered when the pref
     sort order is reset.
   </summary>
-  <token key="TabletOrClamshell" variants="DisplayModes"/>
+  <token key="TabletOrClamshell" variants="AppDisplayModes"/>
 </histogram>
 
 <histogram
@@ -2236,7 +2245,7 @@
     smoothness of this animation. 100% represents the ideally smooth 60 frames
     per second.
   </summary>
-  <token key="TabletOrClamshell" variants="DisplayModes"/>
+  <token key="TabletOrClamshell" variants="AppDisplayModes"/>
 </histogram>
 
 <histogram name="Apps.Launcher.InstallAppFromLinkResult"
@@ -2270,7 +2279,7 @@
     The user-set sort order of the productivity launcher. Triggered when the
     launcher is set with a new order.
   </summary>
-  <token key="TabletOrClamshell" variants="DisplayModes"/>
+  <token key="TabletOrClamshell" variants="AppDisplayModes"/>
 </histogram>
 
 <histogram
@@ -2283,7 +2292,7 @@
     smoothness of this animation. 100% represents the ideally smooth 60 frames
     per second.
   </summary>
-  <token key="TabletOrClamshell" variants="DisplayModes"/>
+  <token key="TabletOrClamshell" variants="AppDisplayModes"/>
 </histogram>
 
 <histogram name="Apps.LockScreen.AppsProfile.Creation.Duration" units="ms"
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 30418a54..356d69c0 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -46,6 +46,10 @@
 </variants>
 
 <variants name="DisplayModes">
+<!-- Should be kept in sync with variants AppDisplayModes in
+  tools/metrics/histograms/metadata/apps/histograms.xml.
+-->
+
   <variant name="ClamshellMode" summary="Clamshell mode"/>
   <variant name="TabletMode" summary="Tablet mode"/>
 </variants>
@@ -214,6 +218,7 @@
     <variant name="ShowStylusTools"/>
     <variant name="ShowTaskManager"/>
     <variant name="StartAssistant"/>
+    <variant name="StopScreenRecording"/>
     <variant name="Suspend"/>
     <variant name="SwapPrimaryDisplay"/>
     <variant name="SwitchIme"/>
@@ -503,6 +508,21 @@
   </summary>
 </histogram>
 
+<histogram name="Ash.AmbientMode.VideoPlaybackStatus.{Settings}"
+    enum="AmbientVideoSessionStatus" expires_after="2023-12-01">
+  <owner>esum@google.com</owner>
+  <owner>xiaohuic@chromium.org</owner>
+  <summary>
+    Emitted at the end of each ambient mode session that renders {Settings}.
+    Only applies to ambient video themes. Tracks whether video playback started
+    successfully in each ambient video session. Ideally, there are nothing but
+    success and loading statuses being recorded (the latter should be rare
+    because it means the user killed the session right as the video was being
+    loaded).
+  </summary>
+  <token key="Settings" variants="AmbientUiSettings"/>
+</histogram>
+
 <histogram name="Ash.AmbientMode.VideoSmoothness.{Settings}" units="%"
     expires_after="2023-12-01">
   <owner>esum@google.com</owner>
@@ -3777,6 +3797,30 @@
   </summary>
 </histogram>
 
+<histogram name="Ash.Login.TotalFirstSessionDuration" units="minutes"
+    expires_after="2024-05-12">
+  <owner>raging@google.com</owner>
+  <owner>alemate@chromium.org</owner>
+  <owner>cros-lurs@google.com</owner>
+  <summary>
+    Total user first session time between when the user was added to the device
+    and session exit or device shutdown. Reported for primary users only.
+  </summary>
+</histogram>
+
+<histogram name="Ash.Login.TotalSessionDuration" units="minutes"
+    expires_after="2024-05-12">
+  <owner>raging@google.com</owner>
+  <owner>alemate@chromium.org</owner>
+  <owner>rsorokin@chromium.org</owner>
+  <owner>cros-lurs@google.com</owner>
+  <summary>
+    Total user session time between sign-in and session exit or device shutdown.
+    Reported for primary users only. First sessions are excluded and reported in
+    a separate histogram: Ash.Login.TotalFirstSessionDuration.
+  </summary>
+</histogram>
+
 <histogram base="true" name="Ash.LoginAnimation.Duration" units="ms"
     expires_after="2023-10-08">
   <owner>oshima@chromium.org</owner>
@@ -6439,6 +6483,17 @@
   </summary>
 </histogram>
 
+<histogram name="Ash.VideoConference.NumberOfRepeatedShows" units="shows"
+    expires_after="2024-03-16">
+  <owner>leandre@chromium.org</owner>
+  <owner>cros-status-area-eng@google.com</owner>
+  <summary>
+    Record the number of times that the video conference tray repeatedly shows
+    per 100ms. Emitted when the sequence of consecutive shows in the video
+    conference tray has finished.
+  </summary>
+</histogram>
+
 <histogram name="Ash.VideoConference.ReturnToApp.Click"
     enum="VideoConferenceAppType" expires_after="2024-03-16">
   <owner>leandre@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index ea27f37..5c956db 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -29,6 +29,37 @@
       summary="Byte size of WebP images that fall into this category."/>
 </variants>
 
+<variants name="BlinkRequestDestination">
+<!-- Should be kept in sync with variants RequestDestination in
+  tools/metrics/histograms/metadata/page/histograms.xml and NetworkRequestDestination
+  in tools/metrics/histograms/metadata/network/histograms.xml.
+-->
+
+  <variant name="audio"/>
+  <variant name="audioworklet"/>
+  <variant name="document"/>
+  <variant name="embed"/>
+  <variant name="empty"/>
+  <variant name="fencedframe"/>
+  <variant name="font"/>
+  <variant name="frame"/>
+  <variant name="iframe"/>
+  <variant name="image"/>
+  <variant name="manifest"/>
+  <variant name="object"/>
+  <variant name="paintworklet"/>
+  <variant name="report"/>
+  <variant name="script"/>
+  <variant name="serviceworker"/>
+  <variant name="sharedworker"/>
+  <variant name="style"/>
+  <variant name="track"/>
+  <variant name="video"/>
+  <variant name="webbundle"/>
+  <variant name="worker"/>
+  <variant name="xslt"/>
+</variants>
+
 <variants name="BlinkVisibleLoadTimeSuffixes">
   <variant name="" summary="Aggregated across all connection types"/>
   <variant name=".2G" summary="2G effective connection type"/>
@@ -2413,7 +2444,7 @@
     same process isolation policies. Recorded when ResourceFetcher fetches a
     resource from network. This histogram is for `{Destination}` destination.
   </summary>
-  <token key="Destination" variants="RequestDestination"/>
+  <token key="Destination" variants="BlinkRequestDestination"/>
 </histogram>
 
 <histogram
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
index 5c5fc9c5..3a5ba65 100644
--- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml
+++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -571,20 +571,26 @@
   </summary>
 </histogram>
 
-<histogram name="Bookmarks.Storage.TimeToLoadAtStartup2" units="ms"
-    expires_after="2023-08-27">
+<histogram name="Bookmarks.Storage.TimeToLoadAtStartup2{StorageState}"
+    units="ms" expires_after="2023-08-27">
   <owner>wylieb@chromium.org</owner>
   <owner>chrome-collections@google.com</owner>
   <component>UI&gt;Browser&gt;Bookmarks</component>
   <summary>
     Duration of loading the bookmarks file, recorded when the bookmark model is
-    loaded.
+    loaded {StorageState}.
 
     Opening a guest session (guest profile) also causes an emit to this
     histogram even though guest sessions don't typically allow bookmarks. (The
     value emitted is typically zero.) Under certain enterpise configuration,
     guest sessions can have bookmarks.
   </summary>
+  <token key="StorageState">
+    <variant name="" summary="irrespective of storage state"/>
+    <variant name=".AccountStorage" summary="with account storage"/>
+    <variant name=".LocalStorage" summary="with local storage not syncing"/>
+    <variant name=".LocalStorageSyncing" summary="with local storage syncing"/>
+  </token>
 </histogram>
 
 <histogram name="Bookmarks.Times.OnProfileLoad.MostRecentlyAddedFolderInDays"
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml
index cda1f6e..6b6308f 100644
--- a/tools/metrics/histograms/metadata/chromeos/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1414,8 +1414,11 @@
   </token>
 </histogram>
 
+<!-- This histogram was expired for about three weeks from 2023-05-01 to
+2023-05-25. -->
+
 <histogram name="ChromeOS.IioService.SensorClientConcurrent" units="clients"
-    expires_after="2023-05-01">
+    expires_after="2024-05-01">
   <owner>chenghaoyang@chromium.org</owner>
   <owner>chromeos-sensors-eng@google.com</owner>
   <summary>
@@ -1425,8 +1428,11 @@
   </summary>
 </histogram>
 
+<!-- This histogram was expired for about three weeks from 2023-05-01 to
+2023-05-25. -->
+
 <histogram name="ChromeOS.IioService.SensorObserver" units="observers"
-    expires_after="2023-05-01">
+    expires_after="2024-05-01">
   <owner>chenghaoyang@chromium.org</owner>
   <owner>chromeos-sensors-eng@google.com</owner>
   <summary>
@@ -1436,8 +1442,11 @@
   </summary>
 </histogram>
 
+<!-- This histogram was expired for about three weeks from 2023-05-01 to
+2023-05-25. -->
+
 <histogram name="ChromeOS.IioService.SensorObserverOpen" units="observers"
-    expires_after="2023-05-01">
+    expires_after="2024-05-01">
   <owner>chenghaoyang@chromium.org</owner>
   <owner>chromeos-sensors-eng@google.com</owner>
   <summary>
@@ -1447,8 +1456,11 @@
   </summary>
 </histogram>
 
+<!-- This histogram was expired for about three weeks from 2023-05-01 to
+2023-05-25. -->
+
 <histogram name="ChromeOS.IioService.SensorUsage.{Frequency}Hz"
-    enum="ChromeOSIioServiceSensorUsage" expires_after="2023-05-01">
+    enum="ChromeOSIioServiceSensorUsage" expires_after="2024-05-01">
   <owner>chenghaoyang@chromium.org</owner>
   <owner>chromeos-sensors-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml
index 984bf37..1c7dd2c 100644
--- a/tools/metrics/histograms/metadata/content/histograms.xml
+++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -1994,6 +1994,24 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSuggestions.{FeedType}.Activity"
+    enum="FeedActivityBucket" expires_after="2023-11-24">
+  <owner>guiperez@google.com</owner>
+  <owner>feed@chromium.org</owner>
+  <summary>
+    Tracks user activity buckets with {FeedType}. Each bucket composed of the
+    user's activity level. Logs the for the first time 1 day after the metric is
+    active (only on first time use), then logs an activity bucket after at least
+    24hrs from the last log have elapsed. When the &quot;Engaged&quot; metric is
+    triggered we log one more day of activity during the past 28 days.
+  </summary>
+  <token key="FeedType">
+    <variant name="Feed" summary="the For-You feed"/>
+    <variant name="Feed.AllFeeds" summary="All Feeds combined"/>
+    <variant name="Feed.WebFeed" summary="the Following/Web Feed"/>
+  </token>
+</histogram>
+
 <histogram name="ContentSuggestions.{FeedType}.CardIndexOnSwitch" units="index"
     expires_after="2023-04-21">
   <owner>adamta@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index d6b26e38..41244c1a 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -545,6 +545,16 @@
       name="Autofill.SaveCreditCardPromptResult.Upload.Reshows"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="AutofillSaveCreditCardPromptWithSameLastFourButDifferentExpiration"
+    separator=".">
+  <suffix name="WithSameLastFourButDifferentExpiration"
+      label="When the same last four but different expiration dates"/>
+  <affected-histogram name="Autofill.CreditCardInfoBar.Server"/>
+  <affected-histogram
+      name="Autofill.SaveCreditCardPromptOffer.Upload.FirstShow"/>
+  <affected-histogram name="Autofill.SaveCreditCardPromptOffer.Upload.Reshows"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="AutofillStoredCardHasNickname" separator=".">
   <owner>sujiezhu@google.com</owner>
   <owner>jsaul@google.com</owner>
@@ -3152,10 +3162,6 @@
   <affected-histogram
       name="PageLoad.Clients.DocWrite.Block.ParseTiming.ParseBlockedOnScriptLoad"/>
   <affected-histogram
-      name="PageLoad.Clients.MultiTabLoading.DocumentTiming.NavigationToDOMContentLoadedEventFired"/>
-  <affected-histogram
-      name="PageLoad.Clients.MultiTabLoading.DocumentTiming.NavigationToLoadEventFired"/>
-  <affected-histogram
       name="PageLoad.Clients.ServiceWorker2.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram
       name="PageLoad.Clients.ServiceWorker2.ParseTiming.NavigationToParseStart"/>
@@ -3278,27 +3284,6 @@
       name="PageLoad.Clients.LoadingPredictor2.PaintTiming.NavigationToFirstContentfulPaint"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PageLoadMetricsClientsMultiTabLoading" separator="."
-    ordering="prefix">
-  <suffix name="Clients.MultiTabLoading"
-      label="PageLoadMetrics for page loads that started while there are
-             other loading tabs."/>
-  <suffix name="Clients.MultiTabLoading.2OrMore"
-      label="PageLoadMetrics for page loads that started while there are 2 or
-             more other loading tabs."/>
-  <suffix name="Clients.MultiTabLoading.5OrMore"
-      label="PageLoadMetrics for page loads that started while there are 5 or
-             more other loading tabs."/>
-  <affected-histogram
-      name="PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired"/>
-  <affected-histogram
-      name="PageLoad.DocumentTiming.NavigationToLoadEventFired"/>
-  <affected-histogram
-      name="PageLoad.PaintTiming.ForegroundToFirstContentfulPaint"/>
-  <affected-histogram
-      name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PageLoadMetricsClientsNoScriptPreview" separator="."
     ordering="prefix">
   <suffix name="Clients.NoScriptPreview"
@@ -5941,12 +5926,14 @@
   <suffix name="Find" label=""/>
   <suffix name="HelpPage" label=""/>
   <suffix name="ImportSettings" label=""/>
+  <suffix name="InstallPwa" label=""/>
   <suffix name="ManageExtensions" label=""/>
   <suffix name="NewIncognitoWindow" label=""/>
   <suffix name="NewTab" label=""/>
   <suffix name="NewWindow" label=""/>
   <suffix name="OpenBookmark" label=""/>
   <suffix name="OpenInChrome" label=""/>
+  <suffix name="OpenInPwaWindow" label=""/>
   <suffix name="OpenRecentTab" label=""/>
   <suffix name="PasswordManager" label=""/>
   <suffix name="Paste" label=""/>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index fc8d96b..71b0dc33 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -3711,7 +3711,7 @@
 </histogram>
 
 <histogram name="Media.Midi.SendReceiveUsage" enum="MidiSendReceiveUsage"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -3726,7 +3726,7 @@
 </histogram>
 
 <histogram name="Media.Midi.SysExMessageSizeUpTo1MB" units="bytes"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -3737,7 +3737,7 @@
   </summary>
 </histogram>
 
-<histogram name="Media.Midi.Usage" enum="MidiUsage" expires_after="2023-06-30">
+<histogram name="Media.Midi.Usage" enum="MidiUsage" expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml
index c965cb92..66335a8 100644
--- a/tools/metrics/histograms/metadata/navigation/histograms.xml
+++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -35,16 +35,10 @@
 </variants>
 
 <variants name="PrerenderTriggerType">
-<!--
-Also used in tools/metrics/histograms/metadata/page/histograms.xml.
+<!-- Should be kept in sync with variants PagePrerenderTriggerType in
+  tools/metrics/histograms/metadata/page/histograms.xml.
 -->
 
-  <variant name="">
-    <obsolete>
-      Base histogram. Use suffixes of this histogram instead. Non-suffix name
-      was removed in Feb 2022.
-    </obsolete>
-  </variant>
   <variant name=".Embedder_BookmarkBar"/>
   <variant name=".Embedder_DefaultSearchEngine"/>
   <variant name=".Embedder_DirectURLInput"/>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml
index 299c72c..6388a22 100644
--- a/tools/metrics/histograms/metadata/network/histograms.xml
+++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -49,6 +49,37 @@
   <variant name="L2tpIpsec" summary="L2TP/IPsec"/>
 </variants>
 
+<variants name="NetworkRequestDestination">
+<!-- Should be kept in sync with variants RequestDestination in
+  tools/metrics/histograms/metadata/page/histograms.xml and BlinkRequestDestination
+  in tools/metrics/histograms/metadata/blink/histograms.xml.
+-->
+
+  <variant name="audio"/>
+  <variant name="audioworklet"/>
+  <variant name="document"/>
+  <variant name="embed"/>
+  <variant name="empty"/>
+  <variant name="fencedframe"/>
+  <variant name="font"/>
+  <variant name="frame"/>
+  <variant name="iframe"/>
+  <variant name="image"/>
+  <variant name="manifest"/>
+  <variant name="object"/>
+  <variant name="paintworklet"/>
+  <variant name="report"/>
+  <variant name="script"/>
+  <variant name="serviceworker"/>
+  <variant name="sharedworker"/>
+  <variant name="style"/>
+  <variant name="track"/>
+  <variant name="video"/>
+  <variant name="webbundle"/>
+  <variant name="worker"/>
+  <variant name="xslt"/>
+</variants>
+
 <variants name="PhysicalTechnology">
   <variant name="Cellular" summary="Cellular"/>
   <variant name="Ethernet" summary="Ethernet"/>
@@ -4005,6 +4036,16 @@
   </summary>
 </histogram>
 
+<histogram name="NetworkService.CorsURLLoaderFactoryStart" enum="Boolean"
+    expires_after="2023-11-19">
+  <owner>yoichio@chromium.org</owner>
+  <owner>blink-network-stack@google.com</owner>
+  <summary>
+    Records when CorsURLLoaderFactory::CreateLoaderAndStart is called from mojo
+    to investigate another histogram issue. See https://crbug.com/1439721.
+  </summary>
+</histogram>
+
 <histogram name="NetworkService.CrossOriginResourcePolicy.ReportOnlyResult"
     enum="NetworkServiceCorpResult" expires_after="2020-09-30">
   <owner>mkwst@chromium.org</owner>
@@ -4048,6 +4089,16 @@
   </summary>
 </histogram>
 
+<histogram name="NetworkService.InitializedTime" units="ms"
+    expires_after="2023-11-19">
+  <owner>yoichio@chromium.org</owner>
+  <owner>blink-network-stack@google.com</owner>
+  <summary>
+    Recoards the time from origin to the network service starts when the network
+    service is initialized. See https://crbug.com/1439721.
+  </summary>
+</histogram>
+
 <histogram name="NetworkService.MdnsResponder.ServiceError"
     enum="MdnsResponderServiceError" expires_after="M81">
   <owner>qingsi@chromium.org</owner>
@@ -4082,7 +4133,7 @@
     response won't be stored in the in-memory cache. This histogram is recorded
     for {RequestDestination}.
   </summary>
-  <token key="RequestDestination" variants="RequestDestination"/>
+  <token key="RequestDestination" variants="NetworkRequestDestination"/>
 </histogram>
 
 <histogram name="NetworkService.MemoryCache.EntryStatus"
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index e6b257e..3e589543593 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -73,24 +73,6 @@
   <variant name=".Video" summary="The context menu was shown for a video"/>
 </variants>
 
-<variants name="DIPSCookieMode">
-  <variant name=".Block3PC"
-      summary="in a NON-off-the-record profile, with third-party cookies
-               blocked"/>
-  <variant name=".OffTheRecord"
-      summary="in an off-the-record profile, with third-party cookies enabled"/>
-  <variant name=".OffTheRecord_Block3PC"
-      summary="in an off-the-record profile, with third-party cookies blocked"/>
-  <variant name=".Standard"
-      summary="in a NON-off-the-record profile, with third-party cookies
-               enabled"/>
-</variants>
-
-<variants name="DIPSRedirectType">
-  <variant name="Client" summary="client-side"/>
-  <variant name="Server" summary="server-side"/>
-</variants>
-
 <variants name="GridTabSwitcherMessageTypes">
   <variant name="PriceAlertsMessageCard"
       summary="the promo message for price notifications"/>
@@ -149,27 +131,6 @@
   <variant name=".NtpRealbox" summary="from the realbox on the NTP"/>
 </variants>
 
-<variants name="ProcessName">
-  <variant name="BrowserProcess" summary=""/>
-  <variant name="GPUProcess" summary=""/>
-  <variant name="NetworkProcess" summary=""/>
-  <variant name="PluginProcess" summary=""/>
-  <variant name="PPAPIFlashProcess" summary="">
-    <obsolete>
-      Ported over from previous suffix based definition where it was removed on
-      2021-03 now that support for Flash has been removed.
-    </obsolete>
-  </variant>
-  <variant name="PPAPIProcess" summary=""/>
-  <variant name="RendererExtensionEventProcess" summary=""/>
-  <variant name="RendererExtensionPersistentProcess" summary=""/>
-  <variant name="RendererProcess" summary=""/>
-<!-- "Total" variant used to exist but was folded into the histogram names and could not be made obsolete. -->
-
-  <variant name="UtilityProcess" summary=""/>
-  <variant name="WorkerProcess" summary=""/>
-</variants>
-
 <variants name="VoiceIntentTargetVariant">
   <variant name="Assistant" summary="Assistant voice transcription."/>
   <variant name="System" summary="System voice transcription."/>
@@ -9210,10 +9171,12 @@
 </histogram>
 
 <histogram name="PendingBeaconHost.Action" enum="PendingBeaconHostAction"
-    expires_after="M112">
+    expires_after="M115">
   <owner>mych@chromium.org</owner>
   <owner>pending-beacon-experiment@chromium.org</owner>
   <summary>
+    Warning: this histogram was expired from M113 to M115; data may be missing.
+
     The type of PendingBeacon-related action that the browser has performed.
 
     This is only recorded when the PendingBeacon API is called to create, send,
@@ -9224,10 +9187,12 @@
 </histogram>
 
 <histogram name="PendingBeaconHost.BatchAction"
-    enum="PendingBeaconHostBatchAction" expires_after="M112">
+    enum="PendingBeaconHostBatchAction" expires_after="M115">
   <owner>mych@chromium.org</owner>
   <owner>pending-beacon-experiment@chromium.org</owner>
   <summary>
+    Warning: this histogram was expired from M113 to M115; data may be missing.
+
     The type of batch PendingBeacon-related action that the browser has
     performed. A batch action means the browser is about to batch process all
     queued pending beacon requests at once.
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml
index e7b6c0a..de4611c6 100644
--- a/tools/metrics/histograms/metadata/page/histograms.xml
+++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -30,6 +30,18 @@
   <variant name="5000ms"/>
 </variants>
 
+<variants name="PagePrerenderTriggerType">
+<!-- Should be kept in sync with variants PrerenderTriggerType in
+  tools/metrics/histograms/metadata/navigation/histograms.xml.
+-->
+
+  <variant name=".Embedder_BookmarkBar"/>
+  <variant name=".Embedder_DefaultSearchEngine"/>
+  <variant name=".Embedder_DirectURLInput"/>
+  <variant name=".SpeculationRule"/>
+  <variant name=".SpeculationRuleFromIsolatedWorld"/>
+</variants>
+
 <variants name="PrivacySandboxAdsApi">
   <variant name="AttributionReporting"/>
   <variant name="FencedFrames"/>
@@ -40,6 +52,11 @@
 </variants>
 
 <variants name="RequestDestination">
+<!-- Should be kept in sync with variants BlinkRequestDestination in
+  tools/metrics/histograms/metadata/blink/histograms.xml and NetworkRequestDestination
+  in tools/metrics/histograms/metadata/network/histograms.xml.
+-->
+
   <variant name="audio"/>
   <variant name="audioworklet"/>
   <variant name="document"/>
@@ -894,6 +911,69 @@
 </histogram>
 
 <histogram
+    name="PageLoad.Clients.MultiTabLoading{OtherLoadingCount}.{Timing}{Background}"
+    units="ms" expires_after="2023-11-01">
+  <owner>chikamune@chromium.org</owner>
+  <owner>chrome-loading@google.com</owner>
+  <summary>{Timing} {OtherLoadingCount} {Background}</summary>
+  <token key="OtherLoadingCount">
+    <variant name=""
+        summary="Only recorded when there were 1 or more other loading tabs
+                 (the same as '1OrMore')."/>
+    <variant name=".1OrMore"
+        summary="Only recorded when there were 1 or more other loading tabs."/>
+    <variant name=".2OrMore"
+        summary="Only recorded when there were 2 or more other loading tabs."/>
+    <variant name=".5OrMore"
+        summary="Only recorded when there were 5 or more other loading tabs."/>
+    <variant name=".With_0_OtherLoading"
+        summary="Only recorded when there was no other loading tab."/>
+    <variant name=".With_1_OtherLoading"
+        summary="Only recorded when there was 1 other loading tab."/>
+    <variant name=".With_2_OtherLoading"
+        summary="Only recorded when there were 2 other loading tabs."/>
+    <variant name=".With_3_OtherLoading"
+        summary="Only recorded when there were 3 other loading tabs."/>
+    <variant name=".With_4_OtherLoading"
+        summary="Only recorded when there were 4 other loading tabs."/>
+    <variant name=".With_5_OtherLoading"
+        summary="Only recorded when there were 5 other loading tabs."/>
+  </token>
+  <token key="Timing">
+    <variant name="DocumentTiming.NavigationToDOMContentLoadedEventFired"
+        summary="Measures the time from navigation timing's navigation start
+                 to the time the DOMContentLoaded event is fired, for main
+                 frame documents."/>
+    <variant name="DocumentTiming.NavigationToLoadEventFired"
+        summary="Measures the time from navigation timing's navigation start
+                 to the time the load event is fired, for main frame
+                 documents."/>
+    <variant name="Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"
+        summary="Measures the time from navigation start to first meaningful
+                 paint."/>
+    <variant name="PaintTiming.ForegroundToFirstContentfulPaint"
+        summary="Measures the time from a background tab being switched to
+                 the foreground to the time the first contentful paint is
+                 performed, for main frame documents."/>
+    <variant name="PaintTiming.NavigationToFirstContentfulPaint"
+        summary="Measures the time from navigation start to first contentful
+                 paint."/>
+    <variant name="PaintTiming.NavigationToLargestContentfulPaint"
+        summary="Measures the time from navigation timing's navigation start
+                 to the time the largest content (text or image) is first
+                 painted, across all frames. Excludes any content painted
+                 after user input. Includes content that has been removed
+                 from the page."/>
+  </token>
+  <token key="Background">
+    <variant name="" summary=""/>
+    <variant name=".Background"
+        summary="The page was backgrounded at least once from navigation
+                 start to this event."/>
+  </token>
+</histogram>
+
+<histogram
     name="PageLoad.Clients.Prerender.InteractiveTiming.FirstInputDelay4{PrerenderTriggerType}"
     units="ms" expires_after="2023-09-03">
   <owner>ksakamoto@chromium.org</owner>
@@ -903,11 +983,7 @@
     prerendered and were later activated. Note that prerendered page loads are
     excluded from PageLoad.InteractiveTiming.FirstInputDelay4.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram
@@ -921,11 +997,7 @@
     page loads are excluded from
     PageLoad.LayoutInstability.CumulativeShiftScore.MainFrame.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram
@@ -938,11 +1010,7 @@
     were prerendered and were later activated. Note that prerendered page loads
     are excluded from PageLoad.LayoutInstability.CumulativeShiftScore.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram
@@ -956,11 +1024,7 @@
     prerendered page loads are excluded from
     PageLoad.LayoutInstability.MaxCumulativeShiftScore.SessionWindow.Gap1000ms.Max5000ms2.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram
@@ -974,11 +1038,7 @@
     attribute of PerformanceNavigationTiming. Recorded when a prerendered page
     is activated.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram
@@ -993,11 +1053,7 @@
     loads are excluded from
     PageLoad.PaintTiming.NavigationToFirstContentfulPaint.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram
@@ -1011,11 +1067,7 @@
     activation navigation start. Note that prerendered page loads are excluded
     from PageLoad.PaintTiming.NavigationToFirstPaint.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram
@@ -1030,11 +1082,7 @@
     loads are excluded from
     PageLoad.PaintTiming.NavigationToLargestContentfulPaint2.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram
@@ -2466,11 +2514,7 @@
     This metric is used to monitor whether preload cache intercepting logic
     causes extra page loading errors.
   </summary>
-<!-- PrerenderTriggerType variant is defined in
-  tools/metrics/histograms/metadata/navigation/histograms.xml.
--->
-
-  <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/>
+  <token key="PrerenderTriggerType" variants="PagePrerenderTriggerType"/>
 </histogram>
 
 <histogram name="PageLoad.Internal.Prerender2.Event"
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml
index 7578f93d..85cfb93 100644
--- a/tools/metrics/histograms/metadata/permissions/histograms.xml
+++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -23,6 +23,10 @@
 <histograms>
 
 <variants name="AllPermissionTypes">
+<!-- Should be kept in sync with variants SettingsAllPermissionTypes in
+  tools/metrics/histograms/metadata/settings/histograms.xml.
+-->
+
   <variant name="AR"/>
   <variant name="AudioAndVideoCapture"/>
   <variant name="AudioCapture"/>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml
index ea6eb2c..f1721a4 100644
--- a/tools/metrics/histograms/metadata/power/histograms.xml
+++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -65,6 +65,27 @@
       summary="every sample recorded after the first one"/>
 </variants>
 
+<variants name="ProcessName">
+  <variant name="BrowserProcess" summary=""/>
+  <variant name="GPUProcess" summary=""/>
+  <variant name="NetworkProcess" summary=""/>
+  <variant name="PluginProcess" summary=""/>
+  <variant name="PPAPIFlashProcess" summary="">
+    <obsolete>
+      Ported over from previous suffix based definition where it was removed on
+      2021-03 now that support for Flash has been removed.
+    </obsolete>
+  </variant>
+  <variant name="PPAPIProcess" summary=""/>
+  <variant name="RendererExtensionEventProcess" summary=""/>
+  <variant name="RendererExtensionPersistentProcess" summary=""/>
+  <variant name="RendererProcess" summary=""/>
+<!-- "Total" variant used to exist but was folded into the histogram names and could not be made obsolete. -->
+
+  <variant name="UtilityProcess" summary=""/>
+  <variant name="WorkerProcess" summary=""/>
+</variants>
+
 <variants name="UsageScenario">
 <!--
   Variants describing the usage scenario for a time interval. Consider updating
diff --git a/tools/metrics/histograms/metadata/privacy/histograms.xml b/tools/metrics/histograms/metadata/privacy/histograms.xml
index 03bb37a8..b9c75a9 100644
--- a/tools/metrics/histograms/metadata/privacy/histograms.xml
+++ b/tools/metrics/histograms/metadata/privacy/histograms.xml
@@ -19,6 +19,24 @@
 
 <histograms>
 
+<variants name="DIPSCookieMode">
+  <variant name=".Block3PC"
+      summary="in a NON-off-the-record profile, with third-party cookies
+               blocked"/>
+  <variant name=".OffTheRecord"
+      summary="in an off-the-record profile, with third-party cookies enabled"/>
+  <variant name=".OffTheRecord_Block3PC"
+      summary="in an off-the-record profile, with third-party cookies blocked"/>
+  <variant name=".Standard"
+      summary="in a NON-off-the-record profile, with third-party cookies
+               enabled"/>
+</variants>
+
+<variants name="DIPSRedirectType">
+  <variant name="Client" summary="client-side"/>
+  <variant name="Server" summary="server-side"/>
+</variants>
+
 <histogram name="Privacy.AboutThisSite.PageLoadValidation"
     enum="AboutThisSiteStatus" expires_after="2023-10-15">
   <owner>dullweber@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index 7ed6a00..293c676 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -584,6 +584,21 @@
   </summary>
 </histogram>
 
+<histogram name="SafeBrowsing.Enhanced.ProtegoRequestSentInLast24Hours"
+    enum="SafeBrowsingEnhancedProtegoPingType" expires_after="2024-05-18">
+  <owner>jacastro@chromium.org</owner>
+  <owner>chrome-counter-abuse-alerts@google.com</owner>
+  <summary>
+    Records whether an ESB user has sent a Protego ping to the Safe Browsing API
+    servers within the last 24 hours. If a ping was sent since the last time
+    this metric was logged, then this metric will report the type of that ping,
+    otherwise it will report that none was sent. If the user has sent a ping of
+    multiple types since the last time this metric was logged, then only the
+    type of the most recent ping will be reported. This metric is logged at most
+    once per day and only for users that have enhanced protection enabled.
+  </summary>
+</histogram>
+
 <histogram name="SafeBrowsing.EsbDisabled.LastBypassEventType"
     enum="SBMetricsCollectorEventType" expires_after="2024-03-23">
   <owner>xinghuilu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml
index b427b31..0d44806b6 100644
--- a/tools/metrics/histograms/metadata/settings/histograms.xml
+++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -22,6 +22,36 @@
 
 <histograms>
 
+<variants name="SettingsAllPermissionTypes">
+<!-- Should be kept in sync with variants AllPermissionTypes in
+  tools/metrics/histograms/metadata/permissions/histograms.xml.
+-->
+
+  <variant name="AR"/>
+  <variant name="AudioAndVideoCapture"/>
+  <variant name="AudioCapture"/>
+  <variant name="CameraPanTiltZoom"/>
+  <variant name="ClipboardReadWrite"/>
+  <variant name="Geolocation"/>
+  <variant name="IdleDetection"/>
+  <variant name="LocalFonts"/>
+  <variant name="MidiSysEx"/>
+  <variant name="MultipleDownload"/>
+  <variant name="Nfc"/>
+  <variant name="Notifications"/>
+  <variant name="PaymentHandler"/>
+  <variant name="ProtectedMedia"/>
+  <variant name="Quota"/>
+  <variant name="RegisterProtocolHandler"/>
+  <variant name="SecurityKeyAttestation"/>
+  <variant name="StorageAccess"/>
+  <variant name="TopLevelStorageAccess"/>
+  <variant name="U2fApiRequest"/>
+  <variant name="VideoCapture"/>
+  <variant name="VR"/>
+  <variant name="WindowPlacement"/>
+</variants>
+
 <histogram name="Settings.AdvancedSpellcheck.OnStartup" enum="BooleanEnabled"
     expires_after="2023-05-07">
   <obsolete>
@@ -664,7 +694,7 @@
     a permission that was previously revoked by the unused site permission
     module of SafetyCheck.
   </summary>
-  <token key="PermissionType" variants="AllPermissionTypes"/>
+  <token key="PermissionType" variants="SettingsAllPermissionTypes"/>
   <token key="SourceUI">
     <variant name="Prompt"/>
     <variant name="Settings"/>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml
index 6344ba0..73f2b4c 100644
--- a/tools/metrics/histograms/metadata/tab/histograms.xml
+++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -1642,7 +1642,7 @@
 </histogram>
 
 <histogram name="Tabs.SavedTabLoadTime.{SavedTabMethod}.{SavedTabLoadResult}"
-    units="ms" expires_after="2023-05-30">
+    units="ms" expires_after="2024-05-22">
   <owner>davidjm@chromium.org</owner>
   <owner>nyquist@chromium.org</owner>
   <owner>dtrainor@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/web_audio/histograms.xml b/tools/metrics/histograms/metadata/web_audio/histograms.xml
index 6094c7ba..426248d 100644
--- a/tools/metrics/histograms/metadata/web_audio/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_audio/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="WebAudio.AudioBuffer.Length" units="frames"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <summary>
@@ -33,7 +33,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioBuffer.NumberOfChannels" units="units"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -55,7 +55,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioBuffer.SampleRateRatio384kHz" units="units"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -67,7 +67,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContext.CreateTime" units="ms"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>cduvall@chromium.org</owner>
@@ -113,7 +113,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContext.MaxChannelsAvailable" units="units"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -147,7 +147,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContextOptions.sampleRateRatio" units="units"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -194,7 +194,7 @@
 </histogram>
 
 <histogram name="WebAudio.Autoplay" enum="WebAudioAutoplayStatus"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -206,7 +206,7 @@
 </histogram>
 
 <histogram name="WebAudio.Autoplay.CrossOrigin" enum="WebAudioAutoplayStatus"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -217,7 +217,7 @@
 </histogram>
 
 <histogram name="WebAudio.Autoplay.UnlockType"
-    enum="WebAudioAutoplayUnlockType" expires_after="2023-06-30">
+    enum="WebAudioAutoplayUnlockType" expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -228,7 +228,7 @@
 </histogram>
 
 <histogram name="WebAudio.BiquadFilter.Type" enum="BiquadFilterType"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -241,7 +241,7 @@
 </histogram>
 
 <histogram name="WebAudio.ConvolverNode.ImpulseResponseLength" units="ms"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <summary>
@@ -251,7 +251,7 @@
 </histogram>
 
 <histogram name="WebAudio.IIRFilterNode.Order" units="units"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <summary>
@@ -262,7 +262,7 @@
 </histogram>
 
 <histogram name="WebAudio.OfflineAudioContext.CreateTime" units="ms"
-    expires_after="2023-06-30">
+    expires_after="2023-12-01">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>cduvall@chromium.org</owner>
diff --git a/tools/perf/benchmarks/speedometer2.py b/tools/perf/benchmarks/speedometer2.py
index 0bc89856..4482b31 100644
--- a/tools/perf/benchmarks/speedometer2.py
+++ b/tools/perf/benchmarks/speedometer2.py
@@ -132,7 +132,7 @@
   Explicitly named version."""
 
   # TODO(cbruni): update source folder name to speedometer20 here.
-  _SOURCE_DIR = os.path.join(_PERF_TEST_DIR, 'speedometer')
+  _SOURCE_DIR = os.path.join(_PERF_TEST_DIR, 'speedometer20')
 
   @classmethod
   def GetStoryClass(cls):
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 9c9b5ae2..ed2aff5c 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@
             "full_remote_path": "perfetto-luci-artifacts/v34.0/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "af1b51ca274566e2379c03d3d7571efd8dd384d6",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/603af5820895ff5b344fd8b2b7e90a5336f2de30/trace_processor_shell.exe"
+            "hash": "d881142af8241e0d0a22d9a1971510a79f1d9047",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/face7c192d81d632120a587dd45884fe89158203/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "336a42cb9ec3c417e13a97816271fec10cdf67e5",
             "full_remote_path": "perfetto-luci-artifacts/v34.0/linux-arm/trace_processor_shell"
         },
         "mac": {
-            "hash": "45cc12219a0d03b2443070a50363714515211d7d",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/603af5820895ff5b344fd8b2b7e90a5336f2de30/trace_processor_shell"
+            "hash": "6f0d744597b857e99cbfc01d80e21767b516b838",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/face7c192d81d632120a587dd45884fe89158203/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "c32364e05e22cdf82ee0866aedd11c0e2050809c",
             "full_remote_path": "perfetto-luci-artifacts/v34.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "a7bcd56700bd6b57a2749a1ce1d66fe128ba35c6",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/603af5820895ff5b344fd8b2b7e90a5336f2de30/trace_processor_shell"
+            "hash": "9587493949881f35711830e94dc534deefa2a297",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/face7c192d81d632120a587dd45884fe89158203/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/rust/update_rust.py b/tools/rust/update_rust.py
index 1700886..e63fa02 100755
--- a/tools/rust/update_rust.py
+++ b/tools/rust/update_rust.py
@@ -65,7 +65,7 @@
 # TODO(lukasza): Include CRUBIT_REVISION and CRUBIT_SUB_REVISION once we
 # include Crubit binaries in the generated package.  See also a TODO comment
 # in BuildCrubit in package_rust.py.
-FALLBACK_REVISION = '2a8221dbdfd180a2d56d4b0089f4f3952d8c2bcd-1-llvmorg-17-init-10134-g3da83fba-1'
+FALLBACK_REVISION = 'f3d597b31c0f101a02c230798afa31a36bdacbc6-1-llvmorg-17-init-12166-g7586aeab-2'
 
 # Hash of src/stage0.json, which itself contains the stage0 toolchain hashes.
 # We trust the Rust build system checks, but to ensure it is not tampered with
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 83f7c37..1090461 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -418,4 +418,5 @@
  <item id="unified_state_determination_kill_switch" added_in_milestone="115" content_hash_code="01f51d8e" os_list="chromeos" file_path="chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker.cc" />
  <item id="crash_file_uploader" added_in_milestone="115" content_hash_code="05f6902f" os_list="linux" file_path="remoting/host/crash/crash_file_uploader.cc" />
  <item id="glanceables_classroom_integration" added_in_milestone="115" content_hash_code="05bfd7c6" os_list="chromeos" file_path="chrome/browser/ui/ash/glanceables/glanceables_classroom_client_impl.cc" />
+ <item id="promise_app_service_download_icon" added_in_milestone="115" content_hash_code="00521032" os_list="chromeos" file_path="chrome/browser/apps/app_service/promise_apps/promise_app_service.cc" />
 </annotations>
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml
index eb32823..5127e6a 100644
--- a/tools/traffic_annotation/summary/grouping.xml
+++ b/tools/traffic_annotation/summary/grouping.xml
@@ -290,6 +290,7 @@
       <annotation id="unified_state_determination_kill_switch"/>
       <annotation id="crash_file_uploader"/>
       <annotation id="glanceables_classroom_integration"/>
+      <annotation id="promise_app_service_download_icon"/>
     </sender>
   </group>
   <group name="Admin Features" hidden="true">
diff --git a/tools/typescript/validate_tsconfig.py b/tools/typescript/validate_tsconfig.py
index e1580da..7dfd041 100644
--- a/tools/typescript/validate_tsconfig.py
+++ b/tools/typescript/validate_tsconfig.py
@@ -120,6 +120,8 @@
 
   # Specific exceptions for directories that are still migrating to TS.
   migrating_directories = [
+      # TODO(crbug.com/1337318): Migrate bluetooth-internals to TypeScript and
+      # remove exception.
       'chrome/browser/resources/bluetooth_internals',
       'chrome/browser/resources/chromeos/accessibility',
       'chrome/browser/resources/ntp4',
diff --git a/ui/chromeos/file_manager_strings.grdp b/ui/chromeos/file_manager_strings.grdp
index a3f8cbfe..35f8fd7 100644
--- a/ui/chromeos/file_manager_strings.grdp
+++ b/ui/chromeos/file_manager_strings.grdp
@@ -1072,18 +1072,6 @@
   <message name="IDS_FILE_BROWSER_SUGGEST_DIALOG_INSTALLATION_FAILED" desc="Error message when the installation of the app from WebStore is failed.">
     Installation failed.
   </message>
-  <message name="IDS_FILE_BROWSER_DROP_TARGET_DEVICE_WRITE_PROTECTED" desc="Tooltip label displayed besides mouse pointer while dragging files or folders over a write-protected folder or disk.">
-    Device is read-only
-  </message>
-  <message name="IDS_FILE_BROWSER_DROP_TARGET_ACCESS_RESTRICTED" desc="Tooltip label displayed besides mouse pointer when dragging files or folders over a removable device whose write access is restricted by administration policy.">
-    Access restricted
-  </message>
-  <message name="IDS_FILE_BROWSER_DROP_TARGET_FOLDER_NO_MOVE_PERMISSION" desc="Tooltip label displayed besides mouse pointer while dragging files or folders over a Team Drive or folder in Drive that does not have write access.">
-    You don't have permission to move files into '<ph name="FOLDER_NAME">$1<ex>Trip Photos</ex></ph>'.
-  </message>
-  <message name="IDS_FILE_BROWSER_DROP_TARGET_OPENING_LINUX_FILES" desc="Tooltip label displayed besides mouse pointer when dragging files or folders over Linux files root before the container has been started and mounted.">
-    Opening Linux files...
-  </message>
 
   <message name="IDS_FILE_BROWSER_SELECT_FOLDER_TITLE" desc="Select folder title.">
     Select a folder to open
diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc
index 9767b38..8b5bd3e 100644
--- a/ui/events/ozone/evdev/event_device_info.cc
+++ b/ui/events/ozone/evdev/event_device_info.cc
@@ -81,6 +81,7 @@
     {0x046d, 0xb024},  // Logitech G604 Lightspeed Gaming Mouse (Bluetooth)
     {0x046d, 0xb503},  // Logitech Spotlight Presentation Remote (Bluetooth)
     {0x046d, 0xb505},  // Logitech R500 (Bluetooth)
+    {0x046d, 0xc08b},  // Logitech G502 Hero
     {0x046d, 0xc093},  // Logitech M500s
     {0x046d, 0xc534},  // Logitech M170
     {0x046d, 0xc53e},  // Logitech Spotlight Presentation Remote (USB dongle)
diff --git a/ui/events/platform_event.h b/ui/events/platform_event.h
index ea2f727..189a876 100644
--- a/ui/events/platform_event.h
+++ b/ui/events/platform_event.h
@@ -7,6 +7,10 @@
 
 #include "build/build_config.h"
 
+// TODO(https://crbug.com/1443009): Both gfx::NativeEvent and ui::PlatformEvent
+// are typedefs for native event types on different platforms, but they're
+// slightly different and used in different places. They should be merged.
+
 #if BUILDFLAG(IS_WIN)
 #include "base/win/windows_types.h"
 #elif BUILDFLAG(IS_MAC)
diff --git a/ui/file_manager/file_manager/BUILD.gn b/ui/file_manager/file_manager/BUILD.gn
index da0809c..920ee8c 100644
--- a/ui/file_manager/file_manager/BUILD.gn
+++ b/ui/file_manager/file_manager/BUILD.gn
@@ -89,6 +89,7 @@
     "foreground/images/files/ui/offline.svg",
     "foreground/images/files/ui/odfs_reauthentication_required.svg",
     "foreground/images/files/ui/photos_logo.svg",
+    "foreground/images/files/ui/quickview_star.svg",
     "foreground/images/files/ui/refresh.svg",
     "foreground/images/files/ui/restore.svg",
     "foreground/images/files/ui/search_clear_filled.svg",
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css
index 2c50d8f..8baebefa 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -807,7 +807,12 @@
 
 /* Search button */
 body.check-select-v1 #search-button {
+  border: 0;
+  margin: 0;
+  min-width: 0;
+  padding: 0;
   visibility: hidden;
+  width: 0;
 }
 
 /* Search box */
@@ -828,6 +833,10 @@
   caret-color: var(--cr-input-color);
 }
 
+body.check-select-v1 #search-box {
+  visibility: hidden;
+}
+
 .dialog-header.files-ng #search-box.has-cursor,
 .dialog-header.files-ng #search-box.has-text,
 .dialog-header.files-ng #search-box.hide-pending {
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css b/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css
index 62b3927..dbfc6f8d 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css
@@ -655,7 +655,12 @@
 
 /* Search button */
 body.check-select-v1 #search-button {
+  border: 0;
+  margin: 0;
+  min-width: 0;
+  padding: 0;
   visibility: hidden;
+  width: 0;
 }
 
 /* Search box */
@@ -670,6 +675,10 @@
   margin-inline-end: 16px;
 }
 
+body.check-select-v1 #search-box {
+  visibility: hidden;
+}
+
 .dialog-header.files-ng #search-box.has-cursor,
 .dialog-header.files-ng #search-box.has-text,
 .dialog-header.files-ng #search-box.hide-pending {
diff --git a/ui/file_manager/file_manager/foreground/elements/files_quick_view.html b/ui/file_manager/file_manager/foreground/elements/files_quick_view.html
index 4ced688..3ea6b7c 100644
--- a/ui/file_manager/file_manager/foreground/elements/files_quick_view.html
+++ b/ui/file_manager/file_manager/foreground/elements/files_quick_view.html
@@ -40,16 +40,20 @@
         <template is="dom-if" if="[[isHtml_(type, subtype)]]">
           <files-safe-media hidden="[[!hasContent_(sourceContent)]]" type="html" class="content text-content" src="[[sourceContent]]"></files-safe-media>
           <template is="dom-if" if="[[!hasContent_(sourceContent)]]">
-            <div generic-thumbnail="[[type]]"></div>
-            <div class="no-preview">[[noPreviewText]]</div>
+            <div class="no-preview-container">
+              <div generic-thumbnail="[[type]]"></div>
+              <div class="no-preview">[[noPreviewText]]</div>
+            </div>
           </template>
         </template>
         <!-- Image -->
         <template is="dom-if" if="[[isImage_(type)]]">
           <files-safe-media hidden="[[!hasContent_(sourceContent)]]" type="image" class="content no-close-on-click" src="[[sourceContent]]"></files-safe-media>
           <template is="dom-if" if="[[!hasContent_(sourceContent)]]">
-            <div generic-thumbnail="image"></div>
-            <div class="no-preview">[[noPreviewText]]</div>
+            <div class="no-preview-container">
+              <div generic-thumbnail="image"></div>
+              <div class="no-preview">[[noPreviewText]]</div>
+            </div>
           </template>
         </template>
         <!-- Video -->
@@ -58,8 +62,10 @@
             <div class="thumbnail" hidden="[[!videoPoster]]">
               <files-safe-media type="image" id="video-poster" src="[[videoPoster]]"></files-safe-media>
             </div>
-            <div hidden="[[videoPoster]]" generic-thumbnail="video"></div>
-            <div class="no-preview">[[noPlaybackText]]</div>
+            <div class="no-preview-container">
+              <div hidden="[[videoPoster]]" generic-thumbnail="video"></div>
+              <div class="no-preview">[[noPlaybackText]]</div>
+            </div>
           </template>
           <template is="dom-if" if="[[hasContent_(sourceContent)]]">
             <files-safe-media id="videoSafeMedia" tabindex="0" type="video" class="content no-close-on-click" controls autoplay="[[autoplay]]" src="[[sourceContent]]" poster="[[videoPoster]]"></files-safe-media>
@@ -76,11 +82,13 @@
         </div>
         <template is="dom-if" if="[[isAudio_(type)]]">
           <template is="dom-if" if="[[!hasContent_(sourceContent)]]">
-            <div generic-thumbnail="audio"></div>
-            <div class="no-preview">[[noPlaybackText]]</div>
+            <div class="no-preview-container">
+              <div generic-thumbnail="audio"></div>
+              <div class="no-preview">[[noPlaybackText]]</div>
+            </div>
           </template>
         </template>
-        <div hidden="[[!isUnsupported_(type, subtype, browsable)]]">
+        <div class="no-preview-container" hidden="[[!isUnsupported_(type, subtype, browsable)]]">
           <div generic-thumbnail$="[[type]]"></div>
           <div class="no-preview">[[noPreviewText]]</div>
         </div>
diff --git a/ui/file_manager/file_manager/foreground/elements/files_quick_view_gm3.css b/ui/file_manager/file_manager/foreground/elements/files_quick_view_gm3.css
index 2d73a63..d991167 100644
--- a/ui/file_manager/file_manager/foreground/elements/files_quick_view_gm3.css
+++ b/ui/file_manager/file_manager/foreground/elements/files_quick_view_gm3.css
@@ -244,7 +244,21 @@
 }
 
 .no-preview {
-  margin-top: 16px;
+  max-width: 130px;
+}
+
+.no-preview-container {
+  -webkit-mask-image: url(../images/files/ui/quickview_star.svg);
+  -webkit-mask-position: center;
+  -webkit-mask-repeat: no-repeat;
+  -webkit-mask-size: 224px;
+  align-items: center;
+  background-color: var(--cros-sys-primary_container);
+  color: var(--cros-sys-on_primary_container);
+  display: flex;
+  flex-direction: column;
+  height: 224px;
+  justify-content: center;
 }
 
 /* Large generic thumbnails, used when a file does not have a thumbnail. */
@@ -252,34 +266,28 @@
   -webkit-mask-image: url(../images/filetype/filetype_generic.svg);
   -webkit-mask-position: center;
   -webkit-mask-repeat: no-repeat;
-  -webkit-mask-size: auto 88px;
+  -webkit-mask-size: 80px;
   background-color: currentColor;
-  background-position: center;
-  background-repeat: no-repeat;
-  background-size: auto 88px;
-  height: 88px;
+  height: 80px;
+  margin-bottom: 8px;
+  width: 80px;
 }
 
 [generic-thumbnail='.folder'] {
   -webkit-mask-image: url(../images/filetype/filetype_folder.svg);
-  -webkit-mask-size: auto 72px;
 }
 
 [generic-thumbnail='audio'] {
-  -webkit-mask-image: none;
-  background-color: transparent;
-  background-image: url(../images/filetype/filetype_audio.svg);
+  -webkit-mask-image: url(../images/filetype/filetype_audio.svg);
+  background-color: var(--cros-sys-error);
 }
 
 [generic-thumbnail='image'] {
-  -webkit-mask-image: none;
-  background-color: transparent;
-  background-image: url(../images/filetype/filetype_image.svg);
+  -webkit-mask-image: url(../images/filetype/filetype_image.svg);
+  background-color: var(--cros-sys-error);
 }
 
 [generic-thumbnail='video'] {
-  -webkit-mask-image: none;
-  background-color: transparent;
-  background-image: url(../images/filetype/filetype_video.svg);
-  background-size: auto 72px;
+  -webkit-mask-image: url(../images/filetype/filetype_video.svg);
+  background-color: var(--cros-sys-error);
 }
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quickview_star.svg b/ui/file_manager/file_manager/foreground/images/files/ui/quickview_star.svg
new file mode 100644
index 0000000..eedbf82
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/images/files/ui/quickview_star.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="224" height="224" viewBox="0 0 224 224">
+  <path
+    d="M104.566 222.348a17.55 17.55 0 0 0 14.868 0l16.848-7.879a17.532 17.532 0 0 1 5.924-1.587l18.53-1.601a17.554 17.554 0 0 0 12.876-7.434l10.651-15.247a17.555 17.555 0 0 1 4.337-4.337l15.247-10.651a17.554 17.554 0 0 0 7.434-12.876l1.601-18.53a17.532 17.532 0 0 1 1.587-5.924l7.879-16.848a17.55 17.55 0 0 0 0-14.868l-7.879-16.848a17.533 17.533 0 0 1-1.587-5.924l-1.601-18.53a17.552 17.552 0 0 0-7.434-12.876L188.6 39.737a17.552 17.552 0 0 1-4.337-4.337l-10.651-15.247a17.551 17.551 0 0 0-12.876-7.434l-18.53-1.6a17.548 17.548 0 0 1-5.924-1.588l-16.848-7.879a17.55 17.55 0 0 0-14.868 0L87.718 9.531a17.55 17.55 0 0 1-5.924 1.587l-18.53 1.601a17.55 17.55 0 0 0-12.876 7.434L39.737 35.4a17.548 17.548 0 0 1-4.337 4.337L20.153 50.388a17.55 17.55 0 0 0-7.434 12.876l-1.6 18.53a17.55 17.55 0 0 1-1.588 5.924l-7.879 16.848a17.55 17.55 0 0 0 0 14.868l7.879 16.848a17.548 17.548 0 0 1 1.587 5.924l1.601 18.53a17.551 17.551 0 0 0 7.434 12.876L35.4 184.263a17.552 17.552 0 0 1 4.337 4.337l10.651 15.247a17.553 17.553 0 0 0 12.876 7.434l18.53 1.601c2.053.177 4.058.714 5.924 1.587l16.848 7.879Z" />
+</svg>
diff --git a/ui/file_manager/file_manager/foreground/js/drop_effect_and_label.js b/ui/file_manager/file_manager/foreground/js/drop_effect_and_label.js
index ecd6c04..6d4247a 100644
--- a/ui/file_manager/file_manager/foreground/js/drop_effect_and_label.js
+++ b/ui/file_manager/file_manager/foreground/js/drop_effect_and_label.js
@@ -12,37 +12,3 @@
   MOVE: 'move',
   LINK: 'link',
 };
-
-/**
- * Represents a drop effect and a label to describe it.
- */
-export class DropEffectAndLabel {
-  /**
-   * @param {!DropEffectType} dropEffect
-   * @param {?string} label
-   */
-  constructor(dropEffect, label) {
-    /** @private @const {!DropEffectType} */
-    this.dropEffect_ = dropEffect;
-
-    /**
-     * Optional description why the drop operation is (not) permitted.
-     * @private @const {?string}
-     */
-    this.label_ = label;
-  }
-
-  /**
-   * @return {!DropEffectType} Returns the type of the drop effect.
-   */
-  getDropEffect() {
-    return this.dropEffect_;
-  }
-
-  /**
-   * @return {?string} Returns the label. |none| if a label should not appear.
-   */
-  getLabel() {
-    return this.label_;
-  }
-}
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
index f2d8d6a0..d7b2c56 100644
--- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -19,7 +19,7 @@
 import {VolumeManager} from '../../externs/volume_manager.js';
 
 import {DirectoryModel} from './directory_model.js';
-import {DropEffectAndLabel, DropEffectType} from './drop_effect_and_label.js';
+import {DropEffectType} from './drop_effect_and_label.js';
 import {FileSelectionHandler} from './file_selection.js';
 import {MetadataModel} from './metadata/metadata_model.js';
 import {Command} from './ui/command.js';
@@ -98,6 +98,10 @@
     /**
      * @private {!MetadataModel}
      * @const
+     * Note: We use synchronous `getCache` method under assumption that fields
+     * we request are already cached. See constants.js, specifically
+     * LIST_CONTAINER_METADATA_PREFETCH_PROPERTY_NAMES for list of fields which
+     * are safe to use.
      */
     this.metadataModel_ = metadataModel;
 
@@ -788,9 +792,8 @@
       entry = this.directoryModel_.getCurrentDirEntry();
     }
 
-    const effectAndLabel =
+    event.dataTransfer.dropEffect =
         this.selectDropEffect_(event, this.getDragAndDropGlobalData_(), entry);
-    event.dataTransfer.dropEffect = effectAndLabel.getDropEffect();
     event.preventDefault();
   }
 
@@ -918,8 +921,7 @@
         event.dataTransfer,
         /** @type {DirectoryEntry} */ (destinationEntry),
         this.selectDropEffect_(
-                event, this.getDragAndDropGlobalData_(), destinationEntry)
-            .getDropEffect());
+            event, this.getDragAndDropGlobalData_(), destinationEntry));
     this.clearDropTarget_();
   }
 
@@ -1451,51 +1453,47 @@
    *     getDragAndDropGlobalData_().
    * @param {DirectoryEntry|FilesAppEntry} destinationEntry Destination
    *     entry.
-   * @return {DropEffectAndLabel} Returns the appropriate drop query type
+   * @return {!string} Returns the appropriate drop query type
    *     ('none', 'move' or copy') to the current modifiers status and the
-   *     destination, as well as label message to describe why the operation is
-   *     not allowed.
+   *     destination.
    * @private
    */
   selectDropEffect_(event, dragAndDropData, destinationEntry) {
     if (!destinationEntry) {
-      return new DropEffectAndLabel(DropEffectType.NONE, null);
+      return DropEffectType.NONE;
     }
     const destinationLocationInfo =
         this.volumeManager_.getLocationInfo(destinationEntry);
     if (!destinationLocationInfo) {
-      return new DropEffectAndLabel(DropEffectType.NONE, null);
+      return DropEffectType.NONE;
     }
     if (destinationLocationInfo.volumeInfo &&
         destinationLocationInfo.volumeInfo.error) {
-      return new DropEffectAndLabel(DropEffectType.NONE, null);
+      return DropEffectType.NONE;
     }
     // Recent isn't read-only, but it doesn't support drop.
     if (destinationLocationInfo.rootType ===
         VolumeManagerCommon.RootType.RECENT) {
-      return new DropEffectAndLabel(DropEffectType.NONE, null);
+      return DropEffectType.NONE;
     }
     if (destinationLocationInfo.isReadOnly) {
       if (destinationLocationInfo.isSpecialSearchRoot) {
         // The location is a fake entry that corresponds to special search.
-        return new DropEffectAndLabel(DropEffectType.NONE, null);
+        return DropEffectType.NONE;
       }
       if (destinationLocationInfo.rootType ==
           VolumeManagerCommon.RootType.CROSTINI) {
         // The location is a the fake entry for crostini.  Start container.
-        return new DropEffectAndLabel(
-            DropEffectType.NONE, strf('OPENING_LINUX_FILES'));
+        return DropEffectType.NONE;
       }
       if (destinationLocationInfo.volumeInfo &&
           destinationLocationInfo.volumeInfo.isReadOnlyRemovableDevice) {
-        return new DropEffectAndLabel(
-            DropEffectType.NONE, strf('DEVICE_WRITE_PROTECTED'));
+        return DropEffectType.NONE;
       }
       // The disk device is not write-protected but read-only.
       // Currently, the only remaining possibility is that write access to
       // removable drives is restricted by device policy.
-      return new DropEffectAndLabel(
-          DropEffectType.NONE, strf('DEVICE_ACCESS_RESTRICTED'));
+      return DropEffectType.NONE;
     }
     const destinationMetadata =
         this.metadataModel_.getCache([destinationEntry], ['canAddChildren']);
@@ -1503,9 +1501,7 @@
         destinationMetadata[0].canAddChildren === false) {
       // TODO(sashab): Distinguish between copy/move operations and display
       // corresponding warning text here.
-      return new DropEffectAndLabel(
-          DropEffectType.NONE,
-          strf('DROP_TARGET_FOLDER_NO_MOVE_PERMISSION', destinationEntry.name));
+      return DropEffectType.NONE;
     }
     // Files can be dragged onto the TrashRootEntry, but they must reside on a
     // volume that is trashable.
@@ -1515,24 +1511,24 @@
                          destinationLocationInfo, event.dataTransfer)) ?
           DropEffectType.MOVE :
           DropEffectType.NONE;
-      return new DropEffectAndLabel(effect, null);
+      return effect;
     }
     if (isDropEffectAllowed(event.dataTransfer.effectAllowed, 'move')) {
       if (!isDropEffectAllowed(event.dataTransfer.effectAllowed, 'copy')) {
-        return new DropEffectAndLabel(DropEffectType.MOVE, null);
+        return DropEffectType.MOVE;
       }
       // TODO(mtomasz): Use volumeId instead of comparing roots, as soon as
       // volumeId gets unique.
       if (this.getSourceRootURL_(event.dataTransfer, dragAndDropData) ===
               destinationLocationInfo.volumeInfo.fileSystem.root.toURL() &&
           !event.ctrlKey) {
-        return new DropEffectAndLabel(DropEffectType.MOVE, null);
+        return DropEffectType.MOVE;
       }
       if (event.shiftKey) {
-        return new DropEffectAndLabel(DropEffectType.MOVE, null);
+        return DropEffectType.MOVE;
       }
     }
-    return new DropEffectAndLabel(DropEffectType.COPY, null);
+    return DropEffectType.COPY;
   }
 
   /**
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index dadf2bdc9..34df275 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -944,8 +944,7 @@
         appId, preview, getTextContent);
 
     // Check: the content of ENTRIES.utf8Text should be shown.
-    if (!text || !text[0] ||
-        !text[0].includes('їсти मुझे |∊☀✌✂♁ 🙂\n')) {
+    if (!text || !text[0] || !text[0].includes('їсти मुझे |∊☀✌✂♁ 🙂\n')) {
       return pending(caller, 'Waiting for preview content.');
     }
   });
@@ -1919,11 +1918,12 @@
 
   /**
    * The [generic-thumbnail] element resides in the #quick-view shadow DOM
-   * as a sibling of the files-safe-media[type="image"] element.
+   * as a child of .no-preview-container which is a sibling of the
+   * files-safe-media[type="image"] element.
    */
   const genericThumbnail = [
     '#quick-view',
-    'files-safe-media[type="image"][hidden] + [generic-thumbnail="image"]',
+    'files-safe-media[type="image"][hidden] + .no-preview-container > [generic-thumbnail="image"]',
   ];
 
   // Open Files app on Downloads containing ENTRIES.brokenJpeg.
@@ -2684,7 +2684,6 @@
 
   // Wait until the preview displays that file's content.
   await repeatUntil(async () => {
-
     const getTextContent = contentWindowQuery + '.document.body.textContent';
     const text = await executeJsInPreviewTagAndCatchErrors(
         appId, preview, getTextContent);
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index c7a777df..80edfe22 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -293,7 +293,7 @@
     ":gfx_skia",
     ":gfx_switches",
     ":memory_buffer_sources",
-    ":native_widget_types",
+    ":native_widget_types_sources",
     ":resize_image_dimensions",
     ":selection_bound_sources",
     "//base",
@@ -499,21 +499,36 @@
 }
 
 # Depend on this to use native_widget_types.h without pulling in all of gfx.
-source_set("native_widget_types") {
+# The structure here allows native_widget_types to be part of the gfx component
+# in the component build, but be a separate source set in a static build.
+group("native_widget_types") {
+  if (is_component_build) {
+    public_deps = [ ":gfx" ]
+  } else {
+    public_deps = [ ":native_widget_types_sources" ]
+  }
+}
+
+source_set("native_widget_types_sources") {
+  visibility = [ ":*" ]  # Depend on through ":native_widget_types".
+
   public = [ "native_widget_types.h" ]
+  sources = [ "native_widget_types.cc" ]
 
   public_deps = [
     ":gfx_export",
     "//base",
   ]
 
-  if (is_mac) {
-    sources = [ "native_widget_types.mm" ]
-
-    frameworks = [ "AppKit.framework" ]
-  }
-
   deps = [ "//build:chromeos_buildflags" ]
+
+  defines = [ "GFX_IMPLEMENTATION" ]
+
+  if (is_mac) {
+    sources += [ "native_widget_types_mac.mm" ]
+    frameworks = [ "AppKit.framework" ]
+    deps += [ "//base:base_arc" ]
+  }
 }
 
 group("selection_bound") {
@@ -527,7 +542,7 @@
 # Depend on this to use selection_bound.h without pulling in all of gfx.
 # Cannot be a static_library in component builds due to exported functions
 source_set("selection_bound_sources") {
-  visibility = [ ":*" ]
+  visibility = [ ":*" ]  # Depend on through ":selection_bound".
 
   sources = [
     "gfx_export.h",
@@ -584,12 +599,15 @@
     "gpu_fence.h",
     "gpu_fence_handle.cc",
     "gpu_fence_handle.h",
-    "native_pixmap.h",
     "overlay_priority_hint.h",
     "overlay_transform.h",
     "surface_origin.h",
   ]
 
+  if (!is_nacl) {
+    sources += [ "native_pixmap.h" ]
+  }
+
   if (use_blink) {
     sources += [
       "ca_layer_params.cc",
@@ -607,13 +625,16 @@
 
   deps = [
     ":gfx_switches",
-    ":native_widget_types",
     "//base",
     "//build:chromecast_buildflags",
     "//build:chromeos_buildflags",
     "//ui/gfx/geometry",
   ]
 
+  if (!is_nacl) {
+    deps += [ ":native_widget_types_sources" ]
+  }
+
   if (is_linux || is_chromeos) {
     sources += [
       "linux/client_native_pixmap_dmabuf.cc",
diff --git a/ui/gfx/native_widget_types.cc b/ui/gfx/native_widget_types.cc
new file mode 100644
index 0000000..89bd8a4
--- /dev/null
+++ b/ui/gfx/native_widget_types.cc
@@ -0,0 +1,20 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/native_widget_types.h"
+
+// TODO(https://crbug.com/1443009): ui::PlatformEvent has its own version of
+// this function. When unifying, remove one of these copies.
+
+namespace gfx {
+
+GFX_EXPORT bool IsNativeEventValid(const NativeEvent& event) {
+#if BUILDFLAG(IS_APPLE)
+  return event.IsValid();
+#else
+  return !!event;
+#endif
+}
+
+}  // namespace gfx
diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h
index 46a02a3..73283ac 100644
--- a/ui/gfx/native_widget_types.h
+++ b/ui/gfx/native_widget_types.h
@@ -13,9 +13,17 @@
 
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/scoped_java_ref.h"
-#elif BUILDFLAG(IS_MAC)
+#endif
+
+#if BUILDFLAG(IS_APPLE)
+#include "base/apple/owned_objc.h"
+#endif
+
+#if BUILDFLAG(IS_MAC)
 #include <string>
-#elif BUILDFLAG(IS_WIN)
+#endif
+
+#if BUILDFLAG(IS_WIN)
 #include "base/win/windows_types.h"
 #endif
 
@@ -39,6 +47,10 @@
 // The name 'View' here meshes with macOS where the UI elements are called
 // 'views' and with our Chrome UI code where the elements are also called
 // 'views'.
+//
+// TODO(https://crbug.com/1443009): Both gfx::NativeEvent and ui::PlatformEvent
+// are typedefs for native event types on different platforms, but they're
+// slightly different and used in different places. They should be merged.
 
 #if defined(USE_AURA)
 namespace aura {
@@ -59,13 +71,11 @@
 #elif BUILDFLAG(IS_IOS)
 #ifdef __OBJC__
 struct objc_object;
-@class UIEvent;
 @class UIImage;
 @class UIView;
 @class UIWindow;
 @class UITextField;
 #else
-class UIEvent;
 class UIImage;
 class UIView;
 class UIWindow;
@@ -74,7 +84,6 @@
 #elif BUILDFLAG(IS_MAC)
 #ifdef __OBJC__
 @class NSCursor;
-@class NSEvent;
 @class NSImage;
 @class NSView;
 @class NSWindow;
@@ -82,7 +91,6 @@
 #else
 struct objc_object;
 class NSCursor;
-class NSEvent;
 class NSImage;
 class NSView;
 class NSWindow;
@@ -121,12 +129,12 @@
 using NativeCursor = void*;
 using NativeView = UIView*;
 using NativeWindow = UIWindow*;
-using NativeEvent = UIEvent*;
+using NativeEvent = base::apple::OwnedUIEvent;
 constexpr NativeView kNullNativeView = nullptr;
 constexpr NativeWindow kNullNativeWindow = nullptr;
 #elif BUILDFLAG(IS_MAC)
 using NativeCursor = NSCursor*;
-using NativeEvent = NSEvent*;
+using NativeEvent = base::apple::OwnedNSEvent;
 // NativeViews and NativeWindows on macOS are not necessarily in the same
 // process as the NSViews and NSWindows that they represent. Require an explicit
 // function call (GetNativeNSView or GetNativeNSWindow) to retrieve the
@@ -231,12 +239,15 @@
 using NativeViewAccessible = UnimplementedNativeViewAccessible*;
 #endif
 
+// Returns if the event is valid.
+GFX_EXPORT bool IsNativeEventValid(const NativeEvent& event);
+
 // A constant value to indicate that gfx::NativeCursor refers to no cursor.
 #if defined(USE_AURA)
 const ui::mojom::CursorType kNullCursor =
     static_cast<ui::mojom::CursorType>(-1);
 #else
-const gfx::NativeCursor kNullCursor = static_cast<gfx::NativeCursor>(nullptr);
+const NativeCursor kNullCursor = static_cast<NativeCursor>(nullptr);
 #endif
 
 // Note: for test_shell we're packing a pointer into the NativeViewId. So, if
diff --git a/ui/gfx/native_widget_types.mm b/ui/gfx/native_widget_types_mac.mm
similarity index 100%
rename from ui/gfx/native_widget_types.mm
rename to ui/gfx/native_widget_types_mac.mm
diff --git a/ui/gl/child_window_win.cc b/ui/gl/child_window_win.cc
index 514411d3..3de7eab 100644
--- a/ui/gl/child_window_win.cc
+++ b/ui/gl/child_window_win.cc
@@ -4,14 +4,16 @@
 
 #include "ui/gl/child_window_win.h"
 
-#include <memory>
-
 #include "base/compiler_specific.h"
 #include "base/debug/alias.h"
 #include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_pump_type.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_checker.h"
 #include "base/win/wrapped_window_proc.h"
 #include "ui/gfx/win/hwnd_util.h"
 #include "ui/gfx/win/window_impl.h"
@@ -109,29 +111,63 @@
   event->Signal();
 }
 
-// This runs on the main thread after the window was destroyed on window owner
-// thread.
-void DestroyThread(std::unique_ptr<base::Thread> thread) {
-  thread->Stop();
-}
-
 // This runs on the window owner thread.
 void DestroyWindowsOnThread(HWND child_window, HWND hidden_popup_window) {
   DestroyWindow(child_window);
   HiddenPopupWindow::Destroy(hidden_popup_window);
 }
 
+THREAD_CHECKER(thread_checker_);
+
 }  // namespace
 
+class ChildWindowWin::ChildWindowThread
+    : public base::RefCounted<ChildWindowThread> {
+ public:
+  // Returns the singleton instance of the thread.
+  static scoped_refptr<ChildWindowThread> GetInstance() {
+    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+    static base::WeakPtr<ChildWindowThread> weak_instance;
+
+    auto instance = base::WrapRefCounted(weak_instance.get());
+    if (!instance) {
+      instance = base::WrapRefCounted(new ChildWindowThread);
+      weak_instance = instance->weak_ptr_factory_.GetWeakPtr();
+    }
+
+    return instance;
+  }
+
+  scoped_refptr<base::TaskRunner> task_runner() {
+    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+    return thread_.task_runner();
+  }
+
+ private:
+  friend class base::RefCounted<ChildWindowThread>;
+
+  ChildWindowThread() : thread_("Window owner thread") {
+    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+    base::Thread::Options options(base::MessagePumpType::UI, 0);
+    thread_.StartWithOptions(std::move(options));
+  }
+
+  ~ChildWindowThread() {
+    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+    thread_.Stop();
+  }
+
+  base::Thread thread_;
+  base::WeakPtrFactory<ChildWindowThread> weak_ptr_factory_{this};
+};
+
 ChildWindowWin::ChildWindowWin() = default;
 
 void ChildWindowWin::Initialize() {
   if (window_)
     return;
 
-  thread_ = std::make_unique<base::Thread>("Window owner thread");
-  base::Thread::Options options(base::MessagePumpType::UI, 0);
-  thread_->StartWithOptions(std::move(options));
+  thread_ = ChildWindowThread::GetInstance();
 
   base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                             base::WaitableEvent::InitialState::NOT_SIGNALED);
@@ -149,7 +185,7 @@
         FROM_HERE,
         base::BindOnce(&DestroyWindowsOnThread, window_,
                        initial_parent_window_),
-        base::BindOnce(&DestroyThread, std::move(thread_)));
+        base::DoNothingWithBoundArgs(std::move(thread_)));
   }
 }
 
diff --git a/ui/gl/child_window_win.h b/ui/gl/child_window_win.h
index 2af3f37..f05a9e246 100644
--- a/ui/gl/child_window_win.h
+++ b/ui/gl/child_window_win.h
@@ -5,9 +5,8 @@
 #ifndef UI_GL_CHILD_WINDOW_WIN_H_
 #define UI_GL_CHILD_WINDOW_WIN_H_
 
-#include "base/memory/weak_ptr.h"
+#include "base/memory/ref_counted.h"
 #include "base/task/task_runner.h"
-#include "base/threading/thread.h"
 #include "ui/gl/gl_export.h"
 
 #include <windows.h>
@@ -37,8 +36,11 @@
   scoped_refptr<base::TaskRunner> GetTaskRunnerForTesting();
 
  private:
+  class ChildWindowThread;
+
   // The window owner thread.
-  std::unique_ptr<base::Thread> thread_;
+  scoped_refptr<ChildWindowThread> thread_;
+
   HWND window_ = nullptr;
   // The window is initially created with this parent window. We need to keep it
   // around so that we can destroy it at the end.
diff --git a/ui/gl/gl_features.cc b/ui/gl/gl_features.cc
index cc3470c..c17d84f2 100644
--- a/ui/gl/gl_features.cc
+++ b/ui/gl/gl_features.cc
@@ -86,7 +86,12 @@
 // platforms that would otherwise not default to using EGL bindings.
 BASE_FEATURE(kDefaultPassthroughCommandDecoder,
              "DefaultPassthroughCommandDecoder",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+             base::FEATURE_ENABLED_BY_DEFAULT
+#else
+             base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+);
 #endif  // !defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
 
 #if BUILDFLAG(IS_MAC)
diff --git a/ui/gl/swap_chain_presenter.cc b/ui/gl/swap_chain_presenter.cc
index b2e37c4..9f7c3cc 100644
--- a/ui/gl/swap_chain_presenter.cc
+++ b/ui/gl/swap_chain_presenter.cc
@@ -423,6 +423,62 @@
       sets_output_hdr_metadata, use_vp_super_resolution);
 }
 
+// Try disabling the topmost desktop plane for a decode swap chain in the case
+// of full screen. Otherwise, swap chain size is used to set destination size
+// and target rectangle for the decode swap chain. In DWM, the desktop plane
+// can be turned off if the letterboxing info is set up properly for YUV
+// swapchains, meaning that when the size of the window and the size of the
+// monitor are the same and there is no other UI component overtop of the
+// video. Otherwise, set the letterboxing info with swap chain size in order
+// to restore the topmost desktop plane, which happens in scenarios like
+// switching to underlay.
+// Returns true on successful settings.
+bool TryDisableDesktopPlane(IDXGIDecodeSwapChain* decode_swap_chain,
+                            const gfx::Size& dest_size,
+                            const gfx::Rect& target_rect) {
+  // Get the original dest size in case of restoring.
+  uint32_t original_dest_width, original_dest_height;
+  HRESULT hr = decode_swap_chain->GetDestSize(&original_dest_width,
+                                              &original_dest_height);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "GetDestSize failed with error 0x" << std::hex << hr;
+    return false;
+  }
+
+  // Set the destination surface size if necessary.
+  if (dest_size.width() != (int)original_dest_width ||
+      dest_size.height() != (int)original_dest_height) {
+    hr = decode_swap_chain->SetDestSize(dest_size.width(), dest_size.height());
+    if (FAILED(hr)) {
+      DLOG(ERROR) << "SetDestSize failed with error 0x" << std::hex << hr;
+      return false;
+    }
+  }
+
+  // Get the original target rect in case of restoring.
+  RECT original_target_rect;
+  hr = decode_swap_chain->GetTargetRect(&original_target_rect);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "GetTargetRect failed with error 0x" << std::hex << hr;
+    decode_swap_chain->SetDestSize(original_dest_width, original_dest_height);
+    return false;
+  }
+
+  // Set the target region to the specified rectangle if necessary.
+  RECT target_region = target_rect.ToRECT();
+  if (target_region != original_target_rect) {
+    hr = decode_swap_chain->SetTargetRect(&target_region);
+    if (FAILED(hr)) {
+      DLOG(ERROR) << "SetTargetRect failed with error 0x" << std::hex << hr;
+      decode_swap_chain->SetDestSize(original_dest_width, original_dest_height);
+      decode_swap_chain->SetTargetRect(&original_target_rect);
+      return false;
+    }
+  }
+
+  return true;
+}
+
 }  // namespace
 
 SwapChainPresenter::PresentationHistory::PresentationHistory() = default;
@@ -659,6 +715,24 @@
   }
 }
 
+void SwapChainPresenter::SetTargetToFullScreen(
+    gfx::Transform* visual_transform,
+    gfx::Rect* visual_clip_rect) const {
+  // Reset the horizontal/vertical shift according to the visual clip and
+  // original transform, since DWM will do the positioning in case of overlay.
+  visual_transform->set_rc(
+      0, 3,
+      visual_clip_rect->x() -
+          visual_transform->rc(0, 3) * visual_transform->rc(0, 0));
+  visual_transform->set_rc(
+      1, 3,
+      visual_clip_rect->y() -
+          visual_transform->rc(1, 3) * visual_transform->rc(1, 1));
+
+  // Expand the clip rect for swap chain to the whole screen.
+  *visual_clip_rect = gfx::Rect(GetMonitorSize());
+}
+
 void SwapChainPresenter::AdjustTargetToOptimalSizeIfNeeded(
     const DCLayerOverlayParams& params,
     const gfx::Rect& overlay_onscreen_rect,
@@ -1089,7 +1163,9 @@
     const gfx::Rect& content_rect,
     const gfx::Size& swap_chain_size,
     DXGI_FORMAT swap_chain_format,
-    const gfx::Transform& transform_to_root) {
+    const gfx::Transform& transform_to_root,
+    const absl::optional<gfx::Size> dest_size,
+    const absl::optional<gfx::Rect> target_rect) {
   if (ShouldUseVideoProcessorScaling())
     return false;
 
@@ -1144,7 +1220,8 @@
     if (is_decoder_texture && !is_shared_texture && !is_unitary_texture_array &&
         compatible_transform) {
       if (PresentToDecodeSwapChain(texture, array_slice, color_space,
-                                   content_rect, swap_chain_size)) {
+                                   content_rect, swap_chain_size, dest_size,
+                                   target_rect)) {
         return true;
       }
       ReleaseSwapChainResources();
@@ -1161,7 +1238,9 @@
     unsigned array_slice,
     const gfx::ColorSpace& color_space,
     const gfx::Rect& content_rect,
-    const gfx::Size& swap_chain_size) {
+    const gfx::Size& swap_chain_size,
+    const absl::optional<gfx::Size> dest_size,
+    const absl::optional<gfx::Rect> target_rect) {
   DCHECK(!swap_chain_size.IsEmpty());
 
   TRACE_EVENT2("gpu", "SwapChainPresenter::PresentToDecodeSwapChain",
@@ -1172,6 +1251,7 @@
   texture.As(&decode_resource);
   DCHECK(decode_resource);
 
+  HRESULT hr = S_OK;
   if (!decode_swap_chain_ || decode_resource_ != decode_resource) {
     TRACE_EVENT0(
         "gpu",
@@ -1201,10 +1281,9 @@
     // does not qualify as fullscreen by DWM's logic then the flag will have
     // no effects.
     desc.Flags = DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO;
-    HRESULT hr =
-        media_factory->CreateDecodeSwapChainForCompositionSurfaceHandle(
-            d3d11_device_.Get(), swap_chain_handle_.Get(), &desc,
-            decode_resource_.Get(), nullptr, &decode_swap_chain_);
+    hr = media_factory->CreateDecodeSwapChainForCompositionSurfaceHandle(
+        d3d11_device_.Get(), swap_chain_handle_.Get(), &desc,
+        decode_resource_.Get(), nullptr, &decode_swap_chain_);
     if (FAILED(hr)) {
       DLOG(ERROR) << "CreateDecodeSwapChainForCompositionSurfaceHandle failed "
                      "with error 0x"
@@ -1231,12 +1310,29 @@
   }
 
   RECT source_rect = content_rect.ToRECT();
-  decode_swap_chain_->SetSourceRect(&source_rect);
+  hr = decode_swap_chain_->SetSourceRect(&source_rect);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "SetSourceRect failed with error 0x" << std::hex << hr;
+    return false;
+  }
 
-  decode_swap_chain_->SetDestSize(swap_chain_size.width(),
-                                  swap_chain_size.height());
-  RECT target_rect = gfx::Rect(swap_chain_size).ToRECT();
-  decode_swap_chain_->SetTargetRect(&target_rect);
+  gfx::Size swap_chain_dest_size =
+      dest_size.has_value() ? dest_size.value() : swap_chain_size;
+  hr = decode_swap_chain_->SetDestSize(swap_chain_dest_size.width(),
+                                       swap_chain_dest_size.height());
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "SetDestSize failed with error 0x" << std::hex << hr;
+    return false;
+  }
+
+  RECT swap_chain_target_rect = target_rect.has_value()
+                                    ? (target_rect.value()).ToRECT()
+                                    : gfx::Rect(swap_chain_size).ToRECT();
+  hr = decode_swap_chain_->SetTargetRect(&swap_chain_target_rect);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "SetTargetRect failed with error 0x" << std::hex << hr;
+    return false;
+  }
 
   // TODO(sunnyps): Move this to gfx::ColorSpaceWin helper where we can access
   // internal color space state and do a better job.
@@ -1254,11 +1350,15 @@
   if (color_space.FullRangeEncodedValues()) {
     color_space_flags |= DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_xvYCC;
   }
-  decode_swap_chain_->SetColorSpace(
+  hr = decode_swap_chain_->SetColorSpace(
       static_cast<DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS>(color_space_flags));
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "SetColorSpace failed with error 0x" << std::hex << hr;
+    return false;
+  }
 
   UINT present_flags = DXGI_PRESENT_USE_DURATION;
-  HRESULT hr = decode_swap_chain_->PresentBuffer(array_slice, 1, present_flags);
+  hr = decode_swap_chain_->PresentBuffer(array_slice, 1, present_flags);
   // Ignore DXGI_STATUS_OCCLUDED since that's not an error but only indicates
   // that the window is occluded and we can stop rendering.
   if (FAILED(hr) && hr != DXGI_STATUS_OCCLUDED) {
@@ -1273,61 +1373,6 @@
   return true;
 }
 
-bool SwapChainPresenter::TryDisableDesktopPlane(const gfx::Size& dest_size,
-                                                const gfx::Rect& target_rect) {
-  // Note that QI IDXGIDecodeSwapChain from an RGB swap chain will always fail.
-  Microsoft::WRL::ComPtr<IDXGIDecodeSwapChain> decode_swap_chain;
-  HRESULT hr = swap_chain_->QueryInterface(IID_PPV_ARGS(&decode_swap_chain));
-  if (FAILED(hr)) {
-    DLOG(ERROR)
-        << "QueryInterface for IDXGIDecodeSwapChain failed with error 0x"
-        << std::hex << hr;
-    return false;
-  }
-
-  // Get the original dest size in case of restoring.
-  uint32_t original_dest_width, original_dest_height;
-  hr = decode_swap_chain->GetDestSize(&original_dest_width,
-                                      &original_dest_height);
-  if (FAILED(hr)) {
-    DLOG(ERROR) << "GetDestSize failed with error 0x" << std::hex << hr;
-    return false;
-  }
-
-  // Set the destination surface size if necessary.
-  if (dest_size.width() != (int)original_dest_width ||
-      dest_size.height() != (int)original_dest_height) {
-    hr = decode_swap_chain->SetDestSize(dest_size.width(), dest_size.height());
-    if (FAILED(hr)) {
-      DLOG(ERROR) << "SetDestSize failed with error 0x" << std::hex << hr;
-      return false;
-    }
-  }
-
-  // Get the original target rect in case of restoring.
-  RECT original_target_rect;
-  hr = decode_swap_chain->GetTargetRect(&original_target_rect);
-  if (FAILED(hr)) {
-    DLOG(ERROR) << "GetTargetRect failed with error 0x" << std::hex << hr;
-    decode_swap_chain->SetDestSize(original_dest_width, original_dest_height);
-    return false;
-  }
-
-  // Set the target region to the specified rectangle if necessary.
-  RECT target_region = target_rect.ToRECT();
-  if (target_region != original_target_rect) {
-    hr = decode_swap_chain->SetTargetRect(&target_region);
-    if (FAILED(hr)) {
-      DLOG(ERROR) << "SetTargetRect failed with error 0x" << std::hex << hr;
-      decode_swap_chain->SetDestSize(original_dest_width, original_dest_height);
-      decode_swap_chain->SetTargetRect(&original_target_rect);
-      return false;
-    }
-  }
-
-  return true;
-}
-
 bool SwapChainPresenter::PresentToSwapChain(DCLayerOverlayParams& params,
                                             gfx::Transform* visual_transform,
                                             gfx::Rect* visual_clip_rect) {
@@ -1351,6 +1396,9 @@
   // content is shown again.
   ReleaseDCOMPSurfaceResourcesIfNeeded();
 
+  // Optional |dest_size| and |target_rect| are only calculated for full screen
+  // letterboxing in |AdjustTargetForFullScreenLetterboxing|, which is guarded
+  // by flag of DirectCompositionLetterboxVideoOptimization for now.
   absl::optional<gfx::Size> dest_size;
   absl::optional<gfx::Rect> target_rect;
   gfx::Size swap_chain_size = CalculateSwapChainSize(
@@ -1407,8 +1455,15 @@
 
   if (TryPresentToDecodeSwapChain(input_texture, input_level, input_color_space,
                                   params.content_rect, swap_chain_size,
-                                  swap_chain_format, params.transform)) {
+                                  swap_chain_format, params.transform,
+                                  dest_size, target_rect)) {
     last_overlay_image_ = std::move(params.overlay_image);
+    // Only NV12 format is supported in zero copy presentation path.
+    if (dest_size.has_value() && target_rect.has_value() &&
+        params.z_order > 0) {
+      SetTargetToFullScreen(visual_transform, visual_clip_rect);
+    }
+
     return true;
   }
 
@@ -1510,20 +1565,33 @@
 
   // DWM can turn off the desktop plane if this is a YUV swap chain and the
   // overlay candidate covers the whole screen with letterboxing.
-  // TODO(chunbo): IDXGIDecodeSwapChain path with D3D11VideoDecoder+ZeroCopy
-  // will be supported as well.
   bool is_letterboxing_overlay_ready = false;
-  if (base::FeatureList::IsEnabled(
-          features::kDirectCompositionLetterboxVideoOptimization) &&
-      IsYUVSwapChainFormat(swap_chain_format_)) {
+  if (IsYUVSwapChainFormat(swap_chain_format_) && dest_size.has_value() &&
+      target_rect.has_value()) {
     // Try to QI IDXGIDecodeSwapChain and set the DXGI properties properly, in
     // order to turn off the desktop plane in case of overlay.
-    if (dest_size.has_value() && target_rect.has_value()) {
-      bool succeeded = TryDisableDesktopPlane(*dest_size, *target_rect);
+    bool succeeded = false;
+    Microsoft::WRL::ComPtr<IDXGIDecodeSwapChain> decode_swap_chain;
 
-      if (succeeded && params.z_order > 0) {
-        is_letterboxing_overlay_ready = true;
-      }
+    // Note that QI IDXGIDecodeSwapChain from an RGB swap chain will always
+    // fail.
+    hr = swap_chain_->QueryInterface(IID_PPV_ARGS(&decode_swap_chain));
+    if (SUCCEEDED(hr)) {
+      succeeded = TryDisableDesktopPlane(decode_swap_chain.Get(), *dest_size,
+                                         *target_rect);
+    } else {
+      DLOG(ERROR)
+          << "QueryInterface for IDXGIDecodeSwapChain failed with error 0x"
+          << std::hex << hr;
+    }
+
+    // There should be no other UI content overtop of the video, so that the
+    // letterboxing and positioning can be carried out by DWM. In case of
+    // underlay, both |dest_size| and |target_rect| are initialized according to
+    // swap_chain_size, thus no extra target transform and clip adjustment is
+    // needed as follow-ups.
+    if (succeeded && params.z_order > 0) {
+      is_letterboxing_overlay_ready = true;
     }
   }
 
@@ -1535,24 +1603,10 @@
     return false;
   }
 
-  // Update the visual_clip_rect and visual_transform accordingly after
-  // succeeded presentation with letterboxing for overaly scenario. This will
-  // make sure the video full screen letterboxing take the whole monitor area,
-  // and DWM will take care of the letterboxing info setup automatically.
+  // Update |visual_transform| and |visual_clip_rect| for the full screen
+  // letterboxing overlay presentation.
   if (is_letterboxing_overlay_ready) {
-    // Reset the horizontal/vertical shift according to the visual clip and
-    // original transform, since DWM will do the positioning.
-    visual_transform->set_rc(
-        0, 3,
-        visual_clip_rect->x() -
-            visual_transform->rc(0, 3) * visual_transform->rc(0, 0));
-    visual_transform->set_rc(
-        1, 3,
-        visual_clip_rect->y() -
-            visual_transform->rc(1, 3) * visual_transform->rc(1, 1));
-
-    // Expand the clip rect for swap chain to the whole screen.
-    *visual_clip_rect = gfx::Rect(GetMonitorSize());
+    SetTargetToFullScreen(visual_transform, visual_clip_rect);
   }
 
   last_overlay_image_ = std::move(params.overlay_image);
@@ -2099,10 +2153,10 @@
 
   DXGI_ADAPTER_DESC adapter_desc;
   HRESULT hr = dxgi_adapter->GetDesc(&adapter_desc);
-  if (FAILED(hr)) {
-    DLOG(ERROR) << "Failed to get adapter desc with error 0x" << std::hex << hr;
-  } else {
+  if (SUCCEEDED(hr)) {
     gpu_vendor_id_ = adapter_desc.VendorId;
+  } else {
+    DLOG(ERROR) << "Failed to get adapter desc with error 0x" << std::hex << hr;
   }
 
   return true;
@@ -2153,7 +2207,7 @@
 Microsoft::WRL::ComPtr<IDXGISwapChainMedia>
 SwapChainPresenter::GetSwapChainMedia() const {
   Microsoft::WRL::ComPtr<IDXGISwapChainMedia> swap_chain_media;
-  HRESULT hr = 0;
+  HRESULT hr = S_OK;
   if (decode_swap_chain_) {
     hr = decode_swap_chain_.As(&swap_chain_media);
   } else {
diff --git a/ui/gl/swap_chain_presenter.h b/ui/gl/swap_chain_presenter.h
index b31e2dc..107c34a 100644
--- a/ui/gl/swap_chain_presenter.h
+++ b/ui/gl/swap_chain_presenter.h
@@ -129,11 +129,18 @@
   // Get the size of the monitor on which the window handle is displayed.
   gfx::Size GetMonitorSize() const;
 
+  // Update the |visual_transform| and |visual_clip_rect| accordingly after
+  // succeeded presentation with letterboxing for overaly scenario. This will
+  // make sure the video full screen letterboxing take the whole monitor area,
+  // and DWM will take care of the letterboxing info setup automatically.
+  void SetTargetToFullScreen(gfx::Transform* visual_transform,
+                             gfx::Rect* visual_clip_rect) const;
+
   // Takes in input DC layer params and the video overlay quad. The swap chain
   // backbuffer size will be rounded to the monitor size if it is within a close
-  // margin. The visual_transform will be calculated by what scaling factor is
+  // margin. The |visual_transform| will be calculated by what scaling factor is
   // needed to scale the swap chain backbuffer to the monitor size.
-  // The visual_clip_rect will be adjusted to the monitor size for full screen
+  // The |visual_clip_rect| will be adjusted to the monitor size for full screen
   // mode, and to the video overlay quad for letterboxing mode.
   // The returned optional |dest_size| and |target_rect| have the same meaning
   // as in AdjustTargetForFullScreenLetterboxing.
@@ -185,7 +192,7 @@
 
   // Try presenting to a decode swap chain based on various conditions such as
   // global state (e.g. finch, NV12 support), texture flags, and transform.
-  // Returns true on success.  See PresentToDecodeSwapChain() for more info.
+  // Returns true on success. See PresentToDecodeSwapChain() for more info.
   bool TryPresentToDecodeSwapChain(
       Microsoft::WRL::ComPtr<ID3D11Texture2D> texture,
       unsigned array_slice,
@@ -193,28 +200,22 @@
       const gfx::Rect& content_rect,
       const gfx::Size& swap_chain_size,
       DXGI_FORMAT swap_chain_format,
-      const gfx::Transform& transform_to_root);
-
-  // Try disabling the topmost desktop plane for a swap chain in the case of
-  // full screen. In DWM, the desktop plane can be turned off if the
-  // letterboxing info is set up properly for YUV swapchains, meaning that when
-  // the size of the window and the size of the monitor are the same and there
-  // is no other UI component overtop of the video.
-  // Otherwise, set the letterboxing info with swap chain size in order to
-  // restore the topmost desktop plane, which happens in scenarios like
-  // switching to underlay.
-  // Returns true on successful settings.
-  bool TryDisableDesktopPlane(const gfx::Size& dest_size,
-                              const gfx::Rect& target_rect);
+      const gfx::Transform& transform_to_root,
+      const absl::optional<gfx::Size> dest_size,
+      const absl::optional<gfx::Rect> target_rect);
 
   // Present to a decode swap chain created from compatible video decoder
-  // buffers using given |nv12_image| with destination size |swap_chain_size|.
+  // buffers using given |nv12_image|.
+  // Use |dest_size| for destination size and |target_rect| for target rectangle
+  // if valid. Otherwise, |swap_chain_size| would be used instead.
   // Returns true on success.
   bool PresentToDecodeSwapChain(Microsoft::WRL::ComPtr<ID3D11Texture2D> texture,
                                 unsigned array_slice,
                                 const gfx::ColorSpace& color_space,
                                 const gfx::Rect& content_rect,
-                                const gfx::Size& swap_chain_size);
+                                const gfx::Size& swap_chain_size,
+                                const absl::optional<gfx::Size> dest_size,
+                                const absl::optional<gfx::Rect> target_rect);
 
   // Records presentation statistics in UMA and traces (for pixel tests) for the
   // current swap chain which could either be a regular flip swap chain or a
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc
index a95d6cc..d0ea7f8 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source.cc
+++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -527,7 +527,7 @@
   if (event->IsLocatedEvent()) {
     SetRootLocation(event->AsLocatedEvent());
     auto* cursor_position = connection_->wayland_cursor_position();
-    if (cursor_position) {
+    if (event->IsMouseEvent() && cursor_position) {
       cursor_position->OnCursorPositionChanged(
           GetLocationInScreen(event->AsLocatedEvent()));
     }
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source_unittest.cc b/ui/ozone/platform/wayland/host/wayland_event_source_unittest.cc
index 06020a1..31d3964 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_event_source_unittest.cc
@@ -6,6 +6,8 @@
 
 #include "base/memory/raw_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/ozone/platform/wayland/host/wayland_connection.h"
+#include "ui/ozone/platform/wayland/host/wayland_cursor_position.h"
 #include "ui/ozone/platform/wayland/host/wayland_event_source.h"
 #include "ui/ozone/platform/wayland/host/wayland_seat.h"
 #include "ui/ozone/platform/wayland/test/mock_pointer.h"
@@ -108,6 +110,43 @@
       pointer_delegate_->IsPointerButtonPressed(EF_RIGHT_MOUSE_BUTTON));
 }
 
+TEST_F(WaylandEventSourceTest, TouchDoesNotAffectCursor) {
+  PostToServerAndWait([](wl::TestWaylandServerThread* server) {
+    wl_seat_send_capabilities(
+        server->seat()->resource(),
+        WL_SEAT_CAPABILITY_TOUCH | WL_SEAT_CAPABILITY_POINTER);
+  });
+  ASSERT_TRUE(connection_->seat()->touch());
+  ASSERT_TRUE(connection_->seat()->pointer());
+
+  MockWaylandPlatformWindowDelegate delegate;
+  auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
+                                               kDefaultBounds, &delegate);
+
+  gfx::Point cursor_position =
+      connection_->wayland_cursor_position()->GetCursorSurfacePoint();
+
+  EXPECT_CALL(delegate, DispatchEvent(_)).Times(1);
+
+  PostToServerAndWait(
+      [cursor_position, surface_id = window1->root_surface()->get_surface_id()](
+          wl::TestWaylandServerThread* server) {
+        auto* const surface =
+            server->GetObject<wl::MockSurface>(surface_id)->resource();
+        auto* const touch = server->seat()->touch()->resource();
+
+        wl_touch_send_down(touch, server->GetNextSerial(),
+                           server->GetNextTime(), surface, /*id=*/0,
+                           wl_fixed_from_int(cursor_position.x() + 1),
+                           wl_fixed_from_int(cursor_position.y() + 1));
+
+        wl_touch_send_frame(touch);
+      });
+
+  ASSERT_EQ(connection_->wayland_cursor_position()->GetCursorSurfacePoint(),
+            cursor_position);
+}
+
 // Verify WaylandEventSource properly manages its internal state as pointer
 // button events are sent. More specifically - pointer flags.
 TEST_F(WaylandEventSourceTest, DeleteBeforeTouchFrame) {
diff --git a/ui/ozone/platform/wayland/host/wayland_pointer.cc b/ui/ozone/platform/wayland/host/wayland_pointer.cc
index a209d43..e41e0a6 100644
--- a/ui/ozone/platform/wayland/host/wayland_pointer.cc
+++ b/ui/ozone/platform/wayland/host/wayland_pointer.cc
@@ -91,7 +91,7 @@
 
   if (ShouldSuppressPointerEnterOrLeaveEvents(pointer->connection_)) {
     LOG(ERROR) << "Compositor sent a spurious wl_pointer.enter event during"
-                  "a window drag 'n drop operation. IGNORING.";
+                  " a window drag 'n drop operation. IGNORING.";
     return;
   }
 
@@ -120,7 +120,7 @@
 
   if (ShouldSuppressPointerEnterOrLeaveEvents(pointer->connection_)) {
     LOG(ERROR) << "Compositor sent a spurious wl_pointer.leave event during"
-                  "a window drag 'n drop operation. IGNORING.";
+                  " a window drag 'n drop operation. IGNORING.";
     return;
   }
 
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
index 3efba839..9b66b03 100644
--- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
@@ -285,7 +285,6 @@
   EXPECT_EQ(State::kAttached, drag_controller()->state());
   EXPECT_CALL(delegate_, DispatchEvent(_)).WillOnce([&](Event* event) {
     EXPECT_EQ(ET_TOUCH_MOVED, event->type());
-    EXPECT_EQ(gfx::Point(10, 10), screen_->GetCursorScreenPoint());
   });
   SendDndMotion({10, 10});
 
@@ -295,10 +294,6 @@
     ASSERT_EQ(kDropping, test_step);
     EXPECT_EQ(ET_TOUCH_RELEASED, event->type());
     EXPECT_EQ(State::kDropped, drag_controller()->state());
-    // Ensure PlatformScreen keeps consistent.
-    gfx::Point expected_point{20, 20};
-    expected_point += window_->GetBoundsInDIP().origin().OffsetFromOrigin();
-    EXPECT_EQ(expected_point, screen_->GetCursorScreenPoint());
     EXPECT_EQ(window_->GetWidget(),
               screen_->GetLocalProcessWidgetAtPoint({20, 20}, {}));
     test_step = kDone;
@@ -734,7 +729,6 @@
   EXPECT_EQ(State::kAttached, drag_controller()->state());
   EXPECT_CALL(delegate_, DispatchEvent(_)).WillOnce([&](Event* event) {
     EXPECT_EQ(ET_TOUCH_MOVED, event->type());
-    EXPECT_EQ(gfx::Point(10, 10), screen_->GetCursorScreenPoint());
   });
   SendDndMotion({10, 10});
 
@@ -797,7 +791,6 @@
     location.Offset(0, 3);
   }
 
-  EXPECT_EQ(gfx::Point(30, 42), screen_->GetCursorScreenPoint());
   EXPECT_EQ(target_window->GetWidget(),
             screen_->GetLocalProcessWidgetAtPoint({50, 50}, {}));
 
diff --git a/ui/qt/qt5_shim_moc.cc b/ui/qt/qt5_shim_moc.cc
index 8f8b6b5..6e504f2 100644
--- a/ui/qt/qt5_shim_moc.cc
+++ b/ui/qt/qt5_shim_moc.cc
@@ -23,8 +23,8 @@
 
 QT_BEGIN_MOC_NAMESPACE
 struct qt_meta_stringdata_qt__QtShim_t {
-  QByteArrayData data[6];
-  char stringdata[52];
+  QByteArrayData data[13];
+  char stringdata[151];
 };
 #define QT_MOC_LITERAL(idx, ofs, len)                                       \
   Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(                  \
@@ -33,9 +33,16 @@
 static const qt_meta_stringdata_qt__QtShim_t qt_meta_stringdata_qt__QtShim = {
     {QT_MOC_LITERAL(0, 0, 10), QT_MOC_LITERAL(1, 11, 11),
      QT_MOC_LITERAL(2, 23, 0), QT_MOC_LITERAL(3, 24, 4),
-     QT_MOC_LITERAL(4, 29, 14), QT_MOC_LITERAL(5, 44, 7)},
+     QT_MOC_LITERAL(4, 29, 14), QT_MOC_LITERAL(5, 44, 7),
+     QT_MOC_LITERAL(6, 52, 11), QT_MOC_LITERAL(7, 64, 8),
+     QT_MOC_LITERAL(8, 73, 6), QT_MOC_LITERAL(9, 80, 13),
+     QT_MOC_LITERAL(10, 94, 25), QT_MOC_LITERAL(11, 120, 3),
+     QT_MOC_LITERAL(12, 124, 26)},
     "qt::QtShim\0FontChanged\0\0font\0"
-    "PaletteChanged\0palette"};
+    "PaletteChanged\0palette\0ScreenAdded\0"
+    "QScreen*\0screen\0ScreenRemoved\0"
+    "LogicalDotsPerInchChanged\0dpi\0"
+    "PhysicalDotsPerInchChanged"};
 #undef QT_MOC_LITERAL
 
 static const uint qt_meta_data_qt__QtShim[] = {
@@ -44,7 +51,7 @@
     7,      // revision
     0,      // classname
     0, 0,   // classinfo
-    2, 14,  // methods
+    6, 14,  // methods
     0, 0,   // properties
     0, 0,   // enums/sets
     0, 0,   // constructors
@@ -52,11 +59,15 @@
     0,      // signalCount
 
     // slots: name, argc, parameters, tag, flags
-    1, 1, 24, 2, 0x08 /* Private */, 4, 1, 27, 2, 0x08 /* Private */,
+    1, 1, 44, 2, 0x08 /* Private */, 4, 1, 47, 2, 0x08 /* Private */, 6, 1, 50,
+    2, 0x08 /* Private */, 9, 1, 53, 2, 0x08 /* Private */, 10, 1, 56, 2,
+    0x08 /* Private */, 12, 1, 59, 2, 0x08 /* Private */,
 
     // slots: parameters
     QMetaType::Void, QMetaType::QFont, 3, QMetaType::Void, QMetaType::QPalette,
-    5,
+    5, QMetaType::Void, 0x80000000 | 7, 8, QMetaType::Void, 0x80000000 | 7, 8,
+    QMetaType::Void, QMetaType::QReal, 11, QMetaType::Void, QMetaType::QReal,
+    11,
 
     0  // eod
 };
@@ -74,6 +85,18 @@
       case 1:
         _t->PaletteChanged((*reinterpret_cast<const QPalette(*)>(_a[1])));
         break;
+      case 2:
+        _t->ScreenAdded((*reinterpret_cast<QScreen*(*)>(_a[1])));
+        break;
+      case 3:
+        _t->ScreenRemoved((*reinterpret_cast<QScreen*(*)>(_a[1])));
+        break;
+      case 4:
+        _t->LogicalDotsPerInchChanged((*reinterpret_cast<qreal(*)>(_a[1])));
+        break;
+      case 5:
+        _t->PhysicalDotsPerInchChanged((*reinterpret_cast<qreal(*)>(_a[1])));
+        break;
       default:;
     }
   }
@@ -107,15 +130,15 @@
     return _id;
   }
   if (_c == QMetaObject::InvokeMetaMethod) {
-    if (_id < 2) {
+    if (_id < 6) {
       qt_static_metacall(this, _c, _id, _a);
     }
-    _id -= 2;
+    _id -= 6;
   } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
-    if (_id < 2) {
+    if (_id < 6) {
       *reinterpret_cast<int*>(_a[0]) = -1;
     }
-    _id -= 2;
+    _id -= 6;
   }
   return _id;
 }
diff --git a/ui/qt/qt6_shim_moc.cc b/ui/qt/qt6_shim_moc.cc
index 6d02ca3..a165150 100644
--- a/ui/qt/qt6_shim_moc.cc
+++ b/ui/qt/qt6_shim_moc.cc
@@ -26,8 +26,8 @@
 QT_WARNING_PUSH
 QT_WARNING_DISABLE_DEPRECATED
 struct qt_meta_stringdata_qt__QtShim_t {
-  const uint offsetsAndSize[12];
-  char stringdata0[52];
+  const uint offsetsAndSize[26];
+  char stringdata0[151];
 };
 #define QT_MOC_LITERAL(ofs, len) \
   uint(offsetof(qt_meta_stringdata_qt__QtShim_t, stringdata0) + ofs), len
@@ -38,11 +38,21 @@
         QT_MOC_LITERAL(23, 0),   // ""
         QT_MOC_LITERAL(24, 4),   // "font"
         QT_MOC_LITERAL(29, 14),  // "PaletteChanged"
-        QT_MOC_LITERAL(44, 7)    // "palette"
+        QT_MOC_LITERAL(44, 7),   // "palette"
+        QT_MOC_LITERAL(52, 11),  // "ScreenAdded"
+        QT_MOC_LITERAL(64, 8),   // "QScreen*"
+        QT_MOC_LITERAL(73, 6),   // "screen"
+        QT_MOC_LITERAL(80, 13),  // "ScreenRemoved"
+        QT_MOC_LITERAL(94, 25),  // "LogicalDotsPerInchChanged"
+        QT_MOC_LITERAL(120, 3),  // "dpi"
+        QT_MOC_LITERAL(124, 26)  // "PhysicalDotsPerInchChanged"
 
     },
     "qt::QtShim\0FontChanged\0\0font\0"
-    "PaletteChanged\0palette"};
+    "PaletteChanged\0palette\0ScreenAdded\0"
+    "QScreen*\0screen\0ScreenRemoved\0"
+    "LogicalDotsPerInchChanged\0dpi\0"
+    "PhysicalDotsPerInchChanged"};
 #undef QT_MOC_LITERAL
 
 static const uint qt_meta_data_qt__QtShim[] = {
@@ -51,7 +61,7 @@
     10,     // revision
     0,      // classname
     0, 0,   // classinfo
-    2, 14,  // methods
+    6, 14,  // methods
     0, 0,   // properties
     0, 0,   // enums/sets
     0, 0,   // constructors
@@ -59,11 +69,15 @@
     0,      // signalCount
 
     // slots: name, argc, parameters, tag, flags, initial metatype offsets
-    1, 1, 26, 2, 0x08, 1 /* Private */, 4, 1, 29, 2, 0x08, 3 /* Private */,
+    1, 1, 50, 2, 0x08, 1 /* Private */, 4, 1, 53, 2, 0x08, 3 /* Private */, 6,
+    1, 56, 2, 0x08, 5 /* Private */, 9, 1, 59, 2, 0x08, 7 /* Private */, 10, 1,
+    62, 2, 0x08, 9 /* Private */, 12, 1, 65, 2, 0x08, 11 /* Private */,
 
     // slots: parameters
     QMetaType::Void, QMetaType::QFont, 3, QMetaType::Void, QMetaType::QPalette,
-    5,
+    5, QMetaType::Void, 0x80000000 | 7, 8, QMetaType::Void, 0x80000000 | 7, 8,
+    QMetaType::Void, QMetaType::QReal, 11, QMetaType::Void, QMetaType::QReal,
+    11,
 
     0  // eod
 };
@@ -83,6 +97,22 @@
         _t->PaletteChanged(
             (*reinterpret_cast<std::add_pointer_t<QPalette>>(_a[1])));
         break;
+      case 2:
+        _t->ScreenAdded(
+            (*reinterpret_cast<std::add_pointer_t<QScreen*>>(_a[1])));
+        break;
+      case 3:
+        _t->ScreenRemoved(
+            (*reinterpret_cast<std::add_pointer_t<QScreen*>>(_a[1])));
+        break;
+      case 4:
+        _t->LogicalDotsPerInchChanged(
+            (*reinterpret_cast<std::add_pointer_t<qreal>>(_a[1])));
+        break;
+      case 5:
+        _t->PhysicalDotsPerInchChanged(
+            (*reinterpret_cast<std::add_pointer_t<qreal>>(_a[1])));
+        break;
       default:;
     }
   }
@@ -98,7 +128,15 @@
          QtPrivate::TypeAndForceComplete<void, std::false_type>,
          QtPrivate::TypeAndForceComplete<const QFont&, std::false_type>,
          QtPrivate::TypeAndForceComplete<void, std::false_type>,
-         QtPrivate::TypeAndForceComplete<const QPalette&, std::false_type>
+         QtPrivate::TypeAndForceComplete<const QPalette&, std::false_type>,
+         QtPrivate::TypeAndForceComplete<void, std::false_type>,
+         QtPrivate::TypeAndForceComplete<QScreen*, std::false_type>,
+         QtPrivate::TypeAndForceComplete<void, std::false_type>,
+         QtPrivate::TypeAndForceComplete<QScreen*, std::false_type>,
+         QtPrivate::TypeAndForceComplete<void, std::false_type>,
+         QtPrivate::TypeAndForceComplete<qreal, std::false_type>,
+         QtPrivate::TypeAndForceComplete<void, std::false_type>,
+         QtPrivate::TypeAndForceComplete<qreal, std::false_type>
 
          >,
      nullptr}};
@@ -127,15 +165,15 @@
     return _id;
   }
   if (_c == QMetaObject::InvokeMetaMethod) {
-    if (_id < 2) {
+    if (_id < 6) {
       qt_static_metacall(this, _c, _id, _a);
     }
-    _id -= 2;
+    _id -= 6;
   } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
-    if (_id < 2) {
+    if (_id < 6) {
       *reinterpret_cast<QMetaType*>(_a[0]) = QMetaType();
     }
-    _id -= 2;
+    _id -= 6;
   }
   return _id;
 }
diff --git a/ui/qt/qt_interface.h b/ui/qt/qt_interface.h
index 6a362bc6..28dfc66 100644
--- a/ui/qt/qt_interface.h
+++ b/ui/qt/qt_interface.h
@@ -118,6 +118,7 @@
 
     virtual void FontChanged() = 0;
     virtual void ThemeChanged() = 0;
+    virtual void ScaleFactorMaybeChanged() = 0;
   };
 
   QtInterface() = default;
diff --git a/ui/qt/qt_shim.cc b/ui/qt/qt_shim.cc
index 74d34ad..0aec9c3ae 100644
--- a/ui/qt/qt_shim.cc
+++ b/ui/qt/qt_shim.cc
@@ -16,6 +16,7 @@
 #include <QMimeType>
 #include <QPainter>
 #include <QPalette>
+#include <QScreen>
 #include <QStyle>
 #include <QStyleOptionTitleBar>
 
@@ -52,8 +53,9 @@
 // Obtain the average color of a gradient.
 SkColor GradientColor(const QGradient& gradient) {
   QGradientStops stops = gradient.stops();
-  if (stops.empty())
+  if (stops.empty()) {
     return qRgba(0, 0, 0, 0);
+  }
 
   float a = 0;
   float r = 0;
@@ -86,11 +88,13 @@
 // Obtain the average color of a texture.
 SkColor TextureColor(QImage image) {
   size_t size = image.width() * image.height();
-  if (!size)
+  if (!size) {
     return qRgba(0, 0, 0, 0);
+  }
 
-  if (image.format() != QImage::Format_ARGB32_Premultiplied)
+  if (image.format() != QImage::Format_ARGB32_Premultiplied) {
     image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+  }
 
   size_t a = 0;
   size_t r = 0;
@@ -203,6 +207,13 @@
           SLOT(FontChanged(const QFont&)));
   connect(&app_, SIGNAL(paletteChanged(const QPalette&)), this,
           SLOT(PaletteChanged(const QPalette&)));
+  connect(&app_, SIGNAL(screenAdded(QScreen*)), this,
+          SLOT(ScreenAdded(QScreen*)));
+  connect(&app_, SIGNAL(screenRemoved(QScreen*)), this,
+          SLOT(ScreenRemoved(QScreen*)));
+  for (QScreen* screen : app_.screens()) {
+    ScreenAdded(screen);
+  }
 }
 
 QtShim::~QtShim() = default;
@@ -241,8 +252,9 @@
       auto icon = QIcon::fromTheme(name);
       auto pixmap = icon.pixmap(size);
       auto image = pixmap.toImage();
-      if (image.format() != QImage::Format_ARGB32_Premultiplied)
+      if (image.format() != QImage::Format_ARGB32_Premultiplied) {
         image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+      }
       if (auto bytes = image.sizeInBytes()) {
         return {image.width(), image.height(),
                 static_cast<float>(image.devicePixelRatio()),
@@ -283,6 +295,30 @@
   delegate_->ThemeChanged();
 }
 
+DISABLE_CFI_VCALL
+void QtShim::ScreenAdded(QScreen* screen) {
+  connect(screen, SIGNAL(logicalDotsPerInchChanged(qreal)), this,
+          SLOT(LogicalDotsPerInchChanged(qreal)));
+  connect(screen, SIGNAL(physicalDotsPerInchChanged(qreal)), this,
+          SLOT(PhysicalDotsPerInchChanged(qreal)));
+  delegate_->ScaleFactorMaybeChanged();
+}
+
+DISABLE_CFI_VCALL
+void QtShim::ScreenRemoved(QScreen* screen) {
+  delegate_->ScaleFactorMaybeChanged();
+}
+
+DISABLE_CFI_VCALL
+void QtShim::LogicalDotsPerInchChanged(qreal dpi) {
+  delegate_->ScaleFactorMaybeChanged();
+}
+
+DISABLE_CFI_VCALL
+void QtShim::PhysicalDotsPerInchChanged(qreal dpi) {
+  delegate_->ScaleFactorMaybeChanged();
+}
+
 Image QtShim::DrawHeader(int width,
                          int height,
                          SkColor default_color,
@@ -309,8 +345,9 @@
     QStyleOptionTitleBar opt;
     opt.rect = QRect(-kBorderWidth, -kBorderWidth, width + 2 * kBorderWidth,
                      height + 2 * kBorderWidth);
-    if (state == ColorState::kNormal)
+    if (state == ColorState::kNormal) {
       opt.titleBarState = QStyle::State_Active;
+    }
     app_.style()->drawComplexControl(QStyle::CC_TitleBar, &opt, &painter,
                                      nullptr);
   } else {
diff --git a/ui/qt/qt_shim.h b/ui/qt/qt_shim.h
index 607e6fe..d979c47 100644
--- a/ui/qt/qt_shim.h
+++ b/ui/qt/qt_shim.h
@@ -42,6 +42,10 @@
  private slots:
   void FontChanged(const QFont& font);
   void PaletteChanged(const QPalette& palette);
+  void ScreenAdded(QScreen* screen);
+  void ScreenRemoved(QScreen* screen);
+  void LogicalDotsPerInchChanged(qreal dpi);
+  void PhysicalDotsPerInchChanged(qreal dpi);
 
  private:
   QImage DrawHeaderImpl(int width,
diff --git a/ui/qt/qt_ui.cc b/ui/qt/qt_ui.cc
index 6a3b58e..bac5245a 100644
--- a/ui/qt/qt_ui.cc
+++ b/ui/qt/qt_ui.cc
@@ -19,6 +19,7 @@
 #include "base/nix/xdg_util.h"
 #include "base/notreached.h"
 #include "base/path_service.h"
+#include "base/task/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "cc/paint/paint_canvas.h"
 #include "chrome/browser/themes/theme_properties.h"  // nogncheck
@@ -36,6 +37,7 @@
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia_rep.h"
 #include "ui/gfx/image/image_skia_source.h"
+#include "ui/linux/device_scale_factor_observer.h"
 #include "ui/linux/linux_ui.h"
 #include "ui/linux/nav_button_provider.h"
 #include "ui/native_theme/native_theme_aura.h"
@@ -194,16 +196,21 @@
                                      int* style_out,
                                      int* weight_out,
                                      gfx::FontRenderParams* params_out) const {
-  if (family_out)
+  if (family_out) {
     *family_out = font_family_;
-  if (size_pixels_out)
+  }
+  if (size_pixels_out) {
     *size_pixels_out = font_size_pixels_;
-  if (style_out)
+  }
+  if (style_out) {
     *style_out = font_style_;
-  if (weight_out)
+  }
+  if (weight_out) {
     *weight_out = font_weight_;
-  if (params_out)
+  }
+  if (params_out) {
     *params_out = font_params_;
+  }
 }
 
 ui::SelectFileDialog* QtUi::CreateSelectFileDialog(
@@ -218,14 +225,16 @@
 DISABLE_CFI_VCALL
 bool QtUi::Initialize() {
   base::FilePath path;
-  if (!base::PathService::Get(base::DIR_MODULE, &path))
+  if (!base::PathService::Get(base::DIR_MODULE, &path)) {
     return false;
+  }
   void* libqt_shim =
       PreferQt6()
           ? LoadLibraryOrFallback(path, "libqt6_shim.so", "libqt5_shim.so")
           : LoadLibraryOrFallback(path, "libqt5_shim.so", "libqt6_shim.so");
-  if (!libqt_shim)
+  if (!libqt_shim) {
     return false;
+  }
   void* create_qt_interface = dlsym(libqt_shim, "CreateQtInterface");
   DCHECK(create_qt_interface);
 
@@ -236,6 +245,7 @@
   ui::ColorProviderManager::Get().AppendColorProviderInitializer(
       base::BindRepeating(&QtUi::AddNativeColorMixer, base::Unretained(this)));
   FontChanged();
+  scale_factor_ = shim_->GetScaleFactor();
 
   return true;
 }
@@ -246,8 +256,9 @@
 
 bool QtUi::GetColor(int id, SkColor* color, bool use_custom_frame) const {
   auto value = GetColor(id, use_custom_frame);
-  if (value)
+  if (value) {
     *color = *value;
+  }
   return value.has_value();
 }
 
@@ -297,8 +308,9 @@
                                        float scale) const {
   Image image =
       shim_->GetIconForContentType(String(content_type.c_str()), size * scale);
-  if (!image.data_argb.size())
+  if (!image.data_argb.size()) {
     return {};
+  }
 
   SkImageInfo image_info = SkImageInfo::Make(
       image.width, image.height, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
@@ -345,14 +357,16 @@
 
 void QtUi::AddWindowButtonOrderObserver(
     ui::WindowButtonOrderObserver* observer) {
-  if (fallback_linux_ui_)
+  if (fallback_linux_ui_) {
     fallback_linux_ui_->AddWindowButtonOrderObserver(observer);
+  }
 }
 
 void QtUi::RemoveWindowButtonOrderObserver(
     ui::WindowButtonOrderObserver* observer) {
-  if (fallback_linux_ui_)
+  if (fallback_linux_ui_) {
     fallback_linux_ui_->RemoveWindowButtonOrderObserver(observer);
+  }
 }
 
 std::unique_ptr<ui::NavButtonProvider> QtUi::CreateNavButtonProvider() {
@@ -441,11 +455,24 @@
   native_theme_->ThemeChanged(PreferDarkTheme());
 }
 
+void QtUi::ScaleFactorMaybeChanged() {
+  // This gets called whenever the monitor configuration changes.  Handle the
+  // scale change asynchronously to allow the change to propagate to QT's scale
+  // factor. This also coalesces scale change events together.
+  if (!scale_factor_task_active_) {
+    scale_factor_task_active_ = true;
+    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
+        FROM_HERE, base::BindOnce(&QtUi::ScaleFactorMaybeChangedImpl,
+                                  weak_factory_.GetWeakPtr()));
+  }
+}
+
 DISABLE_CFI_VCALL
 void QtUi::AddNativeColorMixer(ui::ColorProvider* provider,
                                const ui::ColorProviderManager::Key& key) {
-  if (key.system_theme != ui::SystemTheme::kQt)
+  if (key.system_theme != ui::SystemTheme::kQt) {
     return;
+  }
 
   ui::ColorMixer& mixer = provider->AddMixer();
   // These color constants are required by native_chrome_color_mixer_linux.cc
@@ -494,8 +521,9 @@
        ColorState::kInactive},
       {ui::kColorNativeToolbarBackground, ColorType::kButtonBg},
   };
-  for (const auto& map : kMaps)
+  for (const auto& map : kMaps) {
     mixer[map.id] = {shim_->GetColor(map.role, map.state)};
+  }
 
   const bool use_custom_frame =
       key.frame_type == ui::ColorProviderManager::FrameType::kChromium;
@@ -578,6 +606,20 @@
   }
 }
 
+DISABLE_CFI_VCALL
+void QtUi::ScaleFactorMaybeChangedImpl() {
+  scale_factor_task_active_ = false;
+  double scale = shim_->GetScaleFactor();
+  if (scale == scale_factor_) {
+    return;
+  }
+  scale_factor_ = scale;
+  for (ui::DeviceScaleFactorObserver& observer :
+       device_scale_factor_observer_list()) {
+    observer.OnDeviceScaleFactorChanged();
+  }
+}
+
 std::unique_ptr<ui::LinuxUiAndTheme> CreateQtUi(
     ui::LinuxUi* fallback_linux_ui) {
   return std::make_unique<QtUi>(fallback_linux_ui);
diff --git a/ui/qt/qt_ui.h b/ui/qt/qt_ui.h
index b53ed93..3319edf 100644
--- a/ui/qt/qt_ui.h
+++ b/ui/qt/qt_ui.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/component_export.h"
+#include "base/memory/weak_ptr.h"
 #include "printing/buildflags/buildflags.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/color/color_provider.h"
@@ -88,11 +89,14 @@
   // QtInterface::Delegate:
   void FontChanged() override;
   void ThemeChanged() override;
+  void ScaleFactorMaybeChanged() override;
 
  private:
   void AddNativeColorMixer(ui::ColorProvider* provider,
                            const ui::ColorProviderManager::Key& key);
 
+  void ScaleFactorMaybeChangedImpl();
+
   absl::optional<SkColor> GetColor(int id, bool use_custom_frame) const;
 
   // TODO(https://crbug.com/1317782): This is a fallback for any unimplemented
@@ -114,6 +118,11 @@
   std::unique_ptr<QtInterface> shim_;
 
   std::unique_ptr<QtNativeTheme> native_theme_;
+
+  bool scale_factor_task_active_ = false;
+  double scale_factor_ = 1.0;
+
+  base::WeakPtrFactory<QtUi> weak_factory_{this};
 };
 
 // This should be the only symbol exported from this component.
diff --git a/ui/views/controls/menu/menu_config.h b/ui/views/controls/menu/menu_config.h
index 1d4cde3..c0784dd 100644
--- a/ui/views/controls/menu/menu_config.h
+++ b/ui/views/controls/menu/menu_config.h
@@ -153,9 +153,6 @@
   // Whether the keyboard accelerators are visible.
   bool show_accelerators = true;
 
-  // True if icon to label padding is always added with or without icon.
-  bool always_use_icon_to_label_padding = false;
-
   // True if submenu arrow and shortcut right edge should be aligned.
   bool align_arrow_and_shortcut = false;
 
diff --git a/ui/views/controls/menu/menu_config_chromeos.cc b/ui/views/controls/menu/menu_config_chromeos.cc
index 931b673..0b2ed7c1 100644
--- a/ui/views/controls/menu/menu_config_chromeos.cc
+++ b/ui/views/controls/menu/menu_config_chromeos.cc
@@ -18,7 +18,6 @@
   separator_spacing_height = 7;
   separator_lower_height = 8;
   separator_upper_height = 8;
-  always_use_icon_to_label_padding = true;
   align_arrow_and_shortcut = true;
   offset_context_menus = true;
   corner_radius = 2;
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc
index e235da7..4f2dc50 100644
--- a/ui/views/controls/menu/menu_item_view.cc
+++ b/ui/views/controls/menu/menu_item_view.cc
@@ -382,10 +382,9 @@
     return nullptr;
   }
   MenuItemView* item = new MenuItemView(this, item_id, type);
-  if (label.empty() && GetDelegate())
-    item->SetTitle(GetDelegate()->GetLabel(item_id));
-  else
-    item->SetTitle(label);
+  item->SetTitle(label.empty() && GetDelegate()
+                     ? GetDelegate()->GetLabel(item_id)
+                     : label);
   item->SetSecondaryTitle(secondary_label);
   item->SetMinorText(minor_text);
   item->SetMinorIcon(minor_icon);
@@ -753,43 +752,39 @@
       child->SetBounds(child_x - width, 0, width, height());
       child_x -= width + kChildXPadding;
     }
-    // Position |icon_view|.
+
+    // Position the icons.
     const MenuConfig& config = MenuConfig::instance();
+    const int icon_x = GetContentStart();
+    if (radio_check_image_view_) {
+      const int y =
+          (height() + GetTopMargin() - GetBottomMargin() - kMenuCheckSize) / 2;
+      radio_check_image_view_->SetBounds(icon_x, y, kMenuCheckSize,
+                                         kMenuCheckSize);
+    }
     if (icon_view_) {
       icon_view_->SizeToPreferredSize();
       gfx::Size size = icon_view_->GetPreferredSize();
-      int x = config.item_horizontal_padding +
-              config.item_horizontal_border_padding +
-              (icon_area_width_ - size.width()) / 2;
-      if (config.icons_in_label || type_ == Type::kCheckbox ||
-          type_ == Type::kRadio)
+      int x = (config.icons_in_label ? label_start_ : icon_x) +
+              ((icon_area_width_ - size.width()) / 2);
+      // If this is a checkbox or radio, then it needs space for both the
+      // radio/check image and an icon, so move the icon to where the label
+      // would start.
+      if (type_ == Type::kCheckbox || type_ == Type::kRadio) {
         x = label_start_;
-      if (GetMenuController() &&
-          GetMenuController()->use_ash_system_ui_layout())
-        x = config.touchable_item_horizontal_padding;
-
-      int y =
+      }
+      const int y =
           (height() + GetTopMargin() - GetBottomMargin() - size.height()) / 2;
       icon_view_->SetPosition(gfx::Point(x, y));
     }
 
-    if (radio_check_image_view_) {
-      int x = config.item_horizontal_padding;
-      if (GetMenuController() &&
-          GetMenuController()->use_ash_system_ui_layout())
-        x = config.touchable_item_horizontal_padding;
-      int y =
-          (height() + GetTopMargin() - GetBottomMargin() - kMenuCheckSize) / 2;
-      radio_check_image_view_->SetBounds(x, y, kMenuCheckSize, kMenuCheckSize);
-    }
-
     if (submenu_arrow_image_view_) {
-      int x = width() - config.arrow_width -
-              (type_ == Type::kActionableSubMenu
-                   ? config.actionable_submenu_arrow_to_edge_padding
-                   : config.arrow_to_edge_padding) -
-              config.item_horizontal_border_padding;
-      int y =
+      const int x = width() - config.item_horizontal_border_padding -
+                    (type_ == Type::kActionableSubMenu
+                         ? config.actionable_submenu_arrow_to_edge_padding
+                         : config.arrow_to_edge_padding) -
+                    config.arrow_width;
+      const int y =
           (height() + GetTopMargin() - GetBottomMargin() - kSubmenuArrowSize) /
           2;
       submenu_arrow_image_view_->SetBounds(x, y, config.arrow_width,
@@ -867,26 +862,24 @@
   item_right_margin_ = config.label_to_arrow_padding + config.arrow_width +
                        config.arrow_to_edge_padding +
                        config.item_horizontal_border_padding;
-  icon_area_width_ = config.check_width;
-  if (has_icons_)
-    icon_area_width_ = std::max(icon_area_width_, GetMaxIconViewWidth());
-
-  const bool use_ash_system_ui_layout =
-      GetMenuController() && GetMenuController()->use_ash_system_ui_layout();
-  label_start_ =
-      (use_ash_system_ui_layout ? config.touchable_item_horizontal_padding
-                                : config.item_horizontal_padding) +
-      icon_area_width_ + config.item_horizontal_border_padding;
-
-  const bool use_padding = config.always_use_icon_to_label_padding ||
-                           (!config.icons_in_label && has_icons_) ||
-                           HasChecksOrRadioButtons() ||
-                           use_ash_system_ui_layout;
-  int padding = use_padding ? LayoutProvider::Get()->GetDistanceMetric(
-                                  DISTANCE_RELATED_LABEL_HORIZONTAL)
-                            : 0;
-
-  label_start_ += padding;
+  icon_area_width_ = std::max(
+      HasChecksOrRadioButtons() ? config.check_width : 0,
+      (has_icons_ && !config.icons_in_label) ? GetMaxIconViewWidth() : 0);
+  label_start_ = GetContentStart() + icon_area_width_;
+  if (icon_area_width_) {
+    if (GetMenuController() &&
+        GetMenuController()->use_ash_system_ui_layout()) {
+      label_start_ += config.touchable_item_horizontal_padding;
+    } else if (config.icons_in_label) {
+      label_start_ += config.item_horizontal_padding;
+    } else {
+      label_start_ += LayoutProvider::Get()->GetDistanceMetric(
+          DISTANCE_RELATED_LABEL_HORIZONTAL);
+    }
+  }
+  if (config.icons_in_label) {
+    icon_area_width_ = GetMaxIconViewWidth();
+  }
 
   EmptyMenuMenuItem menu_item(this);
   menu_item.set_controller(GetMenuController());
@@ -1136,22 +1129,22 @@
 }
 
 void MenuItemView::PaintMinorIconAndText(gfx::Canvas* canvas, SkColor color) {
-  std::u16string minor_text = GetMinorText();
+  const std::u16string minor_text = GetMinorText();
   const ui::ImageModel minor_icon = GetMinorIcon();
-  if (minor_text.empty() && minor_icon.IsEmpty())
+  if (minor_text.empty() && minor_icon.IsEmpty()) {
     return;
+  }
 
-  int available_height = height() - GetTopMargin() - GetBottomMargin();
-  int max_minor_text_width =
+  const int max_minor_text_width =
       parent_menu_item_->GetSubmenu()->max_minor_text_width();
   const MenuConfig& config = MenuConfig::instance();
-  int minor_text_right_margin =
-      (config.align_arrow_and_shortcut ? config.arrow_to_edge_padding
-                                       : item_right_margin_) +
-      config.item_horizontal_border_padding;
+  const int minor_text_right_margin =
+      config.align_arrow_and_shortcut ? (config.arrow_to_edge_padding +
+                                         config.item_horizontal_border_padding)
+                                      : item_right_margin_;
   gfx::Rect minor_text_bounds(
       width() - minor_text_right_margin - max_minor_text_width, GetTopMargin(),
-      max_minor_text_width, available_height);
+      max_minor_text_width, height() - GetTopMargin() - GetBottomMargin());
   minor_text_bounds.set_x(GetMirroredXForRect(minor_text_bounds));
 
   std::unique_ptr<gfx::RenderText> render_text =
@@ -1169,13 +1162,14 @@
   if (!minor_icon.IsEmpty()) {
     const gfx::ImageSkia image = minor_icon.Rasterize(GetColorProvider());
 
-    int image_x = GetMirroredRect(minor_text_bounds).right() -
-                  render_text->GetContentWidth() -
-                  (minor_text.empty() ? 0 : config.item_horizontal_padding) -
-                  image.width();
-    int minor_text_center_y =
-        minor_text_bounds.y() + minor_text_bounds.height() / 2;
-    int image_y = minor_text_center_y - image.height() / 2;
+    const int image_x =
+        GetMirroredRect(minor_text_bounds).right() -
+        render_text->GetContentWidth() -
+        (minor_text.empty() ? 0 : config.item_horizontal_padding) -
+        image.width();
+    const int image_y =
+        (minor_text_bounds.y() + minor_text_bounds.height() - image.height()) /
+        2;
     canvas->DrawImageInt(
         image, GetMirroredXWithWidthInView(image_x, image.width()), image_y);
   }
@@ -1202,16 +1196,15 @@
           : style::CONTEXT_MENU;
 
   style::TextStyle text_style = style::STYLE_PRIMARY;
-  if (type_ == Type::kTitle)
-    text_style = style::STYLE_PRIMARY;
-  else if (type_ == Type::kHighlighted)
+  if (type_ == Type::kHighlighted) {
     text_style = style::STYLE_HIGHLIGHTED;
-  else if (!GetEnabled())
+  } else if (!GetEnabled()) {
     text_style = style::STYLE_DISABLED;
-  else if (paint_as_selected)
+  } else if (paint_as_selected) {
     text_style = style::STYLE_SELECTED;
-  else if (minor)
+  } else if (minor) {
     text_style = style::STYLE_SECONDARY;
+  }
 
   return GetColorProvider()->GetColor(style::GetColorId(context, text_style));
 }
@@ -1323,23 +1316,21 @@
     // |children_width|. Setting a |standard_width| would result in additional
     // width being added to the container because the total width used in layout
     // is |children_width| + |standard_width|.
-    if (IsContainer())
-      return dimensions;
+    if (!IsContainer()) {
+      // Calculate total item width to make sure the current |title_|
+      // has enough room within the context menu.
+      dimensions.standard_width = std::clamp(
+          GetLabelStartForThisItem() + gfx::GetStringWidth(title_, font_list) +
+              item_right_margin_,
+          menu_config.touchable_menu_min_width,
+          menu_config.touchable_menu_max_width);
 
-    // Calculate total item width to make sure the current |title_|
-    // has enough room within the context menu.
-    int label_start = GetLabelStartForThisItem();
-    int string_width = gfx::GetStringWidth(title_, font_list);
-    int item_width = string_width + label_start + item_right_margin_ +
-                     menu_config.item_horizontal_border_padding * 2;
-
-    item_width = std::max(item_width, menu_config.touchable_menu_min_width);
-    item_width = std::min(item_width, menu_config.touchable_menu_max_width);
-    dimensions.standard_width = item_width;
-
-    if (icon_view_) {
-      dimensions.height = icon_view_->GetPreferredSize().height() +
-                          2 * menu_config.vertical_touchable_menu_item_padding;
+      if (icon_view_) {
+        dimensions.height =
+            std::max(dimensions.height,
+                     icon_view_->GetPreferredSize().height() +
+                         2 * menu_config.vertical_touchable_menu_item_padding);
+      }
     }
     return dimensions;
   }
@@ -1366,10 +1357,9 @@
 
   dimensions.height += GetBottomMargin() + GetTopMargin();
 
-  int string_width = gfx::GetStringWidth(title_, font_list);
-  int label_start = GetLabelStartForThisItem();
-  dimensions.standard_width = string_width + label_start + item_right_margin_ +
-                              menu_config.item_horizontal_border_padding * 2;
+  dimensions.standard_width = GetLabelStartForThisItem() +
+                              gfx::GetStringWidth(title_, font_list) +
+                              item_right_margin_;
 
   // Determine the length of the right-side text.
   dimensions.minor_text_width =
@@ -1415,26 +1405,33 @@
                                         : config.minimum_text_item_height);
 }
 
-int MenuItemView::GetLabelStartForThisItem() const {
+int MenuItemView::GetContentStart() const {
   const MenuConfig& config = MenuConfig::instance();
+  const bool use_ash_system_ui_layout =
+      GetMenuController() && GetMenuController()->use_ash_system_ui_layout();
+  return config.item_horizontal_border_padding +
+         (use_ash_system_ui_layout ? config.touchable_item_horizontal_padding
+                                   : config.item_horizontal_padding);
+}
 
-  // Touchable items with icons do not respect |label_start_|.
-  if (GetMenuController() && GetMenuController()->use_ash_system_ui_layout() &&
-      icon_view_) {
-    return 2 * config.touchable_item_horizontal_padding +
-           icon_view_->GetPreferredSize().width();
+int MenuItemView::GetLabelStartForThisItem() const {
+  const bool icons_in_label = MenuConfig::instance().icons_in_label;
+  // When `!icons_in_label`, checkbox or radio items that also have icons draw
+  // the check/radio in the normal icon space and move the icon to where the
+  // label starts; see comments in Layout().
+  if (!icon_view_ ||
+      (!icons_in_label && type_ != Type::kCheckbox && type_ != Type::kRadio)) {
+    return label_start_;
   }
 
-  int label_start = label_start_;
-  if ((config.icons_in_label || type_ == Type::kCheckbox ||
-       type_ == Type::kRadio) &&
-      icon_view_) {
-    label_start += icon_view_->GetPreferredSize().width() +
-                   LayoutProvider::Get()->GetDistanceMetric(
-                       DISTANCE_RELATED_LABEL_HORIZONTAL);
-  }
-
-  return label_start;
+  // The icon will be drawn starting where the label normally starts, so indent
+  // past it.
+  const int icon_width = icons_in_label
+                             ? icon_area_width_
+                             : icon_view_->GetPreferredSize().width();
+  return label_start_ + icon_width +
+         LayoutProvider::Get()->GetDistanceMetric(
+             DISTANCE_RELATED_LABEL_HORIZONTAL);
 }
 
 std::u16string MenuItemView::GetMinorText() const {
@@ -1500,9 +1497,7 @@
     if (item->HasSubmenu()) {
       return item->GetMaxIconViewWidth();
     }
-    return (item->icon_view_ && !MenuConfig::instance().icons_in_label)
-               ? item->icon_view_->GetPreferredSize().width()
-               : 0;
+    return item->icon_view_ ? item->icon_view_->GetPreferredSize().width() : 0;
   });
   return base::ranges::max(widths);
 }
diff --git a/ui/views/controls/menu/menu_item_view.h b/ui/views/controls/menu/menu_item_view.h
index 3dbbcbf..43b5a73 100644
--- a/ui/views/controls/menu/menu_item_view.h
+++ b/ui/views/controls/menu/menu_item_view.h
@@ -501,6 +501,9 @@
   //    ApplyMinimumDimensions(x).height >= x.height
   void ApplyMinimumDimensions(MenuItemDimensions* dims) const;
 
+  // Returns the earliest horizontal position where content may appear.
+  int GetContentStart() const;
+
   // Get the horizontal position at which to draw the menu item's label.
   int GetLabelStartForThisItem() const;
 
diff --git a/ui/views/controls/webview/BUILD.gn b/ui/views/controls/webview/BUILD.gn
index f37a5a8..7462baf7 100644
--- a/ui/views/controls/webview/BUILD.gn
+++ b/ui/views/controls/webview/BUILD.gn
@@ -41,6 +41,7 @@
     "//ui/content_accelerators",
     "//ui/events",
     "//ui/events:events_base",
+    "//ui/gfx:native_widget_types",
     "//ui/web_dialogs",
     "//url",
   ]
@@ -61,6 +62,10 @@
       sources += [ "unhandled_keyboard_event_handler_default.cc" ]
     }
   }
+
+  if (is_mac) {
+    deps += [ "//base:base_arc" ]
+  }
 }
 
 static_library("test_support") {
diff --git a/ui/views/controls/webview/unhandled_keyboard_event_handler.cc b/ui/views/controls/webview/unhandled_keyboard_event_handler.cc
index e520615..badf6378 100644
--- a/ui/views/controls/webview/unhandled_keyboard_event_handler.cc
+++ b/ui/views/controls/webview/unhandled_keyboard_event_handler.cc
@@ -6,6 +6,7 @@
 
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "ui/content_accelerators/accelerator_util.h"
+#include "ui/gfx/native_widget_types.h"
 #include "ui/views/focus/focus_manager.h"
 
 namespace views {
@@ -49,8 +50,9 @@
     ignore_next_char_event_ = false;
   }
 
-  if (event.os_event)
+  if (gfx::IsNativeEventValid(event.os_event)) {
     return HandleNativeKeyboardEvent(event, focus_manager);
+  }
 
   return false;
 }
diff --git a/ui/views/controls/webview/unhandled_keyboard_event_handler_mac.mm b/ui/views/controls/webview/unhandled_keyboard_event_handler_mac.mm
index 66905c2..d067fe6 100644
--- a/ui/views/controls/webview/unhandled_keyboard_event_handler_mac.mm
+++ b/ui/views/controls/webview/unhandled_keyboard_event_handler_mac.mm
@@ -13,14 +13,16 @@
 bool UnhandledKeyboardEventHandler::HandleNativeKeyboardEvent(
     const content::NativeWebKeyboardEvent& event,
     FocusManager* focus_manager) {
-  if (event.skip_in_browser)
+  if (event.skip_in_browser) {
     return false;
+  }
 
-  auto os_event = event.os_event;
-  auto* host = views::NativeWidgetMacNSWindowHost::GetFromNativeWindow(
-      [os_event window]);
-  if (host)
-    return host->RedispatchKeyEvent(os_event);
+  NSEvent* ns_event = event.os_event.Get();
+  auto* host =
+      views::NativeWidgetMacNSWindowHost::GetFromNativeWindow(ns_event.window);
+  if (host) {
+    return host->RedispatchKeyEvent(ns_event);
+  }
   return false;
 }
 
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc
index af075e8..d7f5236 100644
--- a/ui/views/controls/webview/web_dialog_view.cc
+++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -20,6 +20,7 @@
 #include "ui/events/event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/gfx/geometry/rounded_corners_f.h"
+#include "ui/gfx/native_widget_types.h"
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/widget/native_widget_private.h"
@@ -370,8 +371,9 @@
 // they're all browser-specific. (This may change in the future.)
 bool WebDialogView::HandleKeyboardEvent(content::WebContents* source,
                                         const NativeWebKeyboardEvent& event) {
-  if (!event.os_event)
+  if (!gfx::IsNativeEventValid(event.os_event)) {
     return false;
+  }
 
   return unhandled_keyboard_event_handler_.HandleKeyboardEvent(
       event, GetFocusManager());
diff --git a/ui/views/examples/vector_example.cc b/ui/views/examples/vector_example.cc
index 4e1bb21..2b429f40 100644
--- a/ui/views/examples/vector_example.cc
+++ b/ui/views/examples/vector_example.cc
@@ -4,6 +4,7 @@
 
 #include "ui/views/examples/vector_example.h"
 
+#include <algorithm>
 #include <memory>
 #include <string>
 #include <utility>
@@ -209,10 +210,17 @@
       base::ScopedAllowBlockingForTesting allow_blocking;
       base::FileEnumerator file_iter(path, false, base::FileEnumerator::FILES,
                                      FILE_PATH_LITERAL("*.icon"));
-      base::FilePath file = file_iter.Next();
+      std::vector<base::FilePath> files;
+      for (base::FilePath input_file = file_iter.Next(); !input_file.empty();
+           input_file = file_iter.Next()) {
+        files.push_back(input_file);
+      }
+      std::sort(files.begin(), files.end());
 
-      while (!file.empty() && count < max) {
-        count++;
+      for (base::FilePath file : files) {
+        if (count++ >= max) {
+          break;
+        }
         std::string file_content;
         base::ReadFileToString(file, &file_content);
 
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 07f4fc7..1dcb402 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -965,7 +965,9 @@
 }
 
 void DesktopNativeWidgetAura::PaintAsActiveChanged() {
-  desktop_window_tree_host_->PaintAsActiveChanged();
+  if (desktop_window_tree_host_) {
+    desktop_window_tree_host_->PaintAsActiveChanged();
+  }
 }
 
 void DesktopNativeWidgetAura::SetZOrderLevel(ui::ZOrderLevel order) {
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
index e8ca140..1ae66541 100644
--- a/ui/views/widget/widget_unittest.cc
+++ b/ui/views/widget/widget_unittest.cc
@@ -3489,6 +3489,49 @@
   EXPECT_EQ(bubble_counter.CallCount(), 0);
 }
 
+// Widget delegate that holds paint as active lock during its lifetime.
+class PaintAsActiveTestDesktopWidgetDelegate
+    : public TestDesktopWidgetDelegate {
+ public:
+  PaintAsActiveTestDesktopWidgetDelegate() = default;
+  ~PaintAsActiveTestDesktopWidgetDelegate() override = default;
+
+  void LockWidgetPaintAsActive() {
+    paint_as_active_lock_ = GetWidget()->LockPaintAsActive();
+  }
+
+ private:
+  std::unique_ptr<Widget::PaintAsActiveLock> paint_as_active_lock_;
+};
+
+// Tests that there is no crash when paint as active lock is removed for child
+// widget while its parent widget is being closed.
+TEST_F(DesktopWidgetTest, LockPaintAsActiveAndCloseParent) {
+  // Make sure that DesktopNativeWidgetAura is used for widgets.
+  test_views_delegate()->set_use_desktop_native_widgets(true);
+
+  std::unique_ptr<Widget> parent = CreateTestWidget();
+  parent->Show();
+
+  auto* delegate = new PaintAsActiveTestDesktopWidgetDelegate();
+  // Ensure that the delegate is destroyed in Widget::OnNativeWidgetDestroyed().
+  delegate->SetOwnedByWidget(true);
+  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+  params.parent = parent->GetNativeView();
+  delegate->InitWidget(std::move(params));
+  delegate->LockWidgetPaintAsActive();
+  base::WeakPtr<Widget> child = delegate->GetWidget()->GetWeakPtr();
+  child->ShowInactive();
+
+  // Child widget and its delegate are destroyed when the parent widget is being
+  // closed. PaintAsActiveTestDesktopWidgetDelegate::paint_as_active_lock_ is
+  // also deleted which should not cause a crash.
+  parent->CloseNow();
+
+  // Ensure that child widget has been destroyed.
+  ASSERT_FALSE(child);
+}
+
 // Widget used to destroy itself when OnNativeWidgetDestroyed is called.
 class TestNativeWidgetDestroyedWidget : public Widget {
  public:
diff --git a/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.html b/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.html
index fad1c2eb..efb7e1ab 100644
--- a/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.html
+++ b/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.html
@@ -26,10 +26,10 @@
       </div>
       <div slot="button-container">
         <paper-spinner-lite id="spinner"></paper-spinner-lite>
-        <cr-button class="cancel-button" on-click="onCancelTap_">
+        <cr-button class="cancel-button" on-click="onCancelClick_">
           [[i18n('cancel')]]
         </cr-button>
-        <cr-button id="ok" class="action-button" on-click="onOkTap_">
+        <cr-button id="ok" class="action-button" on-click="onOkClick_">
           [[i18n('ok')]]
         </cr-button>
       </div>
diff --git a/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.ts
index 8f83ca3c..324eed24 100644
--- a/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.ts
@@ -84,11 +84,11 @@
     }
   }
 
-  private onCancelTap_() {
+  private onCancelClick_() {
     this.$.dialog.close();
   }
 
-  private onOkTap_() {
+  private onOkClick_() {
     this.$.spinner.active = true;
 
     const whenDone = (this.model as CertificateSubnode).id ?
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.html
index ccdb8d5..ab2efad 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.html
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.html
@@ -7,10 +7,10 @@
         <div>[[getDescriptionText_(model, certificateType)]]</div>
       </div>
       <div slot="button-container">
-        <cr-button class="cancel-button" on-click="onCancelTap_">
+        <cr-button class="cancel-button" on-click="onCancelClick_">
           [[i18n('cancel')]]
         </cr-button>
-        <cr-button id="ok" class="action-button" on-click="onOkTap_">
+        <cr-button id="ok" class="action-button" on-click="onOkClick_">
           [[i18n('ok')]]
         </cr-button>
       </div>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.ts
index cfba7db..663f60cf 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.ts
@@ -88,11 +88,11 @@
     }
   }
 
-  private onCancelTap_() {
+  private onCancelClick_() {
     this.$.dialog.close();
   }
 
-  private onOkTap_() {
+  private onOkClick_() {
     CertificatesBrowserProxyImpl.getInstance()
         .deleteCertificate(this.model.id)
         .then(
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_list.html b/ui/webui/resources/cr_components/certificate_manager/certificate_list.html
index 418e0ed..95ccc3c 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_list.html
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_list.html
@@ -15,11 +15,11 @@
     <div class="button-box">
       <span class="flex">
           [[getDescription_(certificateType, certificates)]]</span>
-      <cr-button id="import" on-click="onImportTap_"
+      <cr-button id="import" on-click="onImportClick_"
           hidden="[[!canImport_(certificateType, importAllowed, isKiosk_)]]">
         [[i18n('certificateManagerImport')]]</cr-button>
 <if expr="is_chromeos">
-      <cr-button id="importAndBind" on-click="onImportAndBindTap_"
+      <cr-button id="importAndBind" on-click="onImportAndBindClick_"
           hidden="[[!canImportAndBind_(certificateType, importAllowed,
                  isGuest_)]]">
         [[i18n('certificateManagerImportAndBind')]]</cr-button>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
index 95737ac..eef716a 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
@@ -147,12 +147,12 @@
     }));
   }
 
-  private onImportTap_(e: Event) {
+  private onImportClick_(e: Event) {
     this.handleImport_(false, e.target as HTMLElement);
   }
 
   // <if expr="is_chromeos">
-  private onImportAndBindTap_(e: Event) {
+  private onImportAndBindClick_(e: Event) {
     this.handleImport_(true, e.target as HTMLElement);
   }
   // </if>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.html
index 41f8bdc..a7bdc00 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.html
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.html
@@ -14,10 +14,10 @@
         </cr-input>
       </div>
       <div slot="button-container">
-        <cr-button class="cancel-button" on-click="onCancelTap_">
+        <cr-button class="cancel-button" on-click="onCancelClick_">
           [[i18n('cancel')]]
         </cr-button>
-        <cr-button id="ok" class="action-button" on-click="onOkTap_">
+        <cr-button id="ok" class="action-button" on-click="onOkClick_">
           [[i18n('ok')]]
         </cr-button>
       </div>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.ts
index fb94d4d..9e46a64 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.ts
@@ -55,11 +55,11 @@
     this.$.dialog.showModal();
   }
 
-  private onCancelTap_() {
+  private onCancelClick_() {
     this.$.dialog.close();
   }
 
-  private onOkTap_() {
+  private onOkClick_() {
     CertificatesBrowserProxyImpl.getInstance()
         .importPersonalCertificatePasswordSelected(this.password_)
         .then(
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.html
index bee2607..b66b419 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.html
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.html
@@ -25,10 +25,10 @@
         </div>
       </div>
       <div slot="button-container">
-        <cr-button class="cancel-button" on-click="onCancelTap_">
+        <cr-button class="cancel-button" on-click="onCancelClick_">
           [[i18n('cancel')]]
         </cr-button>
-        <cr-button id="ok" class="action-button" on-click="onOkTap_" disabled>
+        <cr-button id="ok" class="action-button" on-click="onOkClick_" disabled>
           [[i18n('ok')]]
         </cr-button>
       </div>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.ts
index 3193b4a..abe4c98f 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.ts
@@ -62,11 +62,11 @@
     this.$.dialog.showModal();
   }
 
-  private onCancelTap_() {
+  private onCancelClick_() {
     this.$.dialog.close();
   }
 
-  private onOkTap_() {
+  private onOkClick_() {
     CertificatesBrowserProxyImpl.getInstance()
         .exportPersonalCertificatePasswordSelected(this.password_)
         .then(
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.html
index 75c039c..32bd3736 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.html
+++ b/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.html
@@ -10,7 +10,7 @@
         </template>
       </div>
       <div slot="button-container">
-        <cr-button id="ok" class="action-button" on-click="onOkTap_">
+        <cr-button id="ok" class="action-button" on-click="onOkClick_">
           [[i18n('ok')]]
         </cr-button>
       </div>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.ts
index f439e9e..882c6ed9 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.ts
@@ -49,7 +49,7 @@
     this.$.dialog.showModal();
   }
 
-  private onOkTap_() {
+  private onOkClick_() {
     this.$.dialog.close();
   }
 
diff --git a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
index c3ab7ea..a0756c53 100644
--- a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
+++ b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
@@ -95,9 +95,9 @@
         width: 24px;
       }
     </style>
-    <dialog id="dialog" on-cancel="onDialogCancel_" on-click="onDialogTap_"
+    <dialog id="dialog" on-cancel="onDialogCancel_" on-click="onDialogClick_"
         on-close="onDialogClose_">
-      <div id="container" on-click="onContainerTap_">
+      <div id="container" on-click="onContainerClick_">
         <div class="drawer-header">
           <slot name="header-icon">
             <picture>
diff --git a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.ts b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.ts
index ff212a6..146611e 100644
--- a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.ts
+++ b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.ts
@@ -111,16 +111,16 @@
 
   /**
    * Stop propagation of a tap event inside the container. This will allow
-   * |onDialogTap_| to only be called when clicked outside the container.
+   * |onDialogClick_| to only be called when clicked outside the container.
    */
-  private onContainerTap_(event: Event) {
+  private onContainerClick_(event: Event) {
     event.stopPropagation();
   }
 
   /**
    * Close the dialog when tapped outside the container.
    */
-  private onDialogTap_() {
+  private onDialogClick_() {
     this.cancel();
   }
 
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input_style.css b/ui/webui/resources/cr_elements/cr_input/cr_input_style.css
index 69f29e3..d3db85a 100644
--- a/ui/webui/resources/cr_elements/cr_input/cr_input_style.css
+++ b/ui/webui/resources/cr_elements/cr_input/cr_input_style.css
@@ -99,7 +99,7 @@
         z-index: 0;
       }
 
-      :host-context([chrome-refresh-2023]):host(:not([readonly]))
+      :host-context([chrome-refresh-2023]):host(:not([readonly]):not([disabled]))
           #input-container:hover #hover-layer {
         display: block;
       }
diff --git a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
index daad68d..730c00c2 100644
--- a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
+++ b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
@@ -94,7 +94,7 @@
             "avatar-container [[getSelectedClass_(item, selectedAvatar)]]">
           <cr-button id="[[getAvatarId_(index)]]" aria-label="[[item.label]]"
               tabindex$="[[getTabIndex_(index, item, tabFocusableAvatar_)]]"
-              class="avatar" on-click="onAvatarTap_" role="radio"
+              class="avatar" on-click="onAvatarClick_" role="radio"
               style$="background-image: [[getIconImageSet_(item.url)]]"
               aria-checked$="[[getCheckedAttribute_(item, selectedAvatar)]]">
           </cr-button>
diff --git a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.ts b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.ts
index b7a96182..47f6769 100644
--- a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.ts
+++ b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.ts
@@ -124,7 +124,7 @@
     return getImage(iconUrl);
   }
 
-  private onAvatarTap_(e: DomRepeatEvent<AvatarIcon>) {
+  private onAvatarClick_(e: DomRepeatEvent<AvatarIcon>) {
     // |selectedAvatar| is set to pass back selection to the owner of this
     // component.
     this.selectedAvatar = e.model.item;
diff --git a/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.html b/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.html
index 80aee76..64bda9b 100644
--- a/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.html
+++ b/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.html
@@ -73,6 +73,13 @@
     overflow-x: hidden;
     overflow-y: auto;
   }
+
+  :host-context([chrome-refresh-2023]) textarea {
+    /* Ensures content sits above the hover layer. */
+    position: relative;
+    z-index: 1;
+  }
+
 </style>
 <div id="label" class="cr-form-field-label" hidden="[[!label]]"
     aria-hidden="true">
@@ -85,12 +92,14 @@
   <!-- The textarea is limited to |rows| height. If the content exceeds the
        bounds, it scrolls by default unless autogrow is set. No space or
        comments are allowed before the closing tag. -->
+  <div id="hover-layer"></div>
   <textarea id="input" autofocus="[[autofocus]]" rows="[[rows]]"
       value="{{value::input}}" aria-label$="[[label]]"
       on-focus="onInputFocusChange_" on-blur="onInputFocusChange_"
       on-change="onInputChange_" disabled="[[disabled]]"
       maxlength$="[[maxlength]]" readonly$="[[readonly]]"
       required$="[[required]]"></textarea>
+  <div id="underline-base"></div>
   <div id="underline"></div>
 </div>
 <div id="footerContainer" class="cr-row">
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html
index 6dad28a..cff9fad 100644
--- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html
@@ -138,7 +138,7 @@
       <div id="leftSpacer">
         <template is="dom-if" if="[[showMenu]]" restamp>
           <cr-icon-button id="menuButton" class="no-overlap"
-              iron-icon="cr20:menu" on-click="onMenuTap_"
+              iron-icon="cr20:menu" on-click="onMenuClick_"
               aria-label$="[[menuLabel]]"
               title="[[menuLabel]]">
           </cr-icon-button>
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.ts b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.ts
index cfe8520..667ed11f 100644
--- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.ts
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.ts
@@ -108,9 +108,9 @@
     return this.$.search;
   }
 
-  private onMenuTap_() {
+  private onMenuClick_() {
     this.dispatchEvent(new CustomEvent(
-        'cr-toolbar-menu-tap', {bubbles: true, composed: true}));
+        'cr-toolbar-menu-click', {bubbles: true, composed: true}));
   }
 
   focusMenuButton() {
diff --git a/ui/webui/resources/mojo/BUILD.gn b/ui/webui/resources/mojo/BUILD.gn
index 23360c6..4bd4d59 100644
--- a/ui/webui/resources/mojo/BUILD.gn
+++ b/ui/webui/resources/mojo/BUILD.gn
@@ -183,7 +183,8 @@
   deps = [ "//mojo/public/js:bindings_module" ]
   if (optimize_webui) {
     deps += [ ":build_min_js" ]
-    manifest_files = [ "$target_gen_dir/minify_js_manifest.json" ]
+    manifest_files = filter_include(get_target_outputs(":build_min_js"),
+                                    [ "*_manifest.json" ])
   } else {
     deps += [ ":build_ts" ]
     manifest_files =
diff --git a/ui/webui/resources/tools/PRESUBMIT.py b/ui/webui/resources/tools/PRESUBMIT.py
index 9c20100..bda3597 100644
--- a/ui/webui/resources/tools/PRESUBMIT.py
+++ b/ui/webui/resources/tools/PRESUBMIT.py
@@ -7,10 +7,8 @@
 
 def _CheckChangeOnUploadOrCommit(input_api, output_api):
   results = []
-  webui_sources = set([
-      'optimize_webui.py', 'rollup_plugin.js', 'generate_grd.py',
-      'minify_js.py', 'bundle_js.py'
-  ])
+  webui_sources = set(
+      ['rollup_plugin.js', 'generate_grd.py', 'minify_js.py', 'bundle_js.py'])
   affected = input_api.AffectedFiles()
   affected_files = [input_api.os_path.basename(f.LocalPath()) for f in affected]
   if webui_sources.intersection(set(affected_files)):
@@ -20,10 +18,7 @@
 
 def RunPresubmitTests(input_api, output_api):
   presubmit_path = input_api.PresubmitLocalPath()
-  sources = [
-      'optimize_webui_test.py', 'generate_grd_test.py', 'minify_js_test.py',
-      'bundle_js_test.py'
-  ]
+  sources = ['generate_grd_test.py', 'minify_js_test.py', 'bundle_js_test.py']
   tests = [input_api.os_path.join(presubmit_path, s) for s in sources]
   return input_api.canned_checks.RunUnitTests(
       input_api, output_api, tests, run_on_python2=False)
diff --git a/ui/webui/resources/tools/build_webui.gni b/ui/webui/resources/tools/build_webui.gni
index d9b05dc..619482c 100644
--- a/ui/webui/resources/tools/build_webui.gni
+++ b/ui/webui/resources/tools/build_webui.gni
@@ -453,7 +453,8 @@
 
     if (optimize) {
       deps += [ ":build_min_js" ]
-      manifest_files += [ "$target_gen_dir/minify_js_manifest.json" ]
+      manifest_files += filter_include(get_target_outputs(":build_min_js"),
+                                       [ "*_manifest.json" ])
       if (bundle) {
         resource_path_rewrites = []
         foreach(f, invoker.optimize_webui_in_files) {
diff --git a/ui/webui/resources/tools/minify_js.gni b/ui/webui/resources/tools/minify_js.gni
index bc72d1f6..c8638f1 100644
--- a/ui/webui/resources/tools/minify_js.gni
+++ b/ui/webui/resources/tools/minify_js.gni
@@ -23,17 +23,21 @@
       outputs += [ "$out_folder/$f" ]
     }
 
+    out_manifest = "$target_gen_dir/${target_name}_manifest.json"
+    if (defined(invoker.out_manifest)) {
+      out_manifest = invoker.out_manifest
+    }
+
+    outputs += [ out_manifest ]
+
     args = [
              "--in_folder",
              rebase_path(in_folder, root_build_dir),
              "--out_folder",
              rebase_path(out_folder, root_build_dir),
              "--out_manifest",
-             rebase_path("$target_gen_dir/minify_js_manifest.json",
-                         root_build_dir),
+             rebase_path(out_manifest, root_build_dir),
              "--in_files",
            ] + invoker.in_files
-
-    outputs += [ "$target_gen_dir/minify_js_manifest.json" ]
   }
 }
diff --git a/ui/webui/resources/tools/optimize_webui.gni b/ui/webui/resources/tools/optimize_webui.gni
index 697a452..ac5ad40 100644
--- a/ui/webui/resources/tools/optimize_webui.gni
+++ b/ui/webui/resources/tools/optimize_webui.gni
@@ -2,104 +2,36 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/chromeos/ui_mode.gni")
-import("//third_party/node/node.gni")
+import("//ui/webui/resources/tools/bundle_js.gni")
+import("//ui/webui/resources/tools/minify_js.gni")
 
 template("optimize_webui") {
-  node(target_name) {
-    script = "//ui/webui/resources/tools/optimize_webui.py"
+  bundle_js("${target_name}__bundle_js") {
+    forward_variables_from(invoker,
+                           "*",
+                           [
+                             "visibility",
+                             "out_manifest",
+                           ])
+    out_folder = "$target_gen_dir/${target_name}_bundled"
+    visibility = [ ":$target_name" ]
+  }
 
+  minify_js(target_name) {
     forward_variables_from(invoker, [ "visibility" ])
-
-    # This depfile is generated by optimize_webui.py
-    depfile = "${target_gen_dir}/${target_name}.d"
-
-    inputs = [ "//ui/webui/resources/tools/rollup_plugin.mjs" ]
-    outputs = []
-    input_count = 0
-    foreach(f, invoker.js_module_in_files) {
-      input_count = input_count + 1
-      out_file = string_replace(f, ".js", ".rollup.js")
-      outputs += [ "$target_gen_dir/$out_file" ]
-      if (input_count == 2) {
-        folder = get_path_info(f, "dir")
-        outputs += [ "$target_gen_dir/$folder/shared.rollup.js" ]
-      }
+    in_folder = "$target_gen_dir/${target_name}_bundled"
+    out_folder = target_gen_dir
+    in_files = []
+    js_files = filter_include(get_target_outputs(":${target_name}__bundle_js"),
+                              [ "*.js" ])
+    foreach(_js_file, js_files) {
+      in_files += [ string_replace(_js_file,
+                                   "$target_gen_dir/${target_name}_bundled/",
+                                   "") ]
     }
-
-    deps = invoker.deps
-
-    # Note that we have to manually pass the sources to our script if the
-    # script needs them as inputs.
-    args = [
-      "--host",
-      invoker.host,
-      "--input",
-      invoker.input,
-      "--out_folder",
-      rebase_path(target_gen_dir, root_build_dir),
-      "--depfile",
-      rebase_path(depfile, root_build_dir),
-      "--target_name",
-      target_name,
-    ]
-
-    if (defined(invoker.excludes)) {
-      args += [ "--exclude" ] + invoker.excludes
-    }
-
-    # Specify default external_paths. The order here matters in multiple ways.
-    #   1) chrome:// URLs need to be listed before scheme relative URLs
-    #      (otherwise chrome-extension:// contexts break)
-    #   2) Longer prefixes need to be listed before shorter prefixes, otherwise
-    #      mappings are incorrect.
-    #   3) chrome:// URLs should not be listed at all for chrome-untrusted://
-    #      contexts, otherwise generated bundle includes chrome:// URLs which is
-    #      incorrect.
-
-    polymer_path =
-        rebase_path("//third_party/polymer/v3_0/components-chromium/",
-                    root_build_dir)
-    resources_path =
-        rebase_path("$root_gen_dir/ui/webui/resources/tsc/", root_build_dir)
-    is_chrome_untrusted =
-        string_replace(invoker.host, "chrome-untrusted://", "") != invoker.host
-
-    external_paths = []
-    if (is_chromeos_ash) {
-      ash_resources_path =
-          rebase_path("$root_gen_dir/ash/webui/common/resources/preprocessed/",
-                      root_build_dir)
-      if (!is_chrome_untrusted) {
-        external_paths +=
-            [ "chrome://resources/ash/common/|$ash_resources_path" ]
-      }
-      external_paths += [ "//resources/ash/common/|$ash_resources_path" ]
-    }
-
-    if (!is_chrome_untrusted) {
-      external_paths += [ "chrome://resources/polymer/v3_0/|$polymer_path" ]
-    }
-    external_paths += [ "//resources/polymer/v3_0/|$polymer_path" ]
-
-    if (!is_chrome_untrusted) {
-      external_paths += [ "chrome://resources/|$resources_path" ]
-    }
-    external_paths += [ "//resources/|$resources_path" ]
-
-    if (defined(invoker.external_paths)) {
-      external_paths += invoker.external_paths
-    }
-    args += [ "--external_paths" ] + external_paths
-
-    args += [ "--js_module_in_files" ] + invoker.js_module_in_files
-
     if (defined(invoker.out_manifest)) {
-      args += [
-        "--out-manifest",
-        rebase_path(invoker.out_manifest, root_build_dir),
-      ]
-      outputs += [ invoker.out_manifest ]
+      out_manifest = invoker.out_manifest
     }
+    deps = [ ":${target_name}__bundle_js" ]
   }
 }
diff --git a/ui/webui/resources/tools/optimize_webui.py b/ui/webui/resources/tools/optimize_webui.py
deleted file mode 100755
index cd128b6..0000000
--- a/ui/webui/resources/tools/optimize_webui.py
+++ /dev/null
@@ -1,318 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2016 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import itertools
-import json
-import os
-import glob
-import platform
-import re
-import shutil
-import sys
-import tempfile
-
-_HERE_PATH = os.path.dirname(__file__)
-_SRC_PATH = os.path.normpath(os.path.join(_HERE_PATH, '..', '..', '..', '..'))
-_CWD = os.getcwd()  # NOTE(dbeam): this is typically out/<gn_name>/.
-
-sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'node'))
-import node
-import node_modules
-
-# These files are already combined and minified.
-_BASE_EXCLUDES = []
-for excluded_file in [
-    'resources/mojo/mojo/public/js/bindings.js',
-    'resources/mojo/mojo/public/mojom/base/time.mojom-lite.js',
-    'resources/polymer/v3_0/polymer/polymer_bundled.min.js',
-    'resources/js/cr.js',  # This file relies on globals.
-    'resources/js/load_time_data.js',
-    'resources/ash/common/load_time_data.m.js',
-    'resources/mwc/lit/index.js',
-]:
-  # Exclude both the chrome://resources form and the scheme-relative form for
-  # files used in Polymer 3.
-  _BASE_EXCLUDES.append("chrome://" + excluded_file)
-  _BASE_EXCLUDES.append("//" + excluded_file)
-
-
-def _request_list_path(out_path, target_name):
-  # Using |target_name| as a prefix which is guaranteed to be unique within the
-  # same folder, to avoid problems when multiple optimize_webui() targets in the
-  # same BUILD.gn file exist.
-  return os.path.join(out_path, target_name + '_requestlist.txt')
-
-
-def _get_dep_path(dep, host_url, in_path):
-  if dep.startswith(host_url):
-    return dep.replace(host_url, os.path.relpath(in_path, _CWD))
-  elif not (dep.startswith('chrome://') or dep.startswith('//')):
-    return os.path.relpath(in_path, _CWD) + '/' + dep
-  return dep
-
-
-# Get a list of all files that were bundled with rollup and update the
-# depfile accordingly such that Ninja knows when to re-trigger.
-def _update_dep_file(in_folder, args, out_file_path, manifest):
-  in_path = os.path.join(_CWD, in_folder)
-
-  # Gather the dependencies of all bundled root files.
-  request_list = []
-  for out_file in manifest:
-    request_list += manifest[out_file]
-
-  # Add a slash in front of every dependency that is not a chrome:// URL, so
-  # that we can map it to the correct source file path below.
-  request_list = map(lambda dep: _get_dep_path(dep, args.host_url, in_path),
-                     request_list)
-
-  deps = map(os.path.normpath, request_list)
-
-  with open(os.path.join(_CWD, args.depfile), 'w') as f:
-    f.write(out_file_path + ': ' + ' '.join(deps))
-
-
-# Autogenerate a rollup config file so that we can import the plugin and
-# pass it information about the location of the directories and files to
-# exclude from the bundle.
-# Arguments:
-# tmp_out_dir: The root directory for the output (i.e. corresponding to
-#              host_url at runtime).
-# path_to_plugin: Path to the rollup plugin.
-# in_path: Root directory for the input files.
-# bundle_path: Path to the output files from the root output directory.
-#              E.g. if bundle is chrome://foo/bundle.js, this is |foo|.
-# host_url: URL of the host. Usually something like "chrome://settings".
-# excludes: Imports to exclude from the bundle.
-# external_paths: Path mappings for import paths that are outside of
-#                 |in_path|. For example:
-#                 chrome://resources/|gen/ui/webui/resources/tsc
-def _generate_rollup_config(tmp_out_dir, path_to_plugin, in_path, bundle_path,
-                            host_url, excludes, external_paths):
-  rollup_config_file = os.path.join(tmp_out_dir, bundle_path,
-                                    'rollup.config.mjs')
-  config_content = r'''
-    import plugin from '{plugin_path}';
-    export default ({{
-      plugins: [
-        plugin('{in_path}', '{bundle_path}', '{host_url}', {exclude_list},
-               {external_path_list}) ]
-    }});
-    '''.format(
-      plugin_path=path_to_plugin.replace('\\', '/'),
-      in_path=in_path.replace('\\', '/'),
-      bundle_path=bundle_path.replace('\\', '/'),
-      host_url=host_url,
-      exclude_list=json.dumps(excludes),
-      external_path_list=json.dumps(external_paths))
-  with open(rollup_config_file, 'w') as f:
-    f.write(config_content)
-  return rollup_config_file
-
-
-# Create the manifest file from the sourcemap generated by rollup and return the
-# list of bundles.
-def _generate_manifest_file(out_dir, in_path, bundle_path, manifest_out_path):
-  generated_sourcemaps = glob.glob('%s/*.map' % out_dir)
-  manifest = {}
-  output_filenames = []
-  for sourcemap_file in generated_sourcemaps:
-    with open(sourcemap_file, 'r') as f:
-      sourcemap = json.loads(f.read())
-      if not 'sources' in sourcemap:
-        raise Exception('rollup could not construct source map')
-      sources = sourcemap['sources']
-      replaced_sources = []
-      # Normalize everything to be relative to the input directory. This is
-      # where the conversion to a dependency file expects it to be.
-      output_to_input = os.path.relpath(in_path, out_dir) + "/"
-      bundle_to_input = os.path.relpath(in_path,
-                                        os.path.join(in_path, bundle_path))
-      for source in sources:
-        if output_to_input in source:
-          replaced_sources.append(source.replace(output_to_input, "", 1))
-        elif bundle_to_input != ".":
-          replaced_sources.append(source.replace(bundle_to_input + "/", "", 1))
-        else:
-          replaced_sources.append(source)
-      filename = sourcemap_file[:-len('.map')]
-      filepath = os.path.join(bundle_path, os.path.basename(filename)). \
-              replace('\\', '/')
-      manifest[filepath] = replaced_sources
-      output_filenames.append(filename)
-
-  with open(manifest_out_path, 'w') as f:
-    f.write(json.dumps(manifest))
-
-  return output_filenames
-
-
-def _bundle_v3(tmp_out_dir, in_path, out_path, manifest_out_path, args,
-               excludes, external_paths):
-  bundle_path = os.path.dirname(args.js_module_in_files[0])
-  out_dir = tmp_out_dir if not bundle_path else os.path.join(
-      tmp_out_dir, bundle_path)
-  if not os.path.exists(out_dir):
-    os.makedirs(out_dir)
-
-  path_to_plugin = os.path.join(
-      os.path.relpath(_HERE_PATH, os.path.join(tmp_out_dir, bundle_path)),
-      'rollup_plugin.mjs')
-  rollup_config_file = _generate_rollup_config(tmp_out_dir, path_to_plugin,
-                                               in_path, bundle_path,
-                                               args.host_url, excludes,
-                                               external_paths)
-  rollup_args = [os.path.join(in_path, f) for f in args.js_module_in_files]
-
-  # Confirm names are as expected. This is necessary to avoid having to replace
-  # import statements in the generated output files.
-  # TODO(rbpotter): Is it worth adding import statement replacement to support
-  # arbitrary names?
-  bundled_paths = []
-  bundle_names = []
-
-  assert len(args.js_module_in_files) < 3, '3+ input files not supported'
-
-  for index, js_file in enumerate(args.js_module_in_files):
-    bundle_name = '%s.rollup.js' % js_file[:-len('.js')]
-    assert os.path.dirname(js_file) == bundle_path, \
-           'All input files must be in the same directory.'
-    bundled_paths.append(os.path.join(tmp_out_dir, bundle_name))
-    bundle_names.append(bundle_name)
-
-  # This indicates that rollup is expected to generate a shared chunk file as
-  # well as one file per module. Set its name using --chunkFileNames. Note:
-  # Currently, this only supports 2 entry points, which generate 2 corresponding
-  # outputs and 1 shared output.
-  if (len(args.js_module_in_files) == 2):
-    shared_file_name = 'shared.rollup.js'
-    rollup_args += ['--chunkFileNames', shared_file_name]
-    bundled_paths.append(os.path.join(out_dir, shared_file_name))
-    bundle_names.append(os.path.join(bundle_path, shared_file_name))
-
-  node.RunNode([node_modules.PathToRollup()] + rollup_args + [
-      '--format',
-      'esm',
-      '--dir',
-      out_dir,
-      '--entryFileNames',
-      '[name].rollup.js',
-      '--sourcemap',
-      '--sourcemapExcludeSources',
-      '--config',
-      rollup_config_file,
-  ])
-
-  # Create the manifest file from the sourcemaps generated by rollup.
-  generated_paths = _generate_manifest_file(out_dir, in_path, bundle_path,
-                                            manifest_out_path)
-  assert len(generated_paths) == len(bundled_paths), \
-         'unexpected number of bundles - %s - generated by rollup' % \
-         (len(generated_paths))
-
-  for bundled_file in bundled_paths:
-    with open(bundled_file, 'r', encoding='utf-8') as f:
-      output = f.read()
-      assert "<if expr" not in output, \
-          'Unexpected <if expr> found in bundled output. Check that all ' + \
-          'input files using such expressions are preprocessed.'
-
-  return bundle_names
-
-
-def _optimize(in_folder, args):
-  in_path = os.path.normpath(os.path.join(_CWD, in_folder)).replace('\\', '/')
-  out_path = os.path.join(_CWD, args.out_folder).replace('\\', '/')
-  manifest_out_path = _request_list_path(out_path, args.target_name)
-  tmp_out_dir = tempfile.mkdtemp(dir=out_path).replace('\\', '/')
-
-  excludes = _BASE_EXCLUDES + [
-      # This file is dynamically created by C++. Should always be imported with
-      # a relative path.
-      'strings.m.js',
-  ]
-  excludes.extend(args.exclude or [])
-
-  for exclude in excludes:
-    extension = os.path.splitext(exclude)[1]
-    assert extension == '.js', f'Unexpected |excludes| entry: {exclude}.' + \
-        ' Only .js files can appear in |excludes|.'
-
-  external_paths = args.external_paths or []
-  js_module_out_files = []
-
-  try:
-    js_module_out_files = _bundle_v3(tmp_out_dir, in_path, out_path,
-                                     manifest_out_path, args, excludes,
-                                     external_paths)
-
-    # Pass the JS files through Terser and write the output to its final
-    # destination.
-    for index, js_out_file in enumerate(js_module_out_files):
-      node.RunNode([
-          node_modules.PathToTerser(),
-          os.path.join(tmp_out_dir, js_out_file), '--comments',
-          '/Copyright|license|LICENSE|\<\/?if/', '--output',
-          os.path.join(out_path, js_out_file)
-      ])
-  finally:
-    shutil.rmtree(tmp_out_dir)
-  return {
-      'manifest_out_path': manifest_out_path,
-      'js_module_out_files': js_module_out_files,
-  }
-
-
-def main(argv):
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--depfile', required=True)
-  parser.add_argument('--target_name', required=True)
-  parser.add_argument('--exclude', nargs='*')
-  parser.add_argument('--external_paths', nargs='*')
-  parser.add_argument('--host', required=True)
-  parser.add_argument('--input', required=True)
-  parser.add_argument('--out_folder', required=True)
-  parser.add_argument('--js_module_in_files', nargs='*', required=True)
-  parser.add_argument('--out-manifest')
-  args = parser.parse_args(argv)
-
-  # NOTE(dbeam): on Windows, GN can send dirs/like/this. When joined, you might
-  # get dirs/like/this\file.txt. This looks odd to windows. Normalize to right
-  # the slashes.
-  args.depfile = os.path.normpath(args.depfile)
-  args.input = os.path.normpath(args.input)
-  args.out_folder = os.path.normpath(args.out_folder)
-  scheme_end_index = args.host.find('://')
-  if (scheme_end_index == -1):
-    args.host_url = 'chrome://%s/' % args.host
-  else:
-    args.host_url = args.host
-
-  optimize_output = _optimize(args.input, args)
-
-  # Prior call to _optimize() generated an output manifest file, containing
-  # information about all files that were bundled. Grab it from there.
-  with open(optimize_output['manifest_out_path'], 'r') as f:
-    manifest = json.loads(f.read())
-
-    # Output a manifest file that will be used to auto-generate a grd file
-    # later.
-    if args.out_manifest:
-      manifest_data = {
-          'base_dir': args.out_folder.replace('\\', '/'),
-          'files': list(manifest.keys()),
-      }
-      with open(os.path.normpath(os.path.join(_CWD, args.out_manifest)), 'w') \
-          as manifest_file:
-        json.dump(manifest_data, manifest_file)
-
-    dep_file_header = os.path.join(args.out_folder,
-                                   optimize_output['js_module_out_files'][0])
-    _update_dep_file(args.input, args, dep_file_header, manifest)
-
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/ui/webui/resources/tools/optimize_webui_test.py b/ui/webui/resources/tools/optimize_webui_test.py
deleted file mode 100755
index 1376128..0000000
--- a/ui/webui/resources/tools/optimize_webui_test.py
+++ /dev/null
@@ -1,430 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2017 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import optimize_webui
-import os
-import shutil
-import tempfile
-import unittest
-
-_CWD = os.getcwd()
-_HERE_DIR = os.path.dirname(__file__)
-
-
-class OptimizeWebUiTest(unittest.TestCase):
-
-  def setUp(self):
-    self._tmp_dirs = []
-    self._tmp_src_dir = None
-    self._out_folder = self._create_tmp_dir()
-
-  def tearDown(self):
-    for tmp_dir in self._tmp_dirs:
-      shutil.rmtree(tmp_dir)
-
-  def _write_file_to_dir(self, file_path, file_contents):
-    file_dir = os.path.dirname(file_path)
-    if not os.path.exists(file_dir):
-      os.makedirs(file_dir)
-    with open(file_path, 'w') as tmp_file:
-      tmp_file.write(file_contents)
-
-  def _write_file_to_src_dir(self, file_path, file_contents):
-    if not self._tmp_src_dir:
-      self._tmp_src_dir = self._create_tmp_dir()
-    file_path_normalized = os.path.normpath(
-        os.path.join(self._tmp_src_dir, file_path))
-    self._write_file_to_dir(file_path_normalized, file_contents)
-
-  def _create_tmp_dir(self):
-    # TODO(dbeam): support cross-drive paths (i.e. d:\ vs c:\).
-    tmp_dir = tempfile.mkdtemp(dir=_HERE_DIR)
-    self._tmp_dirs.append(tmp_dir)
-    return tmp_dir
-
-  def _read_out_file(self, file_name):
-    assert self._out_folder
-    with open(os.path.join(self._out_folder, file_name), 'r') as f:
-      return f.read()
-
-  def _run_optimize(self, input_args):
-    # TODO(dbeam): make it possible to _run_optimize twice? Is that useful?
-    args = input_args + [
-        '--depfile',
-        os.path.join(self._out_folder, 'depfile.d'),
-        '--target_name',
-        'dummy_target_name',
-        '--input',
-        self._tmp_src_dir,
-        '--out_folder',
-        self._out_folder,
-    ]
-    optimize_webui.main(args)
-
-  def _write_v3_files_to_src_dir(self):
-    self._write_file_to_src_dir('element.js', "alert('yay');")
-    self._write_file_to_src_dir('element_in_dir/element_in_dir.js',
-                                "alert('hello from element_in_dir');")
-    self._write_file_to_src_dir(
-        'ui.js', '''
-import './element.js';
-import './element_in_dir/element_in_dir.js';
-''')
-    self._write_file_to_src_dir(
-        'ui.html', '''
-<script type="module" src="ui.js"></script>
-''')
-
-  def _write_v3_files_with_custom_path_to_src_dir(self, custom_path):
-    self._write_file_to_dir(
-        os.path.join(custom_path, 'external_dir', 'external_element.js'), '''
-import './sub_dir/external_element_dep.js';
-alert('hello from external_element');
-''')
-
-    self._write_file_to_dir(
-        os.path.join(custom_path, 'external_dir', 'sub_dir',
-                     'external_element_dep.js'),
-        "alert('hello from external_element_dep');")
-
-    self._write_file_to_src_dir('element.js', "alert('yay');")
-    self._write_file_to_src_dir(
-        'ui.js', '''
-import './element.js';
-import 'some-fake-scheme://foo/external_dir/external_element.js';
-''')
-    self._write_file_to_src_dir(
-        'ui.html', '''
-<script type="module" src="ui.js"></script>
-''')
-
-  def _write_v3_files_with_resources_to_src_dir(self, resources_scheme):
-    resources_path = os.path.join(
-        _HERE_DIR.replace('\\', '/'), 'gen', 'ui', 'webui', 'resources', 'tsc',
-        'js')
-    fake_resource_path = os.path.join(resources_path, 'fake_resource.js')
-    scheme_relative_resource_path = os.path.join(resources_path,
-                                                 'scheme_relative_resource.js')
-    os.makedirs(os.path.dirname(resources_path))
-
-    self._tmp_dirs.append('gen')
-    self._write_file_to_dir(
-        fake_resource_path, '''
-export const foo = 5;
-alert('hello from shared resource');''')
-    self._write_file_to_dir(
-        scheme_relative_resource_path, '''
-export const bar = 6;
-alert('hello from another shared resource');''')
-
-    self._write_file_to_src_dir(
-        'element.js', '''
-import '%s//resources/js/fake_resource.js';
-import {bar} from '//resources/js/scheme_relative_resource.js';
-alert('yay ' + bar);
-''' % resources_scheme)
-    self._write_file_to_src_dir(
-        'element_in_dir/element_in_dir.js', '''
-import {foo} from '%s//resources/js/fake_resource.js';
-import '../strings.m.js';
-alert('hello from element_in_dir ' + foo);
-''' % resources_scheme)
-    self._write_file_to_src_dir(
-        'ui.js', '''
-import './strings.m.js';
-import './element.js';
-import './element_in_dir/element_in_dir.js';
-''')
-    self._write_file_to_src_dir(
-        'ui.html', '''
-<script type="module" src="ui.js"></script>
-''')
-
-  def _check_output_html(self, out_html):
-    self.assertNotIn('element.html', out_html)
-    self.assertNotIn('element.js', out_html)
-    self.assertNotIn('element_in_dir.html', out_html)
-    self.assertNotIn('element_in_dir.js', out_html)
-    self.assertIn('got here!', out_html)
-
-  def _check_output_js(self, output_js_name):
-    output_js = self._read_out_file(output_js_name)
-    self.assertIn('yay', output_js)
-    self.assertIn('hello from element_in_dir', output_js)
-
-  def _check_output_depfile(self, has_html):
-    depfile_d = self._read_out_file('depfile.d')
-    self.assertIn('element.js', depfile_d)
-    self.assertIn(
-        os.path.normpath('element_in_dir/element_in_dir.js'), depfile_d)
-    if (has_html):
-      self.assertIn('element.html', depfile_d)
-      self.assertIn(
-          os.path.normpath('element_in_dir/element_in_dir.html'), depfile_d)
-
-  def testV3SimpleOptimize(self):
-    self._write_v3_files_to_src_dir()
-    args = [
-        '--host',
-        'fake-host',
-        '--js_module_in_files',
-        'ui.js',
-    ]
-    self._run_optimize(args)
-
-    self._check_output_js('ui.rollup.js')
-    self._check_output_depfile(False)
-
-  def testV3OptimizeWithResources(self):
-    self._write_v3_files_with_resources_to_src_dir('chrome:')
-    resources_path = os.path.join('gen', 'ui', 'webui', 'resources', 'tsc')
-    args = [
-        '--host',
-        'fake-host',
-        '--js_module_in_files',
-        'ui.js',
-        '--external_paths',
-        'chrome://resources|%s' % resources_path,
-    ]
-    self._run_optimize(args)
-
-    ui_rollup_js = self._read_out_file('ui.rollup.js')
-    self.assertIn('yay', ui_rollup_js)
-    self.assertIn('hello from element_in_dir', ui_rollup_js)
-    self.assertIn('hello from shared resource', ui_rollup_js)
-
-    depfile_d = self._read_out_file('depfile.d')
-    self.assertIn('element.js', depfile_d)
-    self.assertIn(
-        os.path.normpath('element_in_dir/element_in_dir.js'), depfile_d)
-    self.assertIn(
-        os.path.normpath(
-            '../gen/ui/webui/resources/tsc/js/scheme_relative_resource.js'),
-        depfile_d)
-    self.assertIn(
-        os.path.normpath('../gen/ui/webui/resources/tsc/js/fake_resource.js'),
-        depfile_d)
-
-  def testV3MultiBundleOptimize(self):
-    self._write_v3_files_to_src_dir()
-    self._write_file_to_src_dir('lazy_element.js',
-                                "alert('hello from lazy_element');")
-    self._write_file_to_src_dir(
-        'lazy.js', '''
-import './lazy_element.js';
-import './element_in_dir/element_in_dir.js';
-''')
-
-    args = [
-        '--host',
-        'fake-host',
-        '--js_module_in_files',
-        'ui.js',
-        'lazy.js',
-        '--out-manifest',
-        os.path.join(self._out_folder, 'out_manifest.json'),
-    ]
-    self._run_optimize(args)
-
-    # Check that the shared element is in the shared bundle and the non-shared
-    # elements are in the individual bundles.
-    ui_js = self._read_out_file('ui.rollup.js')
-    self.assertIn('yay', ui_js)
-    self.assertNotIn('hello from lazy_element', ui_js)
-    self.assertNotIn('hello from element_in_dir', ui_js)
-
-    lazy_js = self._read_out_file('lazy.rollup.js')
-    self.assertNotIn('yay', lazy_js)
-    self.assertIn('hello from lazy_element', lazy_js)
-    self.assertNotIn('hello from element_in_dir', lazy_js)
-
-    shared_js = self._read_out_file('shared.rollup.js')
-    self.assertNotIn('yay', shared_js)
-    self.assertNotIn('hello from lazy_element', shared_js)
-    self.assertIn('hello from element_in_dir', shared_js)
-
-    # All 3 JS files should be in the depfile.
-    self._check_output_depfile(False)
-    depfile_d = self._read_out_file('depfile.d')
-    self.assertIn('lazy_element.js', depfile_d)
-
-    manifest = json.loads(self._read_out_file('out_manifest.json'))
-    self.assertEqual(3, len(manifest['files']))
-    self.assertTrue('lazy.rollup.js' in manifest['files'])
-    self.assertTrue('ui.rollup.js' in manifest['files'])
-    self.assertTrue('shared.rollup.js' in manifest['files'])
-
-    self.assertEqual(
-        os.path.relpath(self._out_folder, _CWD).replace('\\', '/'),
-        os.path.relpath(manifest['base_dir'], _CWD))
-
-  def testV3OptimizeWithCustomPaths(self):
-    custom_dir = os.path.join(self._create_tmp_dir(), 'foo_root')
-    self._write_v3_files_with_custom_path_to_src_dir(custom_dir)
-    resources_path = os.path.join('gen', 'ui', 'webui', 'resources', 'tsc')
-    args = [
-        '--host',
-        'fake-host',
-        '--js_module_in_files',
-        'ui.js',
-        '--external_paths',
-        'chrome://resources|%s' % resources_path,
-        'some-fake-scheme://foo|%s' % os.path.abspath(custom_dir),
-    ]
-    self._run_optimize(args)
-
-    ui_rollup_js = self._read_out_file('ui.rollup.js')
-    self.assertIn('yay', ui_rollup_js)
-    self.assertIn('hello from external_element', ui_rollup_js)
-    self.assertIn('hello from external_element_dep', ui_rollup_js)
-
-    depfile_d = self._read_out_file('depfile.d')
-    self.assertIn('element.js', depfile_d)
-    # Relative path from the src of the root module to the external root dir
-    relpath = os.path.relpath(custom_dir, self._tmp_src_dir)
-    self.assertIn(
-        os.path.normpath(
-            os.path.join(relpath, 'external_dir', 'external_element.js')),
-        depfile_d)
-    self.assertIn(
-        os.path.normpath(
-            os.path.join(relpath, 'external_dir', 'sub_dir',
-                         'external_element_dep.js')), depfile_d)
-
-  def testV3SimpleOptimizeExcludes(self):
-    self._write_v3_files_to_src_dir()
-    args = [
-        '--host',
-        'chrome-extension://myextensionid/',
-        '--js_module_in_files',
-        'ui.js',
-        '--exclude',
-        'element_in_dir/element_in_dir.js',
-    ]
-    self._run_optimize(args)
-
-    output_js = self._read_out_file('ui.rollup.js')
-    self.assertIn('yay', output_js)
-    self.assertNotIn('hello from element_in_dir', output_js)
-    depfile_d = self._read_out_file('depfile.d')
-    self.assertIn('element.js', depfile_d)
-    self.assertNotIn('element_in_dir', depfile_d)
-
-  # Tests that bundling resources for an untrusted UI can successfully exclude
-  # resources imported from both chrome-untrusted://resources and scheme
-  # relative paths.
-  def testV3SimpleOptimizeExcludesResources(self):
-    self._write_v3_files_with_resources_to_src_dir('chrome-untrusted:')
-    resources_path = os.path.join('gen', 'ui', 'webui', 'resources', 'tsc')
-    args = [
-        '--host',
-        'chrome-untrusted://fake-host',
-        '--js_module_in_files',
-        'ui.js',
-        '--external_paths',
-        '//resources|%s' % resources_path,
-        'chrome-untrusted://resources|%s' % resources_path,
-        '--exclude',
-        '//resources/js/scheme_relative_resource.js',
-        'chrome-untrusted://resources/js/fake_resource.js',
-    ]
-    self._run_optimize(args)
-
-    output_js = self._read_out_file('ui.rollup.js')
-    self.assertIn('yay', output_js)
-    self.assertIn('//resources/js/scheme_relative_resource.js', output_js)
-    self.assertIn('chrome-untrusted://resources/js/fake_resource.js', output_js)
-    self.assertNotIn('hello from another shared resource', output_js)
-    self.assertNotIn('hello from shared resource', output_js)
-    depfile_d = self._read_out_file('depfile.d')
-    self.assertNotIn('fake_resource', depfile_d)
-    self.assertNotIn('scheme_relative_resource', depfile_d)
-
-  # Tests that bundling resources for an untrusted UI successfully bundles
-  # resources from both chrome-untrusted://resources and //resources.
-  def testV3SimpleOptimizeUntrustedResources(self):
-    self._write_v3_files_with_resources_to_src_dir('chrome-untrusted:')
-    resources_path = os.path.join('gen', 'ui', 'webui', 'resources', 'tsc')
-    args = [
-        '--host',
-        'chrome-untrusted://fake-host',
-        '--js_module_in_files',
-        'ui.js',
-        '--external_paths',
-        '//resources|%s' % resources_path,
-        'chrome-untrusted://resources|%s' % resources_path,
-    ]
-    self._run_optimize(args)
-
-    output_js = self._read_out_file('ui.rollup.js')
-    self.assertIn('yay', output_js)
-    self.assertIn('hello from another shared resource', output_js)
-    self.assertIn('hello from shared resource', output_js)
-    depfile_d = self._read_out_file('depfile.d')
-    self.assertIn('fake_resource', depfile_d)
-    self.assertIn('scheme_relative_resource', depfile_d)
-
-  def testV3OptimizeWithCustomLayeredPaths(self):
-    tmp_dir = self._create_tmp_dir()
-    custom_dir_foo = os.path.join(tmp_dir, 'foo_root')
-    custom_dir_bar = os.path.join(tmp_dir, 'bar_root')
-
-    self._write_v3_files_with_custom_path_to_src_dir(custom_dir_foo)
-
-    # Overwrite one of the foo files to import something from
-    # some-fake-scheme://bar.
-    self._write_file_to_dir(
-        os.path.join(custom_dir_foo, 'external_dir', 'sub_dir',
-                     'external_element_dep.js'), '''
-import 'some-fake-scheme://bar/another_element.js';
-alert('hello from external_element_dep');''')
-
-    # Write that file to the bar_root directory.
-    self._write_file_to_dir(
-        os.path.join(custom_dir_bar, 'another_element.js'),
-        "alert('hello from another external dep');")
-
-    resources_path = os.path.join('gen', 'ui', 'webui', 'resources', 'tsc')
-    args = [
-        '--host',
-        'fake-host',
-        '--js_module_in_files',
-        'ui.js',
-        '--external_paths',
-        '//resources|%s' % resources_path,
-        'some-fake-scheme://foo|%s' % os.path.abspath(custom_dir_foo),
-        'some-fake-scheme://bar|%s' % os.path.abspath(custom_dir_bar),
-    ]
-    self._run_optimize(args)
-
-    ui_rollup_js = self._read_out_file('ui.rollup.js')
-    self.assertIn('yay', ui_rollup_js)
-    self.assertIn('hello from external_element', ui_rollup_js)
-    self.assertIn('hello from external_element_dep', ui_rollup_js)
-    self.assertIn('hello from another external dep', ui_rollup_js)
-
-    depfile_d = self._read_out_file('depfile.d')
-    self.assertIn('element.js', depfile_d)
-    # Relative path from the src of the root module to the external root dir
-    relpath = os.path.relpath(custom_dir_foo, self._tmp_src_dir)
-    self.assertIn(
-        os.path.normpath(
-            os.path.join(relpath, 'external_dir', 'external_element.js')),
-        depfile_d)
-    self.assertIn(
-        os.path.normpath(
-            os.path.join(relpath, 'external_dir', 'sub_dir',
-                         'external_element_dep.js')), depfile_d)
-    # Relative path from the src of the root module to the secondary dependency
-    # root dir.
-    relpath_bar = os.path.relpath(custom_dir_bar, self._tmp_src_dir)
-    self.assertIn(
-        os.path.normpath(os.path.join(relpath_bar, 'another_element.js')),
-        depfile_d)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/weblayer/browser/safe_browsing/weblayer_ping_manager_factory_browsertest.cc b/weblayer/browser/safe_browsing/weblayer_ping_manager_factory_browsertest.cc
index b3f3b58..616f5c9 100644
--- a/weblayer/browser/safe_browsing/weblayer_ping_manager_factory_browsertest.cc
+++ b/weblayer/browser/safe_browsing/weblayer_ping_manager_factory_browsertest.cc
@@ -56,7 +56,9 @@
       expect_should_fetch);
 }
 
-IN_PROC_BROWSER_TEST_F(WeblayerPingManagerFactoryTest, ReportThreatDetails) {
+// TODO(crbug.com/1448686)
+IN_PROC_BROWSER_TEST_F(WeblayerPingManagerFactoryTest,
+                       DISABLED_ReportThreatDetails) {
   auto* ping_manager = WebLayerPingManagerFactory::GetForBrowserContext(
       GetProfile()->GetBrowserContext());